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...
Forum Updated to NodeBB v4.3 + New Features

Emitted signals only processed once per event loop...

Scheduled Pinned Locked Moved Unsolved General and Desktop
7 Posts 5 Posters 619 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 Online
        Christian EhrlicherC Online
        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