Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QEventLoop in showEvent() will trigger showEvent() twice!
QtWS25 Last Chance

QEventLoop in showEvent() will trigger showEvent() twice!

Scheduled Pinned Locked Moved Solved General and Desktop
10 Posts 4 Posters 562 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Q Offline
    Q Offline
    QtTester
    wrote on last edited by QtTester
    #1

    hi guys:
    win10 + 5.14.1, I has a problem , the showEvent() will trigger twice, in some condition the ui will be stuck, exec() will not return.here is my code:

    #define SHOWED 1
    void MainWindow::showEvent(QShowEvent *e)
    {
        Q_UNUSED(e);
        qDebug("1enter showE");
    
    #if SHOWED 
        QEventLoop loop;
        QTimer timer;
    
        //
        connect(&timer,&QTimer::timeout,this,[&](){
            qDebug("5time out");
            loop.quit();
        });
    
        // QEventLoop::
        connect(this,SIGNAL(sigTimerCallOut()),&loop,SLOT(quit()));
        QTimer::singleShot(0,this,[=](){
            qDebug("3exec in timer");
            emit sigTimerCallOut();
        });
    
        timer.setSingleShot(true);
        timer.start(3000);
        qDebug("2wait signal");
        loop.exec();
    #endif
    
        qDebug("4show End");
    }
    

    on the first time when app start ,it runs normal ,output:

    1enter showE
    2wait signal
    3exec in timer
    4show End
    

    now I minimise and resotre the window , it shows:

    1enter showE
    2wait signal
    3exec in timer
    1enter showE
    2wait signal
    3exec in timer
    4show End
    4show End
    

    after step by step debug after restoring window , at the first time it runs to :

    qDebug("3exec in timer");
    

    next it will emit the signal , but loop will not return and run at the begin of showEvent(), so

    1enter showE
    

    output again.
    Why will happen like this? thanks.

    JonBJ 1 Reply Last reply
    0
    • Q QtTester

      hi guys:
      win10 + 5.14.1, I has a problem , the showEvent() will trigger twice, in some condition the ui will be stuck, exec() will not return.here is my code:

      #define SHOWED 1
      void MainWindow::showEvent(QShowEvent *e)
      {
          Q_UNUSED(e);
          qDebug("1enter showE");
      
      #if SHOWED 
          QEventLoop loop;
          QTimer timer;
      
          //
          connect(&timer,&QTimer::timeout,this,[&](){
              qDebug("5time out");
              loop.quit();
          });
      
          // QEventLoop::
          connect(this,SIGNAL(sigTimerCallOut()),&loop,SLOT(quit()));
          QTimer::singleShot(0,this,[=](){
              qDebug("3exec in timer");
              emit sigTimerCallOut();
          });
      
          timer.setSingleShot(true);
          timer.start(3000);
          qDebug("2wait signal");
          loop.exec();
      #endif
      
          qDebug("4show End");
      }
      

      on the first time when app start ,it runs normal ,output:

      1enter showE
      2wait signal
      3exec in timer
      4show End
      

      now I minimise and resotre the window , it shows:

      1enter showE
      2wait signal
      3exec in timer
      1enter showE
      2wait signal
      3exec in timer
      4show End
      4show End
      

      after step by step debug after restoring window , at the first time it runs to :

      qDebug("3exec in timer");
      

      next it will emit the signal , but loop will not return and run at the begin of showEvent(), so

      1enter showE
      

      output again.
      Why will happen like this? thanks.

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by JonB
      #2

      @QtTester
      I don't understand your question or what your issue is. You set off a singleshot timer first time showEvent() is invoked and there you run a QEventLoop. If during the 3 seconds waiting for the singleshot to fire a new showEvent() is raised you receive another showEvent() then you will set off a new timer. The output shows what I would expect in such a situation.

      Calling QEventLoop::exec() inside a slot or event or waiting for a timeout like you do is not a good idea. I don't know what you are trying to achieve but there is doubtless a better way to accomplish it.

      Q 2 Replies Last reply
      4
      • JonBJ JonB

        @QtTester
        I don't understand your question or what your issue is. You set off a singleshot timer first time showEvent() is invoked and there you run a QEventLoop. If during the 3 seconds waiting for the singleshot to fire a new showEvent() is raised you receive another showEvent() then you will set off a new timer. The output shows what I would expect in such a situation.

        Calling QEventLoop::exec() inside a slot or event or waiting for a timeout like you do is not a good idea. I don't know what you are trying to achieve but there is doubtless a better way to accomplish it.

        Q Offline
        Q Offline
        QtTester
        wrote on last edited by
        #3

        @JonB thanks for reply.
        as i said, after emit the signal ,the eventloop should quit.but it's NOT. and showEvent() call twice. and this is my question ,why showEvent() will be called twice? But at the first time app start, showEvent() run fine and not call twice!!!

        the Timer is for safe if we not emit the signal. after leave showEvent() , the timer will destruct and Will NOT CALL showEvent().

        JonBJ 1 Reply Last reply
        0
        • Q QtTester

          @JonB thanks for reply.
          as i said, after emit the signal ,the eventloop should quit.but it's NOT. and showEvent() call twice. and this is my question ,why showEvent() will be called twice? But at the first time app start, showEvent() run fine and not call twice!!!

          the Timer is for safe if we not emit the signal. after leave showEvent() , the timer will destruct and Will NOT CALL showEvent().

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by
          #4

          @QtTester said in QEventLoop in showEvent() will trigger showEvent() twice!:

          as i said, after emit the signal ,the eventloop should quit.but it's NOT

          It does quit, as shown by your final 2 occurrences of 4show End output. Maybe not at the time you expect, but it does.

          Rather than spend any more time on this, as I wrote earlier I suggest you get rid of QEventLoop::exec() and timers when you are inside an event. It's almost certainly not a good idea.

          why showEvent() will be called twice?

          Because you minimize and maximize the window, or something like that? You can also examine QShowEvent *e to see whether they are spontaneous or not, might be significant.

          1 Reply Last reply
          1
          • JonBJ JonB

            @QtTester
            I don't understand your question or what your issue is. You set off a singleshot timer first time showEvent() is invoked and there you run a QEventLoop. If during the 3 seconds waiting for the singleshot to fire a new showEvent() is raised you receive another showEvent() then you will set off a new timer. The output shows what I would expect in such a situation.

            Calling QEventLoop::exec() inside a slot or event or waiting for a timeout like you do is not a good idea. I don't know what you are trying to achieve but there is doubtless a better way to accomplish it.

            Q Offline
            Q Offline
            QtTester
            wrote on last edited by QtTester
            #5

            no , every time you restore the window the showEvent() will call twice(), I cannot explain why. if set SHOWED=0 showEvent() will call just one time! strange!

            Christian EhrlicherC 1 Reply Last reply
            0
            • Q QtTester

              no , every time you restore the window the showEvent() will call twice(), I cannot explain why. if set SHOWED=0 showEvent() will call just one time! strange!

              Christian EhrlicherC Offline
              Christian EhrlicherC Offline
              Christian Ehrlicher
              Lifetime Qt Champion
              wrote on last edited by
              #6

              You must not spin an event loop inside an event.

              Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
              Visit the Qt Academy at https://academy.qt.io/catalog

              JonBJ Q 2 Replies Last reply
              3
              • Christian EhrlicherC Christian Ehrlicher

                You must not spin an event loop inside an event.

                JonBJ Offline
                JonBJ Offline
                JonB
                wrote on last edited by JonB
                #7

                @Christian-Ehrlicher
                Thank you for chiming in to resolve! I was trying to tell the OP it was "a bad idea" to do it from an event and not to bother analyzing it further, but this makes it even simpler if you are not even allowed to do it :)

                1 Reply Last reply
                0
                • Q QtTester has marked this topic as solved on
                • Christian EhrlicherC Christian Ehrlicher

                  You must not spin an event loop inside an event.

                  Q Offline
                  Q Offline
                  QtTester
                  wrote on last edited by
                  #8

                  @Christian-Ehrlicher
                  it's because i have to call a function in showEvent() , and the function also will be call in a thread. that's why i need a eventloop to wait a signal.
                  Now i change it like this: check the thread owner first, if it's in the ui thread, it will not use eventloop.

                  Pl45m4P JonBJ 2 Replies Last reply
                  0
                  • Q QtTester

                    @Christian-Ehrlicher
                    it's because i have to call a function in showEvent() , and the function also will be call in a thread. that's why i need a eventloop to wait a signal.
                    Now i change it like this: check the thread owner first, if it's in the ui thread, it will not use eventloop.

                    Pl45m4P Offline
                    Pl45m4P Offline
                    Pl45m4
                    wrote on last edited by
                    #9

                    @QtTester said in QEventLoop in showEvent() will trigger showEvent() twice!:

                    Now i change it like this: check the thread owner first, if it's in the ui thread, it will not use eventloop.

                    Still sounds like bad design, which can be done better


                    If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                    ~E. W. Dijkstra

                    1 Reply Last reply
                    0
                    • Q QtTester

                      @Christian-Ehrlicher
                      it's because i have to call a function in showEvent() , and the function also will be call in a thread. that's why i need a eventloop to wait a signal.
                      Now i change it like this: check the thread owner first, if it's in the ui thread, it will not use eventloop.

                      JonBJ Offline
                      JonBJ Offline
                      JonB
                      wrote on last edited by JonB
                      #10

                      @QtTester said in QEventLoop in showEvent() will trigger showEvent() twice!:

                      that's why i need a eventloop to wait a signal.

                      But why do you need to wait, especially from within an event handler, that is the question? Suppose the wait takes 5 minutes? Suppose the thread fails to emit the signal, for whatever reason?

                      You would be expected to set off the thread function, exit the event, and then do whatever elsewhere as & when the thread function ends or send its signal. That is what event-driven programming paradigm is about.

                      1 Reply Last reply
                      0

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved