PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Problem mit Qt



smog_at
14-09-2003, 16:32
Hey @all,

So, ich habe mir nun das Buch "Programming with Qt" vom O'Reilly Verlag bestellt, nun wollte ich halt mein bisher gelerntes in die Praxis umsetzen, und ein kleines Programm erstellen, jedoch scheitert es sogar bei meinem ersten Programm, aber hier mal der Quelltext:





#include <qapplication.h>
#include <qpushbutton.h>
#include <qwidget.h>

class MyApplication : public QWidget {
public:
MyApplication();
~MyApplication();
};

MyApplication::MyApplication() {
QPushButton *buttonPush = new QPushButton("Push", this);
buttonPush->setGeometry(10,50,100,30);

QPushButton *buttonExit = new QPushButton("Exit Program", this);
buttonExit->setGeometry(10,100,100,30);

QObject::connect(buttonExit, SIGNAL(clicked()), this, SLOT(quit()));
}

MyApplication::~MyApplication() {
}

int main(int argc, char*argv[]) {
QApplication myapp(argc, argv);

MyApplication *mywidget = new MyApplication();
mywidget->setGeometry(400,300,200,200);

myapp.setMainWidget(mywidget);
mywidget->show();
return myapp.exec();
}



Könnt Ihr mir etwas helfen und sagen, warum ich wenn ich auf den Exit-Button draufklicke sich nichts tut?

Wenn ich das Programm starte erscheint folgende Meldung:
QObject::connect: No such signal QWidget::clicked()
QObject::connect: (sender name: 'unnamed')
QObject::connect: (receiver name: 'unnamed')

Vielen Dank im Voraus
MfG Flex

tuxipuxi
14-09-2003, 16:48
hi,

2 sachen, erstens:

in klassen brauchst du kein QObject:: vor dem connect, das nur ausserhalb von von QObject abgeleiteten klassen.

und die fuer dein problem wichtigere sache:

der connect muss so aussehen:


connect(buttonExit, SIGNAL(clicked()), qApp, SLOT(quit()));


bei deinem code wuerde der quit() slot in QWidget definiert sein, der ist aber in QApplication.

qApp ist ein programmweiter pointer auf dein QApplication object.


gruss,

tuxipuxi.

smog_at
14-09-2003, 17:34
Vielen Dank @tuxipuxi für Deine schnelle Hilfe,

Funktioniert einwandfrei!

MfG Flex

anda_skoa
15-09-2003, 18:31
Original geschrieben von tuxipuxi
in klassen brauchst du kein QObject:: vor dem connect, das nur ausserhalb von von QObject abgeleiteten klassen.


Schadet aber nicht :)
connect ist static, durch die Schreibweise QObject::connect macht man eindeutig klar, welche Methode man meint.
Kann schon mal passieren, dass man selbst auch eine Methode mit dem Namen connect hat.

Ciao,
_

tuxipuxi
15-09-2003, 18:42
einigen wir uns auf:

"schaden tuts nicht, tun tuts keiner" ;)?

anda_skoa
15-09-2003, 19:08
Original geschrieben von tuxipuxi
einigen wir uns auf:

"schaden tuts nicht, tun tuts keiner" ;)?

Ich tu's :)

Ciao,
_

smog_at
15-09-2003, 19:18
OK, ich möchte keine neuen Thread deswegen anfangen, ich hab da noch ein Problem, und zwar habe ich mit QT-Designer mein Forumlar erstellt, die UIC, und MOC befehle ausgeführt, sodass ich nun eine Datei namens progImpl.h und progImpl.cpp habe, im progmain.cpp erstell ich nichtmehr meine Objekte mit Prog1 sondern von der Abgeleiteten Klasse prog1Impl, soweit so gut, nur wenn ich jetzt die Slots in der Datei progImpl.cpp ändere auf textFielfInput->setText("Neuer Text") erscheint beim kompilieren eine Fehlermeldung

Kann mir da bitte jemand weiterhelfen?

MfG Flex

tuxipuxi
15-09-2003, 19:36
wenn du uns die fehlermeldung zeigst :D

smog_at
15-09-2003, 19:53
ok, von Anfang an, habe nach dem O'Reilly Buch gearbeitet:
Habe das Dialogfeld gespeichert unter prog.ui und danach folgende Befehle ausgeführt


uic -o prog.h prog.ui
uic -o prog.cpp -impl prog.h prog.ui
uic -o progImpl.h -subdecl progImpl prog.h prog.ui
uic -o progImpl.cpp -subimpl progImpl progImpl.h prog.ui



Danach in der Datei progImpl.cpp:


void progImpl::mySlot() {
textFieldInput->setText("Neuer Text");
//qWarning("progImpl::mySlot() not yet implemented!");
}


In der Datei progmain.cpp steht folgendes:


#include <qapplication.h>
#include "progImpl.h"

int main(int argc, char* argv[]) {
QApplication myapp(argc, argv);

progImpl mywidget;
myapp.setMainWidget(&mywidget);
int iReturn = myapp.exec();
return iReturn;
}


Danach noch folgendes:


moc -o moc_prog.cpp prog.h
moc -o moc_progImpl.cpp progImpl.h
moc -o moc_progmain.cpp progmain.cpp



Und danach kompiliert:

g++ -I$QTDIR/include prog.cpp progmain.cpp progImpl.cpp moc_prog.cpp moc_progImpl.cpp -L$QTDIR/lib -lqt -o prog


Anschliessend erscheint dann folgende Fehlermeldung:


progImpl.cpp: In member function 'virtual void progImpl::mySlot()':
progImpl.cpp:28: invalid use of undefined type 'struct QLineEdit'
prog.h:20: forward declaration of 'struct QLineEdit'

MfG Flex

deki
15-09-2003, 19:57
In die Datei progImpl.cpp müsstest du an den Anfang ein
#include <qlineedit.h>setzen, damit du auch die Methoden dieser Klasse verwenden kannst.

smog_at
15-09-2003, 20:05
In der Datei progImpl.cpp steht momentan:

#include "progImpl.h"

Und in der steht wiederrum:

#include "prog.h"


Prog.h:

#include <qvariant.h>
#include <qdialog.h>

class QVBoxLayout;
class QHBoxLayout;
class QGridLayout;
class QPushButton;
class QLineEdit;

class Prog:public QDialog {
.
.
.
.
}
.
.
.
.
.



Das heisst ich muss in der Subclass-Datei (progImpl.h) nochmal für jedes Objekt, beispielsweise QLineEdit, QPushButton, usw. was ich halt verwende noch einbinden?
Habe Ich das Richtig verstanden, ich dachte das wird mit den UIC und MOC befehlen eingebunden?

MfG Flex

deki
15-09-2003, 20:40
Ja, du musst dort aber nur die Dateien einbinden, von denen du auch innerhalb der Datei
auf Methoden der Objekte zugreifen willst.

tuxipuxi
15-09-2003, 20:40
was du/der designer da nun gemacht hat weiss ich nicht, ich mag den nicht.
auf jeden fall hat deki aber recht mit dem einbinden von qlineedit.h

gruss,

tuxipuxi.

edit: da wahr wohl jemand schneller :p

anda_skoa
16-09-2003, 10:12
Original geschrieben von smog_at
Das heisst ich muss in der Subclass-Datei (progImpl.h) nochmal für jedes Objekt, beispielsweise QLineEdit, QPushButton, usw. was ich halt verwende noch einbinden?


In der CPP Datei, nicht in der H Datei.



Habe Ich das Richtig verstanden, ich dachte das wird mit den UIC und MOC befehlen eingebunden?


Da wird sinnvollerweise mit Forward Declaration gearbeitet, denn es müssen im Header nur die Klassennamen bekannt sein.

Ciao,
_

axeljaeger
16-09-2003, 13:48
Du weist aber schon, das du ab Qt 3 nicht mehr von der Designerform ableiten musst?

smog_at
16-09-2003, 14:17
@axeljaeger

wie meinst Du damit, ich muss nicht mehr von der Designerfrom ableiten, was soll ich sonst machen, bzw. wie könnte ich es eleagnter lösen?

MfG Flex

tuxipuxi
16-09-2003, 14:23
eleganter garnicht.

du kannst zwar auch connections und sowas im designer machen, davon wuerde ich dir aber definitiv mit nachdruck abraten. der designer ist als "designer" gedacht, code sollte man komplett in subclasses auslagern. in .ui.h dateien rumzuhacken und mit klicks connections zu machen ist vielleicht ganz angenehm, man spart sich ja das tippen, einen gefallen tust du dir damit aber sicher nicht. das wird einfach nur unuebersichtlich und du steigst nicht mehr durch. WENN du den designer schon benutzt( wovon ich dir erstmal auch abraten wuerde, kannst du dir zu einem spaeteren zeitpunkt anschauen ), dann wirklich nur als designer, nicht als IDE.


gruss,

tuxipuxi.

smog_at
16-09-2003, 14:33
Ich verwende Qt-Designer wirlich nur, um meine Dialogfelder zu deisgnen,
coden tue ich mit VI (ist mir igrendwie ans Herz gewachsen:D )

mit eleganter meinte ich nur weil axeljaeger mich ein bisschen mit der aussage verwirrt hat. Denn die Subclass deklariere ich in den *Impl.cpp bzw. *Impl.h somit war die aussage ein bisschen verwirrend

MfG Flex

axeljaeger
16-09-2003, 15:18
Im Designer von Qt 2 musste man ableiten, weil man keine Membervariablen setzen konnte. Mit Qt 3 kannst du:

a) den Quelltext in eine ui.h schreiben
b) Membervariablen, Includes und ähnliches im Object-Explorer eintragen

Eleganter finde ich daran, das man mit weniger Dateien auskommt.

@tuxipuxi

Gut, du magst den Designer nicht, ich mag ihn halt. Für die Megaprojekte würd ich den jetzt auch nicht nehmen, aber das visuelle Gestallten ist schon sehr angenehmen.

anda_skoa
16-09-2003, 16:33
Original geschrieben von tuxipuxi
mit klicks connections zu machen ist vielleicht ganz angenehm, man spart sich ja das tippen, einen gefallen tust du dir damit aber sicher nicht. das wird einfach nur unuebersichtlich und du steigst nicht mehr durch.

Ausnahme sind da Verbindungen zwischen den Elementen selbst.
Zum Beispiel wenn ein Toggle Button andere Element enabled/disabled.
Denn das kann man dan sogar im Preview testen.

Ciao,
_

axeljaeger
16-09-2003, 16:45
@tuxipuxi

Ich muss da auch nicht mehr durchsteigen, das soll ja das Programm machen. Außerdem: Hast schonmal versucht, ein anständiges QGridLayout mit der Hand zu machen? Da tust DU dir keinen Gefallen, das erstmal auf Papier aufzuzeichnen, überlegen, welche Zellen verbunden werden müssen, usw. Der neue KConfigDialog wird auch massiv Qt-Designer ui-Files nutzen.