Seite 1 von 1

Beispiel für Qthread mit exec() - Timer in Thread

Verfasst: 20. Juli 2009 18:35
von pospiech
Ich habe bei den Tutorials und den Demos von Qt kein Beispiel zur Nutzung von Qt mit QThread und exec() finden können.

Allein von der Doku kapier ich nicht wie man es nutzen sollte.

Hintergrund: ich habe einen Thread mit run(), der vollständig funktioniert - jetzt will ich aber einen Timer einbauen und das klappt anscheint nur wenn es einen eigenen Event Loop hat. Dafür brauche ich jetzt eine Lösung.

Verfasst: 20. Juli 2009 18:39
von franzf
in run() ein exec() und du hast deine eigene EventLoop.
Du brauchst aber wahrscheinlich noch ein this->moveToThread(this), wenn die Events in jenem neuen Thread abgearbeitet werden sollen, denn dein eigenes Thread-Objeckt wird meist nicht in sich selber erstellt, sondern wo anders ;)

Verfasst: 20. Juli 2009 18:43
von pospiech
nun bin ich genau da wo ich es nicht verstehe. Sobald ich exec() ausführe, tut mein Thread nichts mehr.

Ich will aber ja gerade das die run() Funktion abgearbeitet wird.
Deshalb bräuchte ich ein brauchbares Beispiel.

und wohin soll das

Code: Alles auswählen

this->moveToThread(this)

Verfasst: 20. Juli 2009 18:50
von franzf
Ist das besser?
void QCoreApplication::processEvents ( QEventLoop::ProcessEventsFlags flags = QEventLoop::AllEvents ) [static]

Processes all pending events for the calling thread according to the specified flags until there are no more events to process.

You can call this function occasionally when your program is busy performing a long operation (e.g. copying a file).

In event you are running a local loop which calls this function continuously, without an event loop, the DeferredDelete events will not be processed. This can affect the behaviour of widgets, e.g. QToolTip, that rely on DeferredDelete events to function properly. An alternative would be to call sendPostedEvents() from within that local loop.

Calling this function processes events only for the calling thread.

Note: This function is thread-safe.
statt exec().

Ich nehme an du hast ne Schleife, die ewig durchlaufen wird, in run()?

und

Code: Alles auswählen

this->moveToThread(this);
dachte ich wäre klar, dass das in den Konstruktor deines eigenen Thread kommt...

Verfasst: 20. Juli 2009 19:03
von solarix
Ich habe bei den Tutorials und den Demos von Qt kein Beispiel zur Nutzung von Qt mit QThread und exec() finden können.
Forumssuche nach "QTimer" und "QThread"?
z.B. http://www.qtforum.de/forum/viewtopic.php?t=9064
franzf hat geschrieben:...
Du brauchst aber wahrscheinlich noch ein this->moveToThread(this), wenn die Events in jenem neuen Thread abgearbeitet werden sollen, denn dein eigenes Thread-Objeckt wird meist nicht in sich selber erstellt, sondern wo anders ;)
Ist beim QTimer egal... der lebt dann ja im Thread und kann daher auch Signals im Kontext des Threads versenden.. -> kein moveToThread() notwendig.
un bin ich genau da wo ich es nicht verstehe. Sobald ich exec() ausführe, tut mein Thread nichts mehr.
der wartet auf Events/Signals (ein Timeout, ankommende Daten eines Sockets oder sonst was). Du musst nur dafür sorgen, dass auch ein Event kommt ;)

Verfasst: 21. Juli 2009 10:04
von pospiech
Ich habe jetzt den timer als Pointer in der run() function construiert, so das er auf jeden Fall zum Thread dazugehört. Dann bekomme ich beim connect auch keine Fehlermeldung mehr.

Allerdings wird der Slot nie aufgerufen.

Code: Alles auswählen

private slots:
	void OnPowerTimerTimeout()
	{
		double destination = powerTimeline[powerTimelineIndex].powerPosition;
		RotationStage->PowerOn();
		RotationStage->move(destination / RotationStage->CountsToDegree());

		int delaytime = powerTimeline[powerTimelineIndex].timeUntilChange;
		powerTimer->setInterval(delaytime);
		powerTimer->start();
		powerTimelineIndex++;
	}

public:
	
	void run()
	{ 
		powerTimer = new QTimer();
		connect(powerTimer, SIGNAL(timeout()), this, SLOT(OnPowerTimerTimeout()), Qt::DirectConnection);
		powerTimelineIndex = 0;
		OnPowerTimerTimeout();

		runThread(); 
	}
	void runThread()
	{	
	....		


Verfasst: 21. Juli 2009 13:15
von franzf
Was steht in

Code: Alles auswählen

runThread();
?
Außerdem wirst du nie deine Eventloop abarbeiten, wenn du
1) kein exec();
2) oder nirgendwo QCoreApplication::processEvents();
stehen hast.

Verfasst: 21. Juli 2009 13:24
von pospiech
franzf hat geschrieben:Was steht in

Code: Alles auswählen

runThread();
?
Außerdem wirst du nie deine Eventloop abarbeiten, wenn du
1) kein exec();
2) oder nirgendwo QCoreApplication::processEvents();
stehen hast.
stimmt, ich habe weder noch.

Ich habe den Timer jetzt wieder in den MainThread gepackt, da es mir zu umständlich wurde.

Aber ich denke ich habe zumindest verstanden wie es gehen würde.

Nur wie ein Event aussehen soll, der in einem Thread mit exec() wieder eine Aktion auslöst ist mir noch nicht klar. Ist das einfach eine normale Funktion wie meine run(), oder eine public slot function?

Verfasst: 21. Juli 2009 14:48
von CaptnChaos
Ein QTimer benutzt QBasicTimer. QBasicTimer löst einen Event namens timerEvent(QTimerEvent *event) aus. Ohne EventLoop, die durch exec() gestartet wird oder dauerhaftes pollen der Events per processEvents() wird dieser Event (und alle anderen, falls du noch welche implementierst) nicht aufgerufen. Folglich wird der Timer nie einen Slot aufrufen können. Was du also tun musst, um einen Timer in einem Thread ordentlich zum laufen zu bekommen ist:

in der thread-header:

Code: Alles auswählen

class Thread : public QThread{
 Q_OBJECT
public:
 void run();
public slots:
 void timerBla();
}
in der thread-source:

Code: Alles auswählen

void Thread::run()
{
 QTimer timer;
 connect(&timer, SIGNAL(timeout()), this, SLOT(timerBla()));
 timer.start(100);
 while(1)
 {
  //Hier dein Thread-Code
  processEvents();  
 }
}

void timerBla()
{
 //Mach was beim timer-timout (alle 100ms)
}
PS: Bist du der Latex-Pospiech?

Verfasst: 21. Juli 2009 14:53
von pospiech
KernelPanic hat geschrieben: PS: Bist du der Latex-Pospiech?
ja, auch wenn ich in letzter Zeit fast nur noch C++ Code bearbeite...