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. PySide6 gets stuck in QtWidget.setVisible()
Forum Updated to NodeBB v4.3 + New Features

PySide6 gets stuck in QtWidget.setVisible()

Scheduled Pinned Locked Moved Solved Qt for Python
4 Posts 2 Posters 460 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.
  • L Offline
    L Offline
    LingHan
    wrote on last edited by
    #1

    Hi there!

    I'm attempting to develop a python program in which I want to use the PySide6 Dialog to obtain user input. To ensure the main program does not terminate (pynput keyboard.Listener) after the dialog is closed, I placed my PySide6 Dialog function in a thread pool. It works well when I first time call the dialog in my code; however, when I try to call it again, the dialog window fails to show. Upon further inspection, I found that it gets stuck in the QtWidget.setVisible() method. Does anyone know why or can help me solve this problem? Thanks!

    from PySide6.QtWidgets import QWidget, QApplication
    import sys
    from concurrent.futures import ThreadPoolExecutor
    from mini_dialog import Ui_Dialog # Just an empty Dialog
    
    
    class MyQWidget(QWidget):
        def __init__(self):
            super().__init__()
    
        def setVisible(self, visible):
            print("setVisible...[stuck here]")
            return super().setVisible(visible)
    
    
    class MyWidget(MyQWidget, Ui_Dialog):
        def __init__(self, app):
            super().__init__()
            self.setupUi(self)
            self.app = app
            self.message = {}
    
        def show(self):
            print("show...")
            # return super().show()
            self.setVisible(True)
    
    
    def run_my_weight():
        app = QApplication.instance()
        if app is None:
            app = QApplication(sys.argv)
        widget = MyWidget(app)
        widget.show()
        print("first time is ok")
        app.exec()
        return widget.message
    
    
    def main():
        with ThreadPoolExecutor(max_workers=1) as executor:
            future = executor.submit(run_my_weight)
            result = future.result()
            print(result)
    
    
    if __name__ == '__main__':
        main()
        main()
    

    Output: No error or more information.

    show...
    setVisible...[stuck here]
    first time is ok
    setVisible...[stuck here]
    {}
    show...
    setVisible...[stuck here]
    
    JonBJ 1 Reply Last reply
    0
    • L LingHan

      @JonB

      Oh, thank you!

      Actually, this is my first Qt application. I initially thought I could treat the Qt Dialog as a lightweight component within my program. Whenever my back-end code needed to get input, I could just call it, close it, and repeat. But that is wrong.

      I should redesign my program and use front-end code to call my back end algorithms, rather than the other way around.

      Appreciate it!

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by
      #4

      @LingHan said in PySide6 gets stuck in QtWidget.setVisible():

      I should redesign my program and use front-end code to call my back end algorithms, rather than the other way around.

      Yes. You should create a single QApplication instance and call QApplication.exec() as the last step from main(). It does not return until the user quits. All your UI code must be in the main thread, the one where the QApplication is created. You can do background/computation code in secondary threads, either long running one(s) or short-lived. The Qt thread code runs an event loop in each thread, so you can send it signals (e.g. to start something off) and it can send signals back to your main (e.g. when it has finished something or wants the UI to show something on its behalf).

      1 Reply Last reply
      1
      • L LingHan

        Hi there!

        I'm attempting to develop a python program in which I want to use the PySide6 Dialog to obtain user input. To ensure the main program does not terminate (pynput keyboard.Listener) after the dialog is closed, I placed my PySide6 Dialog function in a thread pool. It works well when I first time call the dialog in my code; however, when I try to call it again, the dialog window fails to show. Upon further inspection, I found that it gets stuck in the QtWidget.setVisible() method. Does anyone know why or can help me solve this problem? Thanks!

        from PySide6.QtWidgets import QWidget, QApplication
        import sys
        from concurrent.futures import ThreadPoolExecutor
        from mini_dialog import Ui_Dialog # Just an empty Dialog
        
        
        class MyQWidget(QWidget):
            def __init__(self):
                super().__init__()
        
            def setVisible(self, visible):
                print("setVisible...[stuck here]")
                return super().setVisible(visible)
        
        
        class MyWidget(MyQWidget, Ui_Dialog):
            def __init__(self, app):
                super().__init__()
                self.setupUi(self)
                self.app = app
                self.message = {}
        
            def show(self):
                print("show...")
                # return super().show()
                self.setVisible(True)
        
        
        def run_my_weight():
            app = QApplication.instance()
            if app is None:
                app = QApplication(sys.argv)
            widget = MyWidget(app)
            widget.show()
            print("first time is ok")
            app.exec()
            return widget.message
        
        
        def main():
            with ThreadPoolExecutor(max_workers=1) as executor:
                future = executor.submit(run_my_weight)
                result = future.result()
                print(result)
        
        
        if __name__ == '__main__':
            main()
            main()
        

        Output: No error or more information.

        show...
        setVisible...[stuck here]
        first time is ok
        setVisible...[stuck here]
        {}
        show...
        setVisible...[stuck here]
        
        JonBJ Offline
        JonBJ Offline
        JonB
        wrote on last edited by JonB
        #2

        @LingHan said in PySide6 gets stuck in QtWidget.setVisible():

        I placed my PySide6 Dialog function in a thread pool.

        This is not allowed. Qt requires all UI stuff to be done in the main thread only. Period. You are seeing the consequences of not.

        Do back end stuff in a thread, if you need to. Communicate with UI only through signals & slots.

        from concurrent.futures import ThreadPoolExecutor

        Consider using Qt's threading instead of Python's for a Qt application. Not mandatory, I think, but might have advantages.

        You seem to be creating a QApplication and executing QApplication.exec() each time in some thread? That is not the way to do things. You should not be doing any such even if sequential/serial, but certainly not in parallel.

        L 1 Reply Last reply
        1
        • JonBJ JonB

          @LingHan said in PySide6 gets stuck in QtWidget.setVisible():

          I placed my PySide6 Dialog function in a thread pool.

          This is not allowed. Qt requires all UI stuff to be done in the main thread only. Period. You are seeing the consequences of not.

          Do back end stuff in a thread, if you need to. Communicate with UI only through signals & slots.

          from concurrent.futures import ThreadPoolExecutor

          Consider using Qt's threading instead of Python's for a Qt application. Not mandatory, I think, but might have advantages.

          You seem to be creating a QApplication and executing QApplication.exec() each time in some thread? That is not the way to do things. You should not be doing any such even if sequential/serial, but certainly not in parallel.

          L Offline
          L Offline
          LingHan
          wrote on last edited by
          #3

          @JonB

          Oh, thank you!

          Actually, this is my first Qt application. I initially thought I could treat the Qt Dialog as a lightweight component within my program. Whenever my back-end code needed to get input, I could just call it, close it, and repeat. But that is wrong.

          I should redesign my program and use front-end code to call my back end algorithms, rather than the other way around.

          Appreciate it!

          JonBJ 1 Reply Last reply
          0
          • L LingHan has marked this topic as solved on
          • L LingHan

            @JonB

            Oh, thank you!

            Actually, this is my first Qt application. I initially thought I could treat the Qt Dialog as a lightweight component within my program. Whenever my back-end code needed to get input, I could just call it, close it, and repeat. But that is wrong.

            I should redesign my program and use front-end code to call my back end algorithms, rather than the other way around.

            Appreciate it!

            JonBJ Offline
            JonBJ Offline
            JonB
            wrote on last edited by
            #4

            @LingHan said in PySide6 gets stuck in QtWidget.setVisible():

            I should redesign my program and use front-end code to call my back end algorithms, rather than the other way around.

            Yes. You should create a single QApplication instance and call QApplication.exec() as the last step from main(). It does not return until the user quits. All your UI code must be in the main thread, the one where the QApplication is created. You can do background/computation code in secondary threads, either long running one(s) or short-lived. The Qt thread code runs an event loop in each thread, so you can send it signals (e.g. to start something off) and it can send signals back to your main (e.g. when it has finished something or wants the UI to show something on its behalf).

            1 Reply Last reply
            1
            • L LingHan has marked this topic as solved on

            • Login

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