Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. Getting unexpected results with QTimer.
QtWS25 Last Chance

Getting unexpected results with QTimer.

Scheduled Pinned Locked Moved Unsolved Qt for Python
9 Posts 3 Posters 659 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.
  • P Offline
    P Offline
    Paul_F
    wrote on 29 Apr 2021, 17:26 last edited by Paul_F
    #1

    I am hoping someone can help me with this. The code below controls an On screen display volume widget. A QTimer is started to wait 3 seconds before hiding the widget when a button is released. If a volume button is pressed again within those 3 seconds, the timer must be killed.

    If I press a button repeatedly instead of held down, something weird happens. it's as if none of the timers have been killed; If I press a button, say 5 times fast, the widget hides 3 seconds after the first button press, and repeats the print message 4 times too. In other words, 5 different timers are running. It also has consequences for the widget, it starts flickering after three seconds. When the button is held down, the loop performs flawlessly and does not initiate a timer until the button is released - Even though the autorepeats simulates a button press plus a button release. I am a bit stumped, who can help me here?

    Thank you.

    The code in question:

    class Carma(QtWidgets.QWidget):
    
        def __init__(self,init):
            super().__init__()
    
            if self.init == True:
                self.volstep = 1  # Volume step
                self.osd_delaytime = 3  # seconds
                self.mainvolume = 50  # startup volume
                self.volrate = 20  # volume change speed when using +-
                self.choice = -1
                self.vol_delay_ms = 500
                self.vol_interval_ms = 100
                self.timer = QtCore.QTimer()
                self.init_ui()
    
    
    
        def setVolume(self):
            vol_int_ms = int((1/self.volrate)*1000)
            self.buttons_src[6].setStyleSheet("border-image: url(images/bezel-button.png)")
            self.buttons_src[6].setAutoRepeat(True)
            self.buttons_src[6].setAutoRepeatDelay(self.vol_delay_ms)
            self.buttons_src[6].setAutoRepeatInterval(vol_int_ms)
            self.buttons_src[6].pressed.connect(lambda: self.voldn())
            self.buttons_src[6].clicked.connect(lambda: self.volhidetimer(2))
            self.buttons_src[7].setStyleSheet("border-image: url(images/bezel-button.png)")
            self.buttons_src[7].setAutoRepeat(True)
            self.buttons_src[7].setAutoRepeatDelay(self.vol_delay_ms)
            self.buttons_src[7].setAutoRepeatInterval(vol_int_ms)
            self.buttons_src[7].pressed.connect(lambda: self.volup())
            self.buttons_src[7].clicked.connect(lambda: self.volhidetimer(2))
            self.init = False
    
        def voldn(self):
            self.timer.stop()
            print("voldn pressed", self.mainvolume)
            self.buttons_src[6].setStyleSheet("border-image: url(images/bezel-buttonp.png)")
            if self.osd_vol_widget.isHidden():
                self.osd_vol_widget.show()
            if 1 <= self.mainvolume <= 100:
                self.mainvolume -= self.volstep
                self.osd_vol_bar.setValue(self.mainvolume)
                self.osd_vol_label.setText(str(self.mainvolume))
    
        def volup(self):
            self.timer.stop()
            print("volup pressed", self.mainvolume)
            self.buttons_src[7].setStyleSheet("border-image: url(images/bezel-buttonp.png)")
            if self.osd_vol_widget.isHidden():
                self.osd_vol_widget.show()
            if 0 <= self.mainvolume <= 99:
                self.mainvolume += self.volstep
                self.osd_vol_bar.setValue(self.mainvolume)
                self.osd_vol_label.setText(str(self.mainvolume))
    
        def volhidetimer(self, delaytime):
            if not any(self.buttons_src[i].isDown() for i in (6, 7)):
                self.buttons_src[6].setStyleSheet("border-image: url(images/bezel-button.png)")
                self.timer.singleShot(delaytime * 1000, lambda: self.volhide())
                print("Start timer volume hide")
    
        def volhide(self):
            if not any(self.buttons_src[i].isDown() for i in (6, 7)):
                self.osd_vol_widget.hide()
                print("Volume widget hidden")
    
    1 Reply Last reply
    0
    • S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 29 Apr 2021, 18:17 last edited by
      #2

      Hi,

      The singleShot method is a class function. You are creating a new independent single shot timer each time you call it.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      P 1 Reply Last reply 29 Apr 2021, 18:20
      2
      • S SGaist
        29 Apr 2021, 18:17

        Hi,

        The singleShot method is a class function. You are creating a new independent single shot timer each time you call it.

        P Offline
        P Offline
        Paul_F
        wrote on 29 Apr 2021, 18:20 last edited by
        #3

        @SGaist Understood. How can I prevent this?

        E 1 Reply Last reply 29 Apr 2021, 18:43
        0
        • S Offline
          S Offline
          SGaist
          Lifetime Qt Champion
          wrote on 29 Apr 2021, 18:22 last edited by
          #4

          Make set your timer as single shot and just restart it.

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          P 1 Reply Last reply 29 Apr 2021, 19:04
          2
          • P Paul_F
            29 Apr 2021, 18:20

            @SGaist Understood. How can I prevent this?

            E Offline
            E Offline
            eyllanesc
            wrote on 29 Apr 2021, 18:43 last edited by
            #5

            @Paul_F The implementation that @SGaist points to is something like:

            self.timer = QtCore.QTimer(singleShot=True)
            self.timer.timeout.connect(self.volhide)
            

            then change to:

            self.timer.setInterval(delaytime * 1000)
            self.timer.start()
            

            If you want me to help you develop some work then you can write to my email: e.yllanescucho@gmal.com.

            P 1 Reply Last reply 29 Apr 2021, 19:04
            3
            • E eyllanesc
              29 Apr 2021, 18:43

              @Paul_F The implementation that @SGaist points to is something like:

              self.timer = QtCore.QTimer(singleShot=True)
              self.timer.timeout.connect(self.volhide)
              

              then change to:

              self.timer.setInterval(delaytime * 1000)
              self.timer.start()
              
              P Offline
              P Offline
              Paul_F
              wrote on 29 Apr 2021, 19:04 last edited by
              #6

              @eyllanesc Thank you, but I just sorted it.

              instead of .singleshot I used setSingleShot and .timeout.connect and started it manually. Now it works, no more flickering.

              E 1 Reply Last reply 29 Apr 2021, 19:08
              0
              • S SGaist
                29 Apr 2021, 18:22

                Make set your timer as single shot and just restart it.

                P Offline
                P Offline
                Paul_F
                wrote on 29 Apr 2021, 19:04 last edited by
                #7

                @SGaist Thank you, it now works flawlessly!

                1 Reply Last reply
                0
                • P Paul_F
                  29 Apr 2021, 19:04

                  @eyllanesc Thank you, but I just sorted it.

                  instead of .singleshot I used setSingleShot and .timeout.connect and started it manually. Now it works, no more flickering.

                  E Offline
                  E Offline
                  eyllanesc
                  wrote on 29 Apr 2021, 19:08 last edited by eyllanesc
                  #8

                  @Paul_F That's what my code does:

                  self.timer = QtCore.QTimer(singleShot=True)
                  

                  is the same as:

                  self.timer = QtCore.QTimer()
                  self.timer.setSingleShot(True)
                  

                  And please don't abuse lambda functions.

                  If you want me to help you develop some work then you can write to my email: e.yllanescucho@gmal.com.

                  P 1 Reply Last reply 29 Apr 2021, 19:32
                  1
                  • E eyllanesc
                    29 Apr 2021, 19:08

                    @Paul_F That's what my code does:

                    self.timer = QtCore.QTimer(singleShot=True)
                    

                    is the same as:

                    self.timer = QtCore.QTimer()
                    self.timer.setSingleShot(True)
                    

                    And please don't abuse lambda functions.

                    P Offline
                    P Offline
                    Paul_F
                    wrote on 29 Apr 2021, 19:32 last edited by
                    #9

                    @eyllanesc I tend to get errors if I don't so I just put it in. I just started three months ago with python, with only 80's basic as a base. So cut me some slack ;)

                    1 Reply Last reply
                    0

                    2/9

                    29 Apr 2021, 18:17

                    7 unread
                    • Login

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