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. Please destroy the QApplication singleton before creating a new QApplication instance.
Forum Updated to NodeBB v4.3 + New Features

Please destroy the QApplication singleton before creating a new QApplication instance.

Scheduled Pinned Locked Moved Solved Qt for Python
6 Posts 2 Posters 5.7k Views 2 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.
  • T Offline
    T Offline
    tstex
    wrote on last edited by
    #1

    In an embedded python interpreter running in a C++ app, Pyside widgets can only be opened once. In our app, Python39.dll is delay loaded at runtime, and we spawn each python tool in a new thread. Somehow the QApplication instance survives this thread's termination, and we see this error when we attempt to open the widget again:

    [Python error] (<class 'RuntimeError'>) RuntimeError('Please destroy the QApplication singleton before creating a new QApplication instance.')
    

    This does not work:

    if not QApplication.instance():
        app = QApplication(sys.argv)
    else:
        app = QApplication.instance()
    

    I have tried all manner of brute force deletion of QApplication without luck. Ideally there would be an API call to destroy this singleton in cases like this when it is needed. Is there one already?

    PyQt works fine.

    Thanks!

    Re: How to destroy a singleton and then create a new one.

    1 Reply Last reply
    1
    • JonBJ JonB referenced this topic on
    • jeremy_kJ jeremy_k referenced this topic on
    • T Offline
      T Offline
      tstex
      wrote on last edited by
      #6

      So I found a bugreport describing an undocumented call that did the trick:

      QApplication.shutdown()
      

      Described here: https://bugreports.qt.io/browse/PYSIDE-1190

      By calling that after the exec() returns, we are able to re-open the Dialogs again when the code is executed.

      1 Reply Last reply
      6
      • jeremy_kJ Offline
        jeremy_kJ Offline
        jeremy_k
        wrote on last edited by
        #2

        Have you tried invoking the garbage collector via gc.collect()?

        Asking a question about code? http://eel.is/iso-c++/testcase/

        T 1 Reply Last reply
        0
        • jeremy_kJ jeremy_k

          Have you tried invoking the garbage collector via gc.collect()?

          T Offline
          T Offline
          tstex
          wrote on last edited by
          #3

          @jeremy_k - Yep. Tried gc.collect() and this back on the C++ side: PyGC_Collect();

          The QApplication instance is remarkably persistent. I guess there are ways of setting up a Singleton that make it impossible for people to work around it? In this case, that defense system makes the entire PySide module unusable. At this point, we're about to go PyQt.

          As an aside, running this PySide code slowly makes Visual Studio 2019 unresponsive, and after about 3 debug sessions, a restart is required. Not 100% sure if it's related to PySide, but there's really not a lot else going on in this code.

          1 Reply Last reply
          0
          • jeremy_kJ Offline
            jeremy_kJ Offline
            jeremy_k
            wrote on last edited by
            #4

            It sounds like you're well beyond the depth of my PySide experience. I've stopped at "works the same as PyQt".

            Are the destroyed and aboutToQuit signals emitted?

            Asking a question about code? http://eel.is/iso-c++/testcase/

            jeremy_kJ 1 Reply Last reply
            0
            • jeremy_kJ jeremy_k

              It sounds like you're well beyond the depth of my PySide experience. I've stopped at "works the same as PyQt".

              Are the destroyed and aboutToQuit signals emitted?

              jeremy_kJ Offline
              jeremy_kJ Offline
              jeremy_k
              wrote on last edited by jeremy_k
              #5

              @jeremy_k said in Please destroy the QApplication singleton before creating a new QApplication instance.:

              It sounds like you're well beyond the depth of my PySide experience. I've stopped at "works the same as PyQt".

              Are the destroyed and aboutToQuit signals emitted?

              A test program:

              import sys
              if sys.argv[1:] == ["PyQt"]:
                  from PyQt5.QtCore import QCoreApplication
              else:
                  from PySide6.QtCore import QCoreApplication
              
              def runme():
                  print("creating QApplication")
                  app = QCoreApplication([])
                  app.destroyed.connect(lambda: print("destroyed"))
                  del app
              
              runme()
              runme()
              

              This works with PyQt 5:

              creating QApplication
              destroyed
              creating QApplication
              destroyed
              

              but fails with PySide6:

              creating QApplication
              creating QApplication
              Traceback (most recent call last):
                File "/tmp/test.py", line 15, in <module>
                  runme()
                File "/tmp/test.py", line 10, in runme
                  app = QCoreApplication([])
              RuntimeError: Please destroy the QCoreApplication singleton before creating a new QCoreApplication instance.
              

              So apparently yes, PySide6 is standing in the way of destroying the QCoreApplication.

              This appears to may be a known issue.

              https://bugreports.qt.io/browse/PYSIDE-1470
              https://bugreports.qt.io/browse/PYSIDE-1647

              Asking a question about code? http://eel.is/iso-c++/testcase/

              1 Reply Last reply
              0
              • T Offline
                T Offline
                tstex
                wrote on last edited by
                #6

                So I found a bugreport describing an undocumented call that did the trick:

                QApplication.shutdown()
                

                Described here: https://bugreports.qt.io/browse/PYSIDE-1190

                By calling that after the exec() returns, we are able to re-open the Dialogs again when the code is executed.

                1 Reply Last reply
                6
                • T tstex 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