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

setVisible() doesn't occur immediately



  • I have a dialog box which processes a lengthy calculation when the user clicks Ok. I've placed a hidden label above the Ok button to inform the user that they need to wait, and I'd like to make that label visible when the user clicks Ok. However, setVisible() doesn't seem to take effect until after the lengthy calculation (immediately before the dialog box closes). Any idea why this is or how to fix it? Minimal working example below.

    import sys
    import time
    from PySide2.QtWidgets import *
    
    class CustomDialog(QDialog):
        def __init__(self, parent=None):
            super().__init__(parent=parent)
    
            self.layout = QVBoxLayout()
            self.message = QLabel("Perform lengthy calculation.")
            self.layout.addWidget(self.message)
    
            self.warning = QLabel("Please wait.")
            self.layout.addWidget(self.warning)
            self.warning.setVisible(False)
    
            QBtn = QDialogButtonBox.Ok | QDialogButtonBox.Cancel
            self.buttonBox = QDialogButtonBox(QBtn)
            self.buttonBox.accepted.connect(self.accept) # Comment out this line to see that the warning label does appear, but not until after the lengthy calculation
            self.buttonBox.rejected.connect(self.reject)
    
            self.layout.addWidget(self.buttonBox)
            self.setLayout(self.layout)
    
            self.buttonBox.button(QDialogButtonBox.Ok).clicked.connect(self.onButtonBoxOkClicked)
    
        def onButtonBoxOkClicked(self):
            self.warning.setVisible(True) # We set the warning label to visible before the lengthy calculation
            time.sleep(5)
    
    
    class MainWindow(QMainWindow):
        def __init__(self):
            super().__init__()
            button = QPushButton("Press me for the dialog.")
            button.clicked.connect(self.button_clicked)
            self.setCentralWidget(button)
    
        def button_clicked(self, s):
            dlg = CustomDialog()
            dlg.exec_()
    
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    app.exec_()
    

  • Lifetime Qt Champion

    Hi,

    setVisible will schedule an update to happen when the event loop can do it. Even loop that you block with your lengthy calculation. You might want to consider using QtConcurrent::run to avoid blocking your GUI.


  • Lifetime Qt Champion

    Hi,

    setVisible will schedule an update to happen when the event loop can do it. Even loop that you block with your lengthy calculation. You might want to consider using QtConcurrent::run to avoid blocking your GUI.


Log in to reply