Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QTimer timeout signal isn't called when a local event loop is running



  • Hi there,

    I need to refresh some data every second. So I use a QTimer to update my data. On my app I have a QMenu as popup. If I exec the QMenu, it run a local QEventLoop. Because of that, my QTimer isn't called.

    Should I need QThread in this case?

    Best regards,
    robin


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    The local event loop created by your menu exec call handles the events in place of the main loop.

    One thing you can do is use the worker object approach and move you data collection code in a different thread.



  • From the QMenu docs:
    "They can be executed either asynchronously with popup() or synchronously with exec()."

    So even though they are getting their own event loop, if you are calling it with exec() then it will stop your event loop that is calling it until it returns something. You should instead try calling it with popup() and connect signals and slots to handle any asynchronous events coming from your popup menu.

    Hope it helps.


  • Moderators

    @robinfaury
    take a look at this example:

    int main(int argc, char *argv[])
    {
    
        QApplication a(argc, argv);
    
        QTimer t;
        QObject::connect(&t, &QTimer::timeout, []()->void{qDebug() <<QTime::currentTime().toString();});
        t.start(10);
    
        QDialog dia;
        dia.exec();
    
        return  a.exec();
    }
    

    you'll notice that the debug output does not stop. So simply calling exec on (in this case) QDialog doesn't block the signal handling.
    There has to be something different going on inside your code



  • @MrShawn Yes I see the popup behaviors but I need a synchronous process and the update.

    @SGaist @J-Hilk I found my mistake
    My QMenu exec is called inside the lambda.

    QApplication a(argc, argv);
    
    QTimer t;
    QObject::connect(&t, &QTimer::timeout, []()->void {
        qDebug() <<QTime::currentTime().toString();
        QDialog dia;
        dia.exec();
    });
    t.start(10);
    
    return  a.exec();
    

    Thanks for everything!

    Update: How can I set the thread as SOLVED?


  • Lifetime Qt Champion

    @robinfaury

    Update: How can I set the thread as SOLVED?

    With the button Topic Tools below the last post.

    Regards


Log in to reply