ui in cpp einbinden

Gast #1344865
Lesenswert?

Ich habe mit Qt eine einfache Oberfläche mit einem Textfeld erstellt.
nun will ich aber mit code::blocks diese datei (.ui) einbinden und 
ändern.
Es kommt aber immer ein Fehler. :-(
1
#include <QApplication>
2
#include <QWidget>
3
#include <QLabel>
4
#include <iostream>
5
#include "ui_test3.h"
6

7
using namespace std;
8

9
 namespace Ui {
10

11
class test3 : public QWidget
12
 {
13
     Q_OBJECT
14

15
 public:
16
     test3(QWidget *parent = 0);
17

18
 private slots:
19
     void on_inputSpinBox1_valueChanged(int value);
20
     void on_inputSpinBox2_valueChanged(int value);
21

22
 private:
23
     Ui::test3 ui;  
24
  };
25

26
 }
27

28
int main(int argc, char* argv[]) {
29

30

31

32
   QApplication app(argc, argv);
33
   QWidget *widget = new QWidget;
34
   Ui::Test3 ui;
35
   ui.setupUi(widget);
36

37
   widget->show();
38
   return app.exec();
39

40
}

Fehlermeldung

main.cpp|22|error: field 'ui' has incomplete type|
main.cpp||In function 'int qMain(int, char**)':|
main.cpp|39|error: 'Test3' is not a member of 'Ui'|
main.cpp|39|error: expected `;' before 'ui'|
main.cpp|40|error: 'ui' was not declared in this scope|
||=== Build finished: 4 errors, 12 warnings ===|
#1344923
Lesenswert?

1
class test3 : public QWidget
2
 {
3
     Q_OBJECT
4

5
 public:
6
     test3(QWidget *parent = 0);
7

8
 private slots:
9
     void on_inputSpinBox1_valueChanged(int value);
10
     void on_inputSpinBox2_valueChanged(int value);
11

12
 private:
13
     Ui::test3 ui;  
14
  };

Aha. Ein test3 Objekt enthält also ein test3 Objekt, welches seinerseits 
wieder ein test3 Objekt enthält welches dann auch wieder ein test3 
Objekt enthält (tief Luft hol), das dann auch wieder ein test3 Objekt 
enthält, welches ein test3 Objekt als Member hat, ....

Merkst du was?
Gast #1344950
Lesenswert?

@Karl heinz Buchegger
Was ist daran so ungewöhnlich, habe den code aus einem beispiel aus der 
online hilfe von qt übernommen.
Ich weiss nicht was ich falsch mache.

test3 ist jetzt überall klein geschrieben.

Gruß
Andre
Gast #1345010
Lesenswert?

#include "ui_calculatorform.h"

 class CalculatorForm : public QWidget
 {
     Q_OBJECT

 public:
     CalculatorForm(QWidget *parent = 0);

 private slots:
     void on_inputSpinBox1_valueChanged(int value);
     void on_inputSpinBox2_valueChanged(int value);

 private:
     Ui::CalculatorForm ui;
 };

 int main(int argc, char *argv[])
 {
     QApplication app(argc, argv);
     QWidget *widget = new QWidget;
     Ui::CalculatorForm ui;
     ui.setupUi(widget);

     widget->show();
     return app.exec();
 }
Persönliche Seite #1345032
Lesenswert?

Und das ist das gleiche Problem:
1
 private:
2
     Ui::CalculatorForm ui;
3
 };

Das ist das Ende der Deklaration der Klasse Ui::CalculatorForm. Und 
damit deklarierst Du eine Membervariable namens "ui" vom Typ 
Ui::CalculatorForm, also genau dem Typ, von dem die gerade deklarierte 
Klasse ist.

Wenn eine Klasse eine Membervariable vom gleichen Typ wie sie selbst 
enthält, dann ist das Rekursion.

Das mit dem Namespace macht die ganze Sache nur unübersichtlicher, 
ändert aber nichts am Hauptproblem:
1
class xyz
2
{
3
public:
4
  xyz();
5
  ~xyz();
6

7
protected:
8
  xyz uvw;
9
};

Das ist dasselbe in Grün.
Gast #1345136
Lesenswert?

Soory, aber ich komme icht weiter.
Hat jemand ein bespiel das ich 1 ein zu eins in mein umgebung einfüge 
kann ohne irgendwelche spezifischen Syntaxänderungen.

Nutze qt4.5
code::blocks
gnu ccc compiler
#1345137
Lesenswert?

Rufus t. Firefly schrieb:
> Und das ist das gleiche Problem:
>
1
>  private:
2
>      Ui::CalculatorForm ui;
3
>  };
4
>
>
> Das ist das Ende der Deklaration der Klasse Ui::CalculatorForm. Und
> damit deklarierst Du eine Membervariable namens "ui" vom Typ
> Ui::CalculatorForm, also genau dem Typ, von dem die gerade deklarierte
> Klasse ist.

Nicht ganz.
Diese Member ist vom Typ Ui::CalculatorForm.
Seine eigene CalculatorForm ist aber im globalen Namespace.
#1345139
Lesenswert?

Andre schrieb:
> Soory, aber ich komme icht weiter.
> Hat jemand ein bespiel das ich 1 ein zu eins in mein umgebung einfüge
> kann ohne irgendwelche spezifischen Syntaxänderungen.

Wie schon gesagt:
Dein Fehler war, dass du deine eigene test3 Klasse in den UI Namespace 
gelegt hast.
#1345143
Lesenswert?

So sollte es besser gehen
1
#include <QApplication>
2
#include <QWidget>
3
#include <QLabel>
4
#include <iostream>
5
#include "ui_test3.h"
6

7
using namespace std;
8

9
class test3 : public QWidget
10
{
11
     Q_OBJECT
12

13
 public:
14
     test3(QWidget *parent = 0);
15

16
 private slots:
17
     void on_inputSpinBox1_valueChanged(int value);
18
     void on_inputSpinBox2_valueChanged(int value);
19

20
 private:
21
     Ui::test3 ui;  
22
};
23

24
int main(int argc, char* argv[])
25
{
26
   QApplication app(argc, argv);
27
   QWidget *widget = new QWidget;
28
   test3 ui;
29
   ui.setupUi(widget);
30

31
   widget->show();
32
   return app.exec();
33
}


zumindest compilermässig. Ob es funktioniert, kann ich mangels QT nicht 
sagen.

Und lies in deinem Stroustroup nach, was es mit Namespaces auf sich hat.
Persönliche Seite #1345174
Lesenswert?

Karl heinz Buchegger schrieb:
> Rufus t. Firefly schrieb:
>> Und das ist das gleiche Problem:
[schnipp]

> Nicht ganz.
> Diese Member ist vom Typ Ui::CalculatorForm.
> Seine eigene CalculatorForm ist aber im globalen Namespace.

Du hast --natürlich-- recht.

Könnte es sein, daß diese Art der Programmierung ein fitzelkleines 
bisschen fehlerträchtig und vielleicht auch ein winziges bisschen 
unübersichtlich ist?
#1345175
Lesenswert?

Rufus t. Firefly schrieb:

> Könnte es sein, daß diese Art der Programmierung ein fitzelkleines
> bisschen fehlerträchtig und vielleicht auch ein winziges bisschen
> unübersichtlich ist?

LOL.
Das -- könnte -- allerdings sein.

(Qt hat mich auch schon an den Rand des Wahnsinns getrieben. Speziell 
der Resource-Editor erzeugt bei mir regelmässig Blutrausch :-)
#1345242
Lesenswert?

Rufus t. Firefly schrieb:
> (Ja, ich oute mich. Als Qt-Nichtbenutzer. Wenn das da beispielhaft für
> Qt ist, dann wird es wohl auch dabei bleiben.)

Na, so schlimm ist es nicht.

Da gibt es einen Resource Editor, der für jeden Dialog eine Klasse im Ui 
Namespace anlegt.
Deinen eigenen Dialog legst du selber an, leitest ihn (ich glaube es war 
eh von QWidget ab), verpasst ihm das Member aus dem Ui Namespace mit dem 
gleichen Namen und im Grunde wars das dann auch schon.
Fast: Dann geht das Gedöns los, wie man die ganzen Files ins Dev Studio 
reinbringt (da ich weiß, dass du Dev Studio benutzt).

Geht alles nach Schema F.
Persönliche Seite #1345263
Lesenswert?

> (da ich weiß, dass du Dev Studio benutzt)
Tu ich zwar, aber mit --igitt-- der MFC.

Hab' ich mir nicht ausgesucht, ist historisch gewachsen. Mein erstes 
größeres MFC-Projekt habe ich vor 14 Jahren verbrochen ... und muss es 
nach wie vor gelegentlich warten.

Als Alternative habe ich mir mal wxWidgets ausgeguckt, das scheint 
konzeptionell nicht völlig anders gelagert zu sein als die MFC, ist aber 
wohl erheblich orthogonaler.

Der Leidensdruck ist bislang noch nicht so groß; ich habe mich erst vor 
etwa einem Jahr final vom Developer Studio 6 getrennt (und alle 
Zwischenstufen bis vor 2008 übersprungen).

Naja, und wenn ich mich wirklich arg langweilen sollte, werde ich mir 
Objective-C näher ansehen, da das die Haus- und Hof-sprache der von mir 
privat zunehmend genutzten Systeme ist.

Ich schweife ab ...

> Da gibt es einen Resource Editor [...]
> Deinen eigenen Dialog legst du selber an, [...]
> verpasst ihm das Member aus dem Ui Namespace mit dem
> gleichen Namen und im Grunde wars das dann auch schon.

Das klingt immerhin auch irgendwie verständlich. Wenn man das aber 
unvorbereitet sieht, erschrickt man, weil es ziemlichem Quark ähnlich 
sieht.
#1345271
Lesenswert?

Rufus t. Firefly schrieb:

> Der Leidensdruck ist bislang noch nicht so groß; ich habe mich erst vor
> etwa einem Jahr final vom Developer Studio 6 getrennt (und alle
> Zwischenstufen bis vor 2008 übersprungen).

Ich habs immer noch (unter anderem).
(PSt nicht weiter sagen: Ich fühl mich eigentlich recht wohl damit)
Persönliche Seite #1345434
Lesenswert?

(zunehmend OT)
Der C- und vor allem der C++-Compiler der neueren Version scheint um 
Größenordnungen besser geworden zu sein, und der Debugger gefällt mir 
auch besser; hier insbesondere die Fähigkeit des Remote Debugging mit 
"Andocken" an bereits laufende Prozesse. Das ist für meine Arbeit doch 
recht wichtig und hat mir den Abschied von VC6 leichtgemacht.
Allerdings ist der "Class Wizard" und das zugehörige Geraffel eher ein 
Rückschritt, und ob mir die schon wieder komplett anders aufgebaute 
Online-Hilfe wirklich gefallen mag, das weiß ich auch nicht.
Persönliche Seite #1345799
Lesenswert?

Rufus t. Firefly schrieb:

> Als Alternative habe ich mir mal wxWidgets ausgeguckt, das scheint
> konzeptionell nicht völlig anders gelagert zu sein als die MFC, ist aber
> wohl erheblich orthogonaler.

WxWidgets ist anders als MFC, nur die Schnittstelle sieht ähnlich aus. 
Es ist für mich die Cross-Plattform-Bibliothek der Wahl, weil 
ausgereift, umfangreich und gleichzeitig sehr schlank. Und für viele 
Plattformen verfügbar.
Gast #1345812
Lesenswert?

>> Nicht ganz.
>> Diese Member ist vom Typ Ui::CalculatorForm.
> Seine eigene CalculatorForm ist aber im globalen Namespace.
>
> Du hast --natürlich-- recht.
>
> Könnte es sein, daß diese Art der Programmierung ein fitzelkleines
> bisschen fehlerträchtig und vielleicht auch ein winziges bisschen
> unübersichtlich ist?

Warum Qt hier einen namespace verwendet, weiß ich auch nicht. Aber den 
ui-Typ gibt's auch unter dem Namen "Ui_CalculatorForm" ohne Namespace. 
Abgesehen davon kann man sich den Namen der Klasse natürlich selbst 
aussuchen, und es ist ja nicht der Qt anzulasten, wenn der 
Programmierer hier Namen wählt, mit denen er sich selbst austrickst.


> Echte Männer verzichten auf ui und coden ihr Layout in Qt selbst :o)

Noch echtere Männer benutzen ui-Files, aber erzeugen sie mit vi ;-)
Gast #1346048
Lesenswert?

Deine Fehlermeldungen passen nicht zum Code.

> main.cpp|22|error: field 'ui' has incomplete type|
> main.cpp|39|error: 'Test3' is not a member of 'Ui'|

Im obigen Code enthält Zeile 22 folgendes:
1
 private:

und Zeile 39 ist eine Leerzeile.

Wie hast du im Designer den Dialog genannt? Heißt er da auch wirklich 
Test3?
Gast #1346084
Lesenswert?

Also muss in der .ui-Datei etwas stehen wie
1
class Ui_MainWindowClass
2
{
3
public:
4
    void setupUi(QMainWindow *MainWindowClass )
5
    {..}
6
    void retranslateUi(..){..}
7

8
};
9

10
namespace Ui
11
{
12
    class MainWindowClass : public Ui_MainWindowClass {};
13
} // namespace Ui

In deiner Klasse muss dann stehen:
1
class Foo: public QMainWindow
2
{
3
Q_OBJECT
4
public:
5
Foo(QWidget* parent = 0, Qt::WFlags flags = 0);
6
virtual ~Foo();
7
private:
8
Ui::MainWindowClass ui;
9
};
10

11
Foo::Foo(QWidget* parent, Qt::WFlags flags)
12
:QMainWindow(parent,flags)
13
{
14
  ui.setupUi(this);
15
}

Damit sollte es erledigt sein.
Gruß
Gast0815
#1346160
Lesenswert?

Tip:

Nicht einfach nur die Beispiele von Trolltech übernehmen, compilieren, 
laufen lassen und "nett" sagen.

In jedes Header File hineinsehen, welche Klassen sind da drinnen.
Wo gehts bei der Demo-Applikation los? Welches Objekt wird erzeugt? 
Welche Member hat dieses Objekt? Wo kommen diese Member wiederrum her?
Interessant sind auch immer Konstruktoren und Destruktoren der Klassen, 
weil sich in ihnen vieles von der Setup-Arbeit verbirgt.

Demos muss man studieren!
Ein Notizblock und ein Bleistift neben dem Monitor helfen ungemein um 
sich Gedankengänge und Dinge die man herausgefunden hat zu notieren. 
Geschriebenes merkt man sich leichter!
Gast #1346194
Lesenswert?

Korrektur:
In der .ui-Datei steht natürlich kein Quellcode!
Der erst genannte Code steht in der ui_xxx.h.
Die eigene Klasse muss diese Header-Datei einbinden.

Danach noch eine Instanz dieser Klasse erzeugen, und
show() aufrufen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren