Manually creating + using an event loop


  • Moderators

    Hi all,

    I've been using Qt a few years now, but there are many features that I haven't familiarized myself with yet.

    I was just reading the documentation on QEventLoop http://doc-snapshot.qt-project.org/5.0/qtcore/qeventloop.html It says "At any time, you can create a QEventLoop object and call exec() on it to start a local event loop", which sounds like I can create an event loop separate from the main loop.

    I can't figure out though, how to manually use that event loop to handle events. I know that I can "bind" QObjects to a QThread's event loop via moveToThread(), but how does QEventLoop fit into the picture?

    Thanks!




  • Moderators

    Thanks, hardcodes.de. That page doesn't talk about QEventLoop though :)



  • Up until now I only created my own eventloop to wait for signals. But this is discouraged in "this article":http://www.developer.nokia.com/Community/Wiki/How_to_wait_synchronously_for_a_Signal_in_Qt. Creating your own eventloop in a thread that already has its own eventloop seems to be error prone.


  • Moderators

    Hmm... yea, that sounds dangerous. I'd use a slot to wait for a signal instead.



  • I use the eventloop to wait for signal and block while still keeping all the other eventloops and thus my application responding. This way I can easily simulate a synchronous behaviour with an asyncronous architecture (for example a syncronous socket).



  • I made a little GUI application.
    There is one MainWindows with QTextEdit and two buttons "ButtonLoop" and "ButtonQuitLoop"

    So, we have in "mainwindow.h"

    class MainWindow : public QMainWindow
    {
    ...
    signals:
        void quitLoop();
    ...
    private slots:
    ...
        void on_pushButtoLoop_clicked();
        void on_pushButtonQuitLoop_clicked();
    private:
    ...
        void loop();
    }
    

    In "mainwindow.cpp" we have following code:

    ...
    void MainWindow::on_pushButtonLoop_clicked()
    {
        loop();
    }
    
    void MainWindow::on_pushButtonQuitLoop_clicked()
    {
        emit quitLoop();
    }
    
    void MainWindow::loop()
    {
        ui->textEdit->append("loop started");
        QEventLoop loop;
        QObject::connect(this, SIGNAL(quitLoop()), &loop, SLOT(quit()), Qt::QueuedConnection);
        loop.exec();
        ui->textEdit->append("loop finished");
    }
    

    I start application.
    Then i click ButtonLoop.
    Only text "loop started" is printed in textEdit.
    Text "loop finished" is printed just when i click ButtonLoopQuit.

    So, we have a small event loop inside function.



  • I see, that i can create two and more simultaneously working event loops.


  • Moderators

    [quote author="KA51O" date="1354718128"]I use the eventloop to wait for signal and block while still keeping all the other eventloops and thus my application responding. This way I can easily simulate a synchronous behaviour with an asyncronous architecture (for example a syncronous socket).[/quote]Ah, I see. That's a clever hack. My only experience with networking so far has been through QNetworkAccessManager; I'll keep your example in mind if I need synchronous behaviour in the future.

    @i.g.chernyak.., thank you for sharing. Did you have a use for the 2 event loops? (for example, have you used it in a "real" program?)



  • I used my local event loops in my "real" program once. I had a method that ensured that user meets some complicated criteria and I needed that method to be synchronous. That involved a few dialogs to show. I used Qt State Machine framework to model user flow in this case but I needed to wait until state machine is finished. As QStateMachine::start() is not blocking I used trick with local event loop:
    @
    bool AssureUserIsAllowed() {
    QEventLoop loop;
    AssureUserIsAllowedStateMachine sm;
    QObject::connect(&sm, SIGNAL(finished()), &loop, SLOT(quit()));
    sm.start();
    loop.exec();
    return sm.IsUserAllowed();
    }
    @


  • Moderators

    Thanks for your example, dakron. I'm seeing a pattern in everyone's usage here -- pseudo-synchronous flow control, without blocking the main thread.

    The fact that one can "wait" on a QEventLoop without blocking the main thread suggests to me that the loop runs in a separate thread. Now, QThread automatically starts an event loop when its thread is started. Hmm... * goes off to ponder the similarities and differences in purpose between QThread and QEventLoop *



  • [quote author="JKSH" date="1354992623"]
    The fact that one can "wait" on a QEventLoop without blocking the main thread suggests to me that the loop runs in a separate thread.*[/quote]
    HI, im not sure but maybe the main thread seems unblocked becouse all the events are processed inside local QEventLoop and it has nothing to do with the separate thread? But its only a guess I dont know how it really works :)


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.