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. QPushButton reacts to press when disabled.
Forum Updated to NodeBB v4.3 + New Features

QPushButton reacts to press when disabled.

Scheduled Pinned Locked Moved Solved Qt for Python
7 Posts 3 Posters 4.8k Views 1 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.
  • M Offline
    M Offline
    martinmaeland
    wrote on last edited by
    #1

    Hi,

    Problem
    I have a simple gui with a push button. When the button is pressed a function is called. I have noticed that the button can be pressed multiple times and that the callback function is ran multiple times. As if the callbacks are queued up.

    To sort this I have tried to use setEnable(False), which do disable the button (it is greyed out). However, the button still register presses, and when the callback function is completed, it starts again. Pressing the button enough times causes the application to crash.

    What i want
    I want to do something like this.

    self.btn = QPushButton('Refresh', self)
    self.btn.clicked.connect(self.refresh)
    
    def refresh(self):
        self.btn.setEnabled(False)
        # do something that takes a couple of seconds
        self.btn.setEnabled(True)
    

    I have tried

    • Using a QTimer to handle the setEnable() method, and then call the function if the button is pressed and disabled.
    • Using a QThread to basically do the same as above.
    • Using a dummy-button. Identical to the original button, but without any callback-functions.
    • Showing/hiding the button.
    JonBJ 1 Reply Last reply
    0
    • mranger90M Offline
      mranger90M Offline
      mranger90
      wrote on last edited by
      #5

      This simple test works with pyside6

      import sys
      from PySide6.QtWidgets import QApplication, QWidget, QPushButton
      from PySide6.QtCore import QTimer
      
      
      class Widget(QWidget):
          def __init__(self):
              QWidget.__init__(self)
              self.btn = QPushButton('Refresh', self)
              self.btn.clicked.connect(self.refresh)
              self.btnTimer = QTimer(self)
              self.btnTimer.setInterval(2000)
              self.btnTimer.setSingleShot(True)
              self.btnTimer.timeout.connect(self.timerTimeout)
      
          def refresh(self):
              self.btn.setEnabled(False)
              self.btnTimer.start()
              print('Button was pressed, starting timer')
      
          def timerTimeout(self):
              self.btn.setEnabled(True)
              print('In Timer TimeOut')
      
      
      
      if __name__ == "__main__":
          app = QApplication([])
          window = Widget()
          window.show()
          sys.exit(app.exec())
      
      
      M 1 Reply Last reply
      0
      • M martinmaeland

        Hi,

        Problem
        I have a simple gui with a push button. When the button is pressed a function is called. I have noticed that the button can be pressed multiple times and that the callback function is ran multiple times. As if the callbacks are queued up.

        To sort this I have tried to use setEnable(False), which do disable the button (it is greyed out). However, the button still register presses, and when the callback function is completed, it starts again. Pressing the button enough times causes the application to crash.

        What i want
        I want to do something like this.

        self.btn = QPushButton('Refresh', self)
        self.btn.clicked.connect(self.refresh)
        
        def refresh(self):
            self.btn.setEnabled(False)
            # do something that takes a couple of seconds
            self.btn.setEnabled(True)
        

        I have tried

        • Using a QTimer to handle the setEnable() method, and then call the function if the button is pressed and disabled.
        • Using a QThread to basically do the same as above.
        • Using a dummy-button. Identical to the original button, but without any callback-functions.
        • Showing/hiding the button.
        JonBJ Online
        JonBJ Online
        JonB
        wrote on last edited by
        #2

        @martinmaeland
        Hello and welcome.

        You should not be having so much trouble. For example, the code you showed should work (AFAIK), it should not generate new clicked signal while disabled. Do you do anything which could affect this in your # do something that takes a couple of seconds?

        1 Reply Last reply
        1
        • M Offline
          M Offline
          martinmaeland
          wrote on last edited by martinmaeland
          #3

          Hello @JonB,

          Thank you for the response.

          I have the same issue if i do it like this:

          def refresh(self):
              self.btn.setEnabled(False)
              sleep(2)
              self.btn.setEnabled(True)
          
          JonBJ 1 Reply Last reply
          0
          • M martinmaeland

            Hello @JonB,

            Thank you for the response.

            I have the same issue if i do it like this:

            def refresh(self):
                self.btn.setEnabled(False)
                sleep(2)
                self.btn.setEnabled(True)
            
            JonBJ Online
            JonBJ Online
            JonB
            wrote on last edited by
            #4

            @martinmaeland
            When you use this code, do you visually see the button disabled before the 2 second sleep?

            M 1 Reply Last reply
            0
            • mranger90M Offline
              mranger90M Offline
              mranger90
              wrote on last edited by
              #5

              This simple test works with pyside6

              import sys
              from PySide6.QtWidgets import QApplication, QWidget, QPushButton
              from PySide6.QtCore import QTimer
              
              
              class Widget(QWidget):
                  def __init__(self):
                      QWidget.__init__(self)
                      self.btn = QPushButton('Refresh', self)
                      self.btn.clicked.connect(self.refresh)
                      self.btnTimer = QTimer(self)
                      self.btnTimer.setInterval(2000)
                      self.btnTimer.setSingleShot(True)
                      self.btnTimer.timeout.connect(self.timerTimeout)
              
                  def refresh(self):
                      self.btn.setEnabled(False)
                      self.btnTimer.start()
                      print('Button was pressed, starting timer')
              
                  def timerTimeout(self):
                      self.btn.setEnabled(True)
                      print('In Timer TimeOut')
              
              
              
              if __name__ == "__main__":
                  app = QApplication([])
                  window = Widget()
                  window.show()
                  sys.exit(app.exec())
              
              
              M 1 Reply Last reply
              0
              • JonBJ JonB

                @martinmaeland
                When you use this code, do you visually see the button disabled before the 2 second sleep?

                M Offline
                M Offline
                martinmaeland
                wrote on last edited by
                #6

                @JonB

                Yes, the button does visually disable for 2 seconds.

                1 Reply Last reply
                0
                • mranger90M mranger90

                  This simple test works with pyside6

                  import sys
                  from PySide6.QtWidgets import QApplication, QWidget, QPushButton
                  from PySide6.QtCore import QTimer
                  
                  
                  class Widget(QWidget):
                      def __init__(self):
                          QWidget.__init__(self)
                          self.btn = QPushButton('Refresh', self)
                          self.btn.clicked.connect(self.refresh)
                          self.btnTimer = QTimer(self)
                          self.btnTimer.setInterval(2000)
                          self.btnTimer.setSingleShot(True)
                          self.btnTimer.timeout.connect(self.timerTimeout)
                  
                      def refresh(self):
                          self.btn.setEnabled(False)
                          self.btnTimer.start()
                          print('Button was pressed, starting timer')
                  
                      def timerTimeout(self):
                          self.btn.setEnabled(True)
                          print('In Timer TimeOut')
                  
                  
                  
                  if __name__ == "__main__":
                      app = QApplication([])
                      window = Widget()
                      window.show()
                      sys.exit(app.exec())
                  
                  
                  M Offline
                  M Offline
                  martinmaeland
                  wrote on last edited by
                  #7

                  @mranger90

                  I actually tried this myself after I posted this, and it worked! As long as the timer interval is long enough. Found that 100 ms is enough for it to be pretty responsive and not queue up the callbacks.

                  Thank you :)

                  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