Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QSpinBox.setValue doesn't redraw window properly



  • I am using pyqt 5.12.3 from anaconda on osx Catalina
    This problem seems to be specific to mac as I do not see it on Linux (do not have a windows system to test)

    Updating a QSpinBox by calling setValue does not seem to properly delete previous content which is only partially drawn over. Switching to another desktop and back does seem to force a redraw, also clicking with the mouse inside the box.

    Example (set value of 8 over previous 0)

    Screenshot 2019-11-02 14.18.03.png

    Any ideas if this is a known problem or if I'm doing something wrong in the code?

    Thanks

    This is a minimal python file:

    import sys
    from PyQt5 import QtWidgets, QtCore
    
    class MainWindow(QtWidgets.QMainWindow):
        def __init__(self, ):
            super().__init__()
    
            self.spin = QtWidgets.QSpinBox(self)
            self.spin.move(50,50)
    
            self.button = QtWidgets.QPushButton('button', self)
            self.button.move(50, 100)
            self.button.clicked.connect(self.on_click)
    
        def on_click(self):
            v = self.spin.value()
            
            if v == 0:
                self.spin.setValue(8)
            else:
                self.spin.setValue(0)
    
    if __name__ == "__main__":
    	app = QtWidgets.QApplication(sys.argv)
    	window = MainWindow()
    	window.show()
    	sys.exit(app.exec_())
    

  • Banned

    Okay I tweaked your code a bit removing a few issues it had and moving it to a much simpler example -- now however I am running on Win10 but I have heard there are sometimes issues when using this on Mac specifically I think the Catalina OS so your issue may still exit but if nothing else the below code is much more streamlined and much more current --- if you have absolutely any questions on why I made any changes that I did do ask -- because every change was something to either fix a syntax error or to bring the syntax up to date and in line with how pyqt5 is meant to be used.

    from PyQt5.QtCore    import *
    from PyQt5.QtGui     import *
    from PyQt5.QtWidgets import *
      
    class MainWindow(QWidget):
        def __init__(self):
            QWidget.__init__(self)
    
            self.spin = QSpinBox(self)
    
            self.btnPush = QPushButton('Push', self)
            self.btnPush.clicked.connect(self.on_click)
            
            VBox = QVBoxLayout()
            VBox.addWidget(self.btnPush)
            VBox.addWidget(self.spin)
            
            self.setLayout(VBox)
    
        def on_click(self):
            v = self.spin.value()
            
            if v == 0:
                self.spin.setValue(8)
            else:
                self.spin.setValue(0)
    
    if __name__ == "__main__":
        app = QApplication([])
        
        window = MainWindow()
        window.show()
    
        app.exec()
    
      # If anyone wants more extensive free help I run an online lab-like classroom-like 
      # message server feel free and drop by you will not be able to post until I clear 
      # you as a student as this prevents spammers so if interested here is the invite
      # https://discord.gg/3D8huKC
    


  • For anyone who comes across this... I could not reproduce the issue with PyQt 5.12.6 and OSX 10.15.5, but if I add a second button to go after the the spinbox in the layout, then I can reproduce:

    import sys
    from PyQt5 import QtWidgets, QtCore
    
    print(QtCore.QT_VERSION_STR)
    
    
    class MainWindow(QtWidgets.QWidget):
        def __init__(self, ):
            super().__init__()
    
            self.spin = QtWidgets.QSpinBox(self)
    
            self.button = QtWidgets.QPushButton('button', self)
            self.button.clicked.connect(self.on_click)
    
            self.button2 = QtWidgets.QPushButton('do nothing', self)
    
            VBox = QtWidgets.QVBoxLayout()
            VBox.addWidget(self.button)
            VBox.addWidget(self.spin)
            VBox.addWidget(self.button2)
            self.setLayout(VBox)
    
        def on_click(self):
            v = self.spin.value()
            if v == 0:
                self.spin.setValue(8)
            else:
                self.spin.setValue(0)
    
    if __name__ == "__main__":
    	app = QtWidgets.QApplication(sys.argv)
    	window = MainWindow()
    	window.show()
    	sys.exit(app.exec_())
    
    

    Then I was able to "fix" / "workaround" the issue by adding type=QtCore.Qt.QueuedConnection in the connect call, i.e. this:

            self.button.clicked.connect(self.on_click, type=QtCore.Qt.QueuedConnection)
    



Log in to reply