QThread<->QEvent Problem (Events zu spät sichtbar)

Alles rund um die Programmierung mit Qt
Antworten
doitux
Beiträge: 12
Registriert: 21. September 2004 08:15

QThread<->QEvent Problem (Events zu spät sichtbar)

Beitrag von doitux »

Hallo.

Ich habe mich erstmals an QThread und QEvent ausprobiert und jetzt folgendes Problem:

Das ist meine main():

Code: Alles auswählen

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

int main( int argc, char **argv )
{
	QApplication a( argc, argv );
	Q_INIT_RESOURCE(deck);
	mainWindowImpl *w = new mainWindowImpl();
	a.setMainWidget( w );
	w->show();
	
	return a.exec();
}
In mainWindowImpl finden der eigentliche Programmablauf statt:

Code: Alles auswählen

class mainWindowImpl: public Q3MainWindow, public Ui::mainWindow {
Q_OBJECT
public:
Im Kostruktor der mainWindowImpl erstelle ich den Thread:

Code: Alles auswählen

mainWindowImpl::mainWindowImpl(Q3MainWindow *parent, const char *name)
     : Q3MainWindow(parent, name)
{
	setupUi(this);
        thread1 = new playerActionThread(this);
Für eine bestimmte Simulations-Sequenz brauche ich eine Thread-Klasse:

Code: Alles auswählen

class playerActionThread : public QThread {
public:
    	playerActionThread(Q3MainWindow* mainWindowImpl);
	Q3MainWindow *_mainWindowImpl;

Code: Alles auswählen

playerActionThread::playerActionThread(Q3MainWindow* mainWindowImpl)
    : QThread()
{
     	_mainWindowImpl=mainWindowImpl; 
}

void playerActionThread::run() 
 { 
 	this->sleep(1);
	qApp->sendEvent(_mainWindowImpl, new QEvent((QEvent::Type)preflopEvent_1)); 
        this->sleep(1);
	qApp->sendEvent(_mainWindowImpl, new QEvent((QEvent::Type)preflopEvent_2)); 
 	this->sleep(1);	
	qApp->sendEvent(_mainWindowImpl, new QEvent((QEvent::Type)preflopEvent_3));
	this->sleep(1);
 } 
in einer Elementfunktion von mainWindowImpl starte ich den Thread:

Code: Alles auswählen

void mainWindowImpl::preflopPlayerAction( int playerIA ) {
                       
	playerInAction=playerIA;

	thread1->setPlayerIA(playerInAction);
	thread1->start(); 
	thread1->wait(10000); 
Die Events nehme ich auch in mainWindowImpl entgegen:

Code: Alles auswählen

void mainWindowImpl::customEvent( QEvent * event ) 
{
 switch((int)event->type())
 {
 case preflopEvent_1: { z.B. textLabel->setText("Test1") }; 
			break;
 case preflopEvent_2: { z.B. textLabel->setText("Test2") }; 
			break;
 case preflopEvent_3: { z.B. textLabel->setText("Test3") }; 
			break;
} 
}
Ich hab mir das ganze so vorgestellt:
Wenn der Thread gestartet wird. Soll über die qApp->sendEvent() Funktion die GUI manipuliert werden. Wichtig war mir dabei dass zwischen den einzelnen Schritten mit this->sleep(1); gewartet wird.

Mit cout konnte ich sehen dass die Events alle mit dem richtigen Zeitabstand ausgeführt wurden. Allerdings sind sie nicht sofort auf der GUI sichtbar. Die GUI ist solange eingefroren bis das letzte Event abgearbeitet wurde. Danach ist die letzte Änderung (z.B. textLabel = "Test3") sichtbar. Also ausgeführt wurden Die Events schon aber die GUI hat sie nicht sofort angezeigt.

Das Programm kompiliert ohne Fehlermeldung. Aber zur Laufzeit gibt es nach dem Ausführen der Events immer:

QTimer can only be used with threads started with QThread
QTimer can only be used with threads started with QThread
QTimer can only be used with threads started with QThread
[...]

Diese Meldung wundert mich, da ich QTimer im Programm eigentlich gar nicht selber benutze. Google konnte dazu leider auch nichts sagen.

Kann mir jemand einen Tip geben was ich da falsch mache?

Vielen Dank schon mal im Voraus
doitux
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

http://doc.trolltech.com/4.1/qthread.html#sleep ist eine static-Funktion. Versuche es mal mit wait() und/oder benutz einen QTimer (was meiner Meinung nach sauberer ist).
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
doitux
Beiträge: 12
Registriert: 21. September 2004 08:15

Beitrag von doitux »

mmh mit wait() klappt es leider nicht.
Ich hab jetzt den Thread rausgenommen und die ganze Animation in der mainwindowimpl per single-shot-Timer gelöst. Ist zwar nicht so schön, aber für die Threads bin ich scheinbar nicht clever genug.
Antworten