Sep 012017
 

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.

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(required)

(required)