Seite 1 von 1

[gelöst] QThreads und Event Loops

Verfasst: 2. April 2010 20:29
von default user
Hallo,

ich sitz' zur Zeit an einem simplen Konsolenprogramm, dass aus main() und einer von QThread abgeleiteten Klasse besteht. in main() werden Argumente verarbeitet und dann wird der Thread erzeugt. Im Moment kann ich jedoch im Thread keine Funktionen wie etwa quit() benutzen, bzw. sie bewirken nichts.

Code: Alles auswählen

// main.cpp
#include <QtCore>
#include <QCoreApplication>
#include <thread.h>

using namespace std;

int main(int argc, char *argv[])
{
	QCoreApplication a( argc, argv );

    if( argc == 1 )
    	return 1;

    QString file;
    file = argv[1];

    thread *thread1 = new thread( file );
    thread1->start();

    return a.exec();
}

Code: Alles auswählen

// thread.h
#ifndef THREAD_H_
#define THREAD_H_
#include <QThread>
#include <QString>
#include <QCoreApplication>

class QProcess;

class thread: public QThread {

	Q_OBJECT

private:
	QProcess *process;
private slots:
	void getOutput();
public:
	thread( QString file, QObject *parent = 0);
	virtual ~thread();
protected:
	void run();

};

#endif /* THREAD_H_ */

Code: Alles auswählen

// thread.cpp
#include "thread.h"
#include <QObject>
#include <QProcess>
#include <iostream>
#include <QtCore>
#include <QCoreApplication>

using namespace std;


thread::thread( QString file, QObject *parent){

	QObject *myParent = new QObject();

	process = new QProcess( myParent );
	connect( process, SIGNAL(readyReadStandardOutput()), this, SLOT(getOutput()) );

	QStringList strList;
	strList << "e" << file;

	process->start( "unrar", strList );

}

void thread::run(){
	exec();
}

void thread::getOutput(){

	QString output = process->readAll();
	cout << output.toStdString() << endl;
	if( output.contains( "All OK") ){
		cout << "exit..." << endl;
		process->kill();
		quit();
	}
}

thread::~thread() {
}
Damit soll erstmal einfach ein rar-file entpackt werden und die Ausgabe weitergegeben werden. Ich erhalte zum Schluss die Ausgabe:
All OK
exit...
Das Programm beendet sich jedoch nicht, obwohl es das if-statement erreicht worin das Programm beendet werden soll.
Hat der Thread überhaupt eine EventLoop, oder würden die SLOTS ohne EventLoop erst garnicht funktionieren?
Woran liegt es sonst, dass nicht beendet wird?

Danke im Voraus.

Verfasst: 2. April 2010 21:38
von Christian81
Den QProcess solltest Du schon innerhalb des Threads starten (also innerhalb von ::run() - siehe Doku)
Mit quit() beendest Du außerdem nicht die Applikation sondern den Thread (wieder Verweis auf die Doku)

Verfasst: 2. April 2010 21:57
von default user
Wenn der Thread nun beendet wird, wo wird die Ausführung dann fortgesetzt? in main()? Wie soll die Implementierung von main() aussehen, um bei beenden von thread1 zu beenden?
SIGNALS und SLOTS ließen sich meines Wissens nicht dort einrichten, da es keine von QObject abgeleitete Klasse ist.

Verfasst: 2. April 2010 23:47
von Chris81T
Nun gut, du hast ja in der main deinen Thread gestartet. Zu dem Zeitpunkt wird ja dann die run() des Threads in der Thread-Umgebung ausgeführt. Der Mainthread wartet nun nicht, laut deinem Code, und geht so in die Qt EventLoop.

Wenn ich das richtig verstehe, so soll nach Beendigung deines Threads die ganze Applikation beendet werden?

Beispiel:
Man kann schon prima das Signal / Slot Handling einsetzen. Dein Thread Objekt sendet zB. ein Signal finished() aus und die QCoreApplication bietet auch ein paar nette Slots an ;) (siehe Dokumentation)

Falls die Anwendung nur mal ein Beispiel sein soll, um einen QThread zu verwenden / zu verstehen, okay. Ansonsten find ich den extra erzeugten Thread etwas überflüssig.

Dann mal viel Erfolg.

Verfasst: 3. April 2010 00:19
von default user
Chris81T hat geschrieben:Man kann schon prima das Signal / Slot Handling einsetzen.
Ja klar, ich hab' da was durcheinandergebracht. Die Funktion, die die Signal/Slot Verbindung erstellt, muss natürlich nicht von QObject abgeleitet sein, sondern nur die beteiligten Objekte.
Ich hab' jetzt in main() das Signal thread1finished() mit a.quit() verbunden, in thread1 dann process.finished() mit quit(). Funktioniert problemlos.
Falls die Anwendung nur mal ein Beispiel sein soll, um einen QThread zu verwenden / zu verstehen, okay. Ansonsten find ich den extra erzeugten Thread etwas überflüssig.
Mir ist klar wozu man Threads verwendet :wink:
Ich hab' einfach Teile des Codes rausgenommen in denen keine Probleme auftauchen, und fertig ist es allemal nicht.