[solved] QEventLoop und QThread

Alles rund um die Programmierung mit Qt
Antworten
cooky1976
Beiträge: 76
Registriert: 24. Januar 2008 00:19

[solved] QEventLoop und QThread

Beitrag von cooky1976 »

Hallo,

ich muss leider nochmals ein altes Thema aufwärmen. Ich muss nun doch in einem QThread events abarbeiten. Allerdings kann ich nicht auf die QThread::exec() zurückgreifen, da ich die run() überschreiben musste.

Ich würde also gerne die EventQueue zwischendurch pollen.

Ich habe also in der klasse x definiert:

Code: Alles auswählen

connect(this, SIGNAL(test()), &thread, SLOT(test()),Qt::QueuedConnection);
und in der Thread-Klasse

Code: Alles auswählen

Testthread::run() {
    QEventLoop eventLoop;
...
    bool test = eventLoop.processEvents();
...
}
Aber selbst wenn ich das Signal emittiere, wird der Slot nicht aufgerufen. Wo ist denn da mein Problem?

Danke

Alexander
Zuletzt geändert von cooky1976 am 21. Mai 2009 14:18, insgesamt 1-mal geändert.
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Und warum machst du es nicht so wie in den Beispielen?

Code: Alles auswählen

void MyThread::run()
{
    Code();
    MoreCodeWithSignals();
    exec();
}
cooky1976
Beiträge: 76
Registriert: 24. Januar 2008 00:19

Beitrag von cooky1976 »

Weil ich, wie ich schon geschrieben habe, eine eigene run()-Methode brauche und die ganze Zeit aktiv in dieser drin sein muss. Es wird da ein anderes Framework implementiert. Langer Rede kurzer Sinn, es geht einfach nicht.
Würde die exec() nur angestossen werden und die Verarbeitung würde weitergeben, wäre es kein Problem. Aber nachdem ja in der exec() verblieben wird, bis zum Threadende - no way.

Also nochmals zu meiner Frage .... gibt es eine Möglichkeit, die threadeigene Eventqueue anzupollen? Und wenn ja, wo ist mein Ansatzfehler?

Ich zitiere mal die Doku:
At any time, you can create a QEventLoop object and call exec() on it to start a local event loop
Aber irgendwie muss es ja auch ohne exec funktionieren.

Danke

Alexander
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Dann mach es doch so wie du es immer machst...
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.
Dann noch ein bool loopStarted, welches Anfangs auf false ist, und nach dem exec() auf true gesetzt wird, damit exec() nur einmal aufgerufen wird. Und schon sind alle glücklich :)
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Ein exec() brauchst du scheinbar gar nicht. QCoreApplication::processEvents() reicht:

Code: Alles auswählen

#include <QThread>
#include <QDebug>
#include <QCoreApplication>

class Thread : public QThread
{
    Q_OBJECT
    public:
        Thread()
        {
            connect(this, SIGNAL(nextRun(int)), this, SLOT(on_nextRun(int)), Qt::QueuedConnection);
        }
    public Q_SLOTS:
        void on_nextRun(int val)
        {
            qDebug() << "run" << val;
        }
    Q_SIGNALS:
        void nextRun(int);
    protected:
        void run()
        {
            int start=111;
            while(true) {
                emit nextRun(start);
                start++;
                QCoreApplication::processEvents();
                QThread::msleep(1500);
            }
        }
};

Code: Alles auswählen

#include <QApplication>
#include <QSpinBox>
#include "thread.h"

int main( int argc, char **argv )
{
    QApplication app( argc, argv );
    Thread t;
    t.start();
    QSpinBox spin;
    spin.setRange(0, 99999);
    QObject::connect(&t, SIGNAL(nextRun(int)), &spin, SLOT(setValue(int)));
    QObject::connect(&spin, SIGNAL(valueChanged(int)), &t, SLOT(on_nextRun(int)));
    spin.show();
    return app.exec();
}
evtl. brauchst du noch im Konstruktor von Thread ein "this->moveToThread(this);"...

Grüße
Franz
cooky1976
Beiträge: 76
Registriert: 24. Januar 2008 00:19

Beitrag von cooky1976 »

Franz, danke, ich hätte die Sache vielleicht auf solved stellen sollen, was ich jetzt machen werde. Und somit kann man relativ einfach eine run überschreiben ohne die exec zu benötigen.

Man muss nur die Doku genau lesen (und intuitiv in der QApplication nach multithread-spezifischen Funktionen suchen) ;-)
Antworten