Seite 1 von 1

Ist Qthread richtig?

Verfasst: 6. März 2009 10:48
von Tokamak23
Hallo,

kurz zu mir:

ich bin QT Neuling und habe mich davor auch noch nie mit GUI Entwicklung auseinander gesetzt. Ich bin ein typischer Algorithmenentwickler, der seine Zwischenergebnisse nun irgendwie optisch präsentieren muss, damit man die Gültigkeit überprüfen kann.

Meine Aufgabe:

Ich habe eine LIB zur Berechnung von 2D-Signalspektren. Die 2D-Signalspektren verändern sich mit der Zeit. Die LIB wird von einem Testprogramm aufgegerufen, welches sich nicht verändern lässt. Nun möchte ich die Spektren anzeigen lassen.
Ich habe QT zusammen mit VTK dazugekriegt, dass ein Fenster geöffnet wird, indem das 2D-Spektrum eines Zeitpunktes angezeigt wird. Die GUI wird durch

Code: Alles auswählen

QApplication app;
...
app.exec();
Dadurch geht die GUI nun aber in ihre eigene main loop. Ich kann den dargestellten Inhalt nicht mehr von außen ändern.

Meine Frage daher:
Ich habe schon mehrfach gesucht und mir sind zwei Schlagworte aufgefallen QThread und QEventLoop. Sind das Hilfsmittel, die mir helfen könnten, oder gibt es Alternativen dazu?

Bin fuer jede Hilfe dankbar!!!

Grüße,
Dirk[/quote]

Verfasst: 6. März 2009 11:11
von AuE

Code: Alles auswählen

int main(int argc, char *argv[])
{
	QApplication a(argc, argv);
	
            ObjektDeinerGUI w;


	w.show();
return  a.exec();
	
}
s müsste deinen Main aussehen. Die Steuerelemente kannst du dann in deiner GUI Klasse behandeln etc.

Schau und debuge doch ml die demos![/quote]

Verfasst: 6. März 2009 11:23
von Tokamak23
Hi,

danke fuer die schnelle Antwort. Problem ist, dass ich mein Main nicht ändern kann. Das Main fuerht die Berechnung der Spektren aus und kann nicht die GUI starten. Die muss auf eine andere Art und Weise gestartet werden. Ich hoffe ich habe selber keinen Denkfehler drinnen ;).

Ich haette versucht deinen Codeschnippsel in einen eigenen QThread zu stecken, dass die GUI unabhängig von dem Rest meiner Main Methode laufen kann. Die Main Methode würde die Spektren berechnen und an die GUI weiterleiten.

Ich hoffe, das Problem ist ein wenig klarer geworden.

Danke,
Dirk

Verfasst: 6. März 2009 11:27
von AuE
mhhhhh ja schon nur du hast doch nicht deine ganze berechnung in einer Main- methode????

Die Methoden kannst du doch zb auch als Static in ne Klasse packen. Diese Klasse hat dann Signale die du bei zB Berechnung fertig sendest.
Deine GUI empfängt dieses Siignal und stellt dann das ergebnis dar.

Verfasst: 6. März 2009 12:25
von Tokamak23
Hi,

zum Verständniss nochmal:

Ich habe einer CoreLib, in welcher die Spektren berechnet werden. Diese CoreLib soll später in einem ganzen Framework eingesetzt werden. Um diese CoreLib zu testen, werden in einer Testmethode, welche auch die Main Methode beinhaltet, Daten eingelesen und der CoreLib übergeben.

Nun soll die CoreLib zusätzlich ein Fenster öffnen, in dem die Ergebnisse visuel dargestellt werden. Man kann sich nun die Frage stellen, wieso die Darstellung nicht in die Main Methode des Testprogramms wandert. Einfach aus dem Grund, weil ich auch in dem gesamten Framework die Ausgabe überprüfen möchte. In dem Framework gibts dann wieder eine andere Main Methode.

Daher wäre es aus meiner Sicht am einfachsten, ich würde eine zweite Lib schreiben, die nur die Visualisierung übernimmt und aus der CoreLib gestartet und beendet werden kann, unabhängig von der eigentlichen Main Methode.

Ich denke, dass das nur über einen Qthread in Verbindung mit einer Eventloop geht?

Ich bin für jede Hilfe dankbar, da ich nicht weiß, ob an der Denke was falsch ist :).

Grüße,
Dirk

Verfasst: 6. März 2009 12:49
von Tokamak23
Ich haetten die run() Methode meines MyThread nun so implementiert.

Code: Alles auswählen

class MyThread : public QThread 
{
public:

	vtkSmartPointer<vtkImageData>	spectrumData;

	virtual void run();

};

Code: Alles auswählen

void MyThread::run()
{
	/*int argc	=	0;
	char** argv	=	new char*("");
	QApplication* vtkApp		=	new QApplication(argc,argv);
	QMainWindow* vtkWindow		=	new QMainWindow();

...

	vtkWindow->show();
	vtkApp->exec();	*/

}
Nach meiner Denke würde ich ganz zu Beginn der Spektrenberechnung die run() Methode aufrufen, damit die GUI geöffnet wird. Bei jeder neuen Spektrenberechnung, würde ich dann das Member spectrumData verändern. Allerdings bekommt das der Thread nicht mit, da er ja bei dem exec() stehengeblieben ist. Kann man das dann updaten?

Danke,
Dirk[/code]

Verfasst: 6. März 2009 13:03
von solarix
Da fehlen wohl noch viele Grundlagen... zumal " Threading" nicht gerade ein Einstiegsthema ist (Synchronisierung usw...).

Also erstens solltest/musst du umdenken: die GUI wird im main gestartet und ist der "Haupthread". Siehe
http://doc.trolltech.com/4.5/threads.html
In GUI applications, the main thread is also called the GUI thread because it's the only thread that is allowed to perform GUI-related operations.
Weil du ja den Code fuer die Berechnung selbst stellst, ist dies jedoch kein Problem: Erstelle eine neue Klasse fuer diese Berechnung und verwende SIGNALs und SLOTs (bitte google fragen und einlesen falls dieses Prinzip unklar ist) und teile so der GUI mit, wenn die Berechnung (oder Teile davon) fertig sind.

Noch was zu "exec()": Das bedeutet nicht, dass deine Applikation (egal welcher Thread) "stehenbleibt", sondern das der weitere Ablauf ueber Events (bei Qt SIGNALs) gesteuert wird. Das kann sein: "Button XY wurde angeklick" oder "Periodischer Timer ist abgelaufen" oder ebene "Berechnung beendet"... aber falls dies unklar ist, solltest du dich wirklich erst mit dem SIGNAL/SLOT-Konzept vertraut machen.

Im die eigentliche Frage "ist QThread richtig" zu beantworten: ja, aber fuer deine Berechnung, nicht fuer die GUI...

Verfasst: 6. März 2009 13:45
von Tokamak23
Super.

Ich glaube ich komme einer funktionierenden Lösung immer näher. Wie bereits beschreiben, kann ich nicht und darf nicht die main() vom Testprogramm nicht ändern.

Wenn jedoch die GUI im main() gestarten werden muss, muss ich zwangsläufig zwei Prozesse generieren, die einen Datenaustausch z.B. ueber Sockets durchführen?

Damit haette ich mir natuerlich das schwierigste zuerst ausgesucht. Gebt ihr mir recht?

Grüße und besten Dank,
Dirk

Verfasst: 6. März 2009 14:12
von solarix
das mit dem unveraenderlichen main() habe ich ueberlesen.. sorry.. aber ich bin verwirrt:

* du musst die Berechnung im main() belassen
* aber du kannst diesen Code erweitern (um Threads oder IPC-Mechanismen wie Sockets)

Das beisst sich.. denn wenn du den Code veraendern kannst, kannst du ihn auch verschieben :roll:


Aber um noch auf deine Bemerkung einzugehen: ja, anstelle von Multithreading ginge natuerlich auch eine Multiprocess-Loesung... ueber (TCP- oder UDP-) Sockets waere eine Variante, eine andere QDBus... http://doc.trolltech.com/4.5/qtdbus.html

hth..

Verfasst: 6. März 2009 15:20
von Tokamak23
Hi,

danke fuer die rasche Antwort.

Ich kann dir main() sehr wohl verändern, nur darf sie um firmenkonform zu arbeiten nur das nötigste enthalten. Und das ist in diesem Fall das laden und testen der CoreLib.

Die Ausgabe in einer GUI spielt nur eine Nebenrolle. Ich dachte, dass ich das in einen Thread auslagern könnte. Da die qapplication aber in einer main() laufen muss, muss ich wohl zwei Prozesse erstellen, die ueber TCP/UDP kommunizieren.

Ihr habt mir sehr weitergeholfen, was das Verständnis anbelangt!!!

Danke,
Dirk