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. Emitted signals only processed once per event loop...

Emitted signals only processed once per event loop...

Scheduled Pinned Locked Moved Unsolved General and Desktop
7 Posts 5 Posters 1.3k Views 3 Watching
  • 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.
  • E Offline
    E Offline
    esmolikowski
    wrote on last edited by
    #1

    Hi all,

    Is there an easy way to configure a signal/slot to only be called once per event loop, even though its been emitted multiple times from different places in the code. Say I have a function that changes state, but calls other function that changes sub-states all those state changes emitting signals to refresh UI, auto-savings, or other. I'd like the slot to be called only once for the whole event loop.

    I know I can deal with that manually with tracking the calls and state, and use a timer to reset state. However, I was wondering if there was a mechanism in Qt to say 'this signal should only be called once per event loop' so its handled internally instead of manually by the application developer.

    Thanks.

    1 Reply Last reply
    0
    • E Offline
      E Offline
      esmolikowski
      wrote on last edited by esmolikowski
      #2

      I took a look, and while there are different types of connections, there isn't a type that matches what I need, which is unfortunate. There is the following flag: SingleShotConnection, but it will be a SingleShot over the whole application (signal is automatically disconnected once emitted). I wish there was something like SingleShotConnectionPerEventLoop or something like this.

      1 Reply Last reply
      0
      • Christian EhrlicherC Offline
        Christian EhrlicherC Offline
        Christian Ehrlicher
        Lifetime Qt Champion
        wrote on last edited by
        #3

        How should this work? What is one event loop call? Someone might call process events somewhere - should count this too? Use a timer.

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

        1 Reply Last reply
        3
        • S Offline
          S Offline
          SimonSchroeder
          wrote on last edited by
          #4

          Qt has nothing like this built in. Usually, there is a solution with two timers: The first is always reset when the slot should be called. During this short interval, more slot calls can be collected. However, this might delay indefinitely. Hence, there should be a second timer which is not reset while it is running and after a longer period (longer than the first timer) still calls the slot.

          In the specific case of refreshing the UI: Just call update(). This one has what you want built in. It will not always just fire away. If you want to force an immediate redraw there is repaint().

          1 Reply Last reply
          2
          • E Offline
            E Offline
            esmolikowski
            wrote on last edited by esmolikowski
            #5

            Thank you @SimonSchroeder. But I am not sure update() does what I need, not in terms of calling it just once, but in terms of updating the UI properly when values change. The way I do things right now is:

            • File loaded -> send signals -> change all values in UI (ie: update())
            • A selection has changed in some comboBox -> send signals -> change necessary values in UI (ie: update())
            • But what I am running into is the following:
            • File loaded -> send signals etc... When values change, the comboBox selection also changed -> send signal -> change necessary values in UI. Now the File loaded will change the same UI that the comboBox selection has triggered. Results in the UI update being called twice.

            I hope that makes sense. I am not sure update() on a widget does that. I think update() is just to trigger a repaint of some widget because its content has changed.

            M 1 Reply Last reply
            0
            • jeremy_kJ Offline
              jeremy_kJ Offline
              jeremy_k
              wrote on last edited by
              #6

              Use a single-shot 0 timer. Operations can request a service by starting the timer. The request can be repeated as many times as desired, but the timer will only fire once when the event loop next has a chance to service the timer event.

              QCoreApplication app(argc, argv);
              QTimer zeroTimer;
              zeroTimer.setInterval(0);
              zeroTimer.setSingleShot(true);
              zeroTimer.callOnTimeout( []{ qDebug() << "timeout"; } );
              zeroTimer.start();
              zeroTimer.start();
              app.exec();
              

              Asking a question about code? http://eel.is/iso-c++/testcase/

              1 Reply Last reply
              0
              • E esmolikowski

                Thank you @SimonSchroeder. But I am not sure update() does what I need, not in terms of calling it just once, but in terms of updating the UI properly when values change. The way I do things right now is:

                • File loaded -> send signals -> change all values in UI (ie: update())
                • A selection has changed in some comboBox -> send signals -> change necessary values in UI (ie: update())
                • But what I am running into is the following:
                • File loaded -> send signals etc... When values change, the comboBox selection also changed -> send signal -> change necessary values in UI. Now the File loaded will change the same UI that the comboBox selection has triggered. Results in the UI update being called twice.

                I hope that makes sense. I am not sure update() on a widget does that. I think update() is just to trigger a repaint of some widget because its content has changed.

                M Offline
                M Offline
                mpergand
                wrote on last edited by
                #7

                @esmolikowski

                Have a look at QObject::blockSignals(bool block) and QSignalBlocker

                https://forum.qt.io/topic/129364/blocking-signals-to-child-widgets/7

                1 Reply Last reply
                1

                • Login

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