Um kurze Reaktionszeiten zu gewährleisten, macht der Gebrauch von Threads Sinn. Unter Qt kann mit der Klasse QThread die Methode QThread::run()
überladen werden. In dieser Methode wird der Thread-Code ausgeführt.
Die von QThread abgeleitete Klasse muss mit der Methode QThread::start()
gestartet werden. Damit der Thread am Signal/Slot-Mechanismus partizipieren kann, muss in der QThread::run()
-Methode die Methode QThread::exec()
ausgeführt werden. Diese führt dann die Event Loop aus, die für Signals und Slot nötig ist. Für die Thread-übergreifende Versendung von Signalen muss jetzt eine Connection via QObject::connect()
von einem Thread normal via emit in die Event Loop des Threads geschickt werden. Entgegen der irrigen Anname, das würde funktionieren, indem man aus dem Thread heraus die Connection verbindet, muss zuerst QObject::moveToThread()
auf das QThread-Objekt vor Aufbau der Connections aufgerufen werden.
Ein Beispiel beschreibt mehr, als tausend Worte. Hier zuerst die Implementierung einer QThread-Klasse:QThread-Klasse
class MyThread : QThread { Q_OBJECT public: MyThread() = default; void run() override { qDebug() << "Thread started:" << currentThreadId(); exec(); } public slots: void receive() { qDebug() << "Received:" << currentThreadId(); } };
Die Includes sind für die Lesbarkeit weggelassen worden. Im Haupt-Thread z.B. im Konstruktor der MainWindow-Klasse wird dann folgendes implementiert:MainWindow.cpp
... MainWindow::MainWindow() : ... { MyThread thread; ui->setupUi(this); thread.moveToThread(&thread); thread.start(); qDebug() << "Main thread:" << currentThreadId(); connect(this, &MainWindow::send, &thread, &MyThread::receive); emit send(); } ...
Im Header muss natürlich noch das Signal MainWindow::send()
declariert werden. Es können auch andere QObject-abgeleitete Klassen mit Slots in die Event Loop des Threads mit QObject::moveToThread()
verschoben werden.
Es bleibt noch zu erwähnen, dass die Verwendung der QTimer-Klasse impliziert, dass sie nur im selben Thread verwendet werden darf. Das kann z.B. damit erreicht werden, dass das Parent zu einer QObject-abgeleiteten Klasse gehört, die dem Thread-Kontext mit QObject::moveToThread()
schon zugeordnet wurde.