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

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



  • I want to create a qapplication to record a sound. Then I want to save the audio file, run some functions on that audio file and then I want to create a new qapplication which will display the results of that functions. Right now I can only get the first qapplication and the functions to run. The script fails before the second application with this error:

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

    def main(audio_file, a_file, final_order):
    
        app = qtw.QApplication(sys.argv)
        w1=record_audio.main()
        w1.show()
        app.exec_()
    
        r = sr.Recognizer()
        audio = SpeechConvert(audio_file, r)
        a = get_a.main(a_file)
        get_command.main(audio, r, a)
    
        app = qtw.QApplication(sys.argv)
        w2=display_qt.main(final_order)
        w2.show()
        sys.exit(app.exec_())
    
        #w1.closed.connect(w2.show)
        #sys.exit(app.exec_())
    
    if __name__ == "__main__":
        audio_file = filenames.audio_file2
        a_file = filenames.a_file
        final_order = filenames.final_order
        main(audio_file, a_file, final_order)
    


  • @a_fol
    Well, it seems to be telling you to go del app before you can go app = qtw.QApplication(sys.argv) a second time. The answer at https://stackoverflow.com/a/6778997/489865 seems to be you (it says PyQt4, let's hope it applies to PyQt5 too).

    Having said that, I do not know whether you ought also exit the exiting app "cleanly" from a Qt point of view. I don't know why one would want to destroy an existing QApplication and then recreate, but that's up to you.



  • Thanks for your reply! I tried adding del app afte the first app.exec_() but I still get the same error about destroying the QApplication singleton before creating a new instance.

    What I want is similar to this:
    https://stackoverflow.com/questions/59581668/how-to-destroy-a-qapplication-and-then-run-a-new-one-without-exiting-the-python

    But instead I can't have the two applications connected to each other as that prevents the functions between them to run in a sequence. So I can't think of another way other than destroying the first one and creating a new one after the functions in between are done.


  • Moderators

    @a_fol
    let me ask this, why do you want to destroy the QApplication to then immediately create a new one!?

    What's stopping you from doing everything inside one QApplication instance?



  • @a_fol said in How to destroy a singleton and then create a new one.:

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

    This error:

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

    If there is a way having both windows displayed in the sequence mentioned above, that is:

    1. w1
    2. Recognizer, SpeechConvert etc functions
    3. w2
      then I that would be great. It's just that looking at the error I thought destroying w1 and then creating w2 would solve everything.

  • Qt Champions 2019

    @a_fol There is really no need to recreate QApplication to show two windows in a sequence!
    First show the first window. When it is closed create and show the second one.



  • Hello, interestingly, I created almost the same question about the same time in another thread: https://forum.qt.io/topic/110416/pyside2-destroying-the-qapplication-instance-and-creating-another-one-gives-an-error

    If I continue here; my problem is the same thing (I cannot create a new QApplication after destroying one) and my application is not a singleton, so users are able to quit the application and create a new one in their programs. I can make it a singleton, and maybe I should, since a process cannot have more than one QApplication running at the same time as far as I know.

    But I still wonder why this code does not work, and if this is a bug? If yes, I'll look out for a way to report it. By the way the code works without a problem on PyQt5, it gives the singleton error only with PySide2.

    For reference the code I try:

    import sys
    from PySide2.QtWidgets import *
    
    app = QApplication(sys.argv)
    label = QLabel("Hello World")
    label.show()
    app.exec_()
    
    del app
    
    app = QApplication(sys.argv)
    label = QLabel("Hello World")
    label.show()
    app.exec_()
    
    sys.exit()
    


  • @canol said in How to destroy a singleton and then create a new one.:

    Hello, interestingly, I created almost the same question about the same time in another thread: https://forum.qt.io/topic/110416/pyside2-destroying-the-qapplication-instance-and-creating-another-one-gives-an-error

    Please don't double post!!



  • @canol
    I was the person who replied to you in your other thread to come here to this one!

    As per my observation there, your findings imply that there is a difference between PyQt5 & PySide2 here. Whether it;s a "bug" or "different handling" I can't say. It looks like the behaviour of del app varies. Not sure what to tell you to do if you insist on multiple QApplications, because the only answers are for PyQt5. You might try "shutting down" your first QApplication better, but I'm not certain how.....



  • @Pablo-J-Rogina said in How to destroy a singleton and then create a new one.:

    @canol said in How to destroy a singleton and then create a new one.:

    Hello, interestingly, I created almost the same question about the same time in another thread: https://forum.qt.io/topic/110416/pyside2-destroying-the-qapplication-instance-and-creating-another-one-gives-an-error

    Please don't double post!!

    I did not double post, we created similar question almost at the same time, I did not see this poster's post before I created mine. Do you have anything useful to add to the discussion?

    @JonB said in How to destroy a singleton and then create a new one.:

    @canol
    I was the person who replied to you in your other thread to come here to this one!

    As per my observation there, your findings imply that there is a difference between PyQt5 & PySide2 here. Whether it;s a "bug" or "different handling" I can't say. It looks like the behaviour of del app varies. Not sure what to tell you to do if you insist on multiple QApplications, because the only answers are for PyQt5. You might try "shutting down" your first QApplication better, but I'm not certain how.....

    Thank you, I'll investigate further.


  • Banned

    Wait wait wait .... I am not sure how far this discussion has got but this seems woefully wrong way to do this

    The process flow should be ---

    Start Program
        Call Record_Audio Main Window
        Switch to Processing Window
            Call Recognizer 
            Call SpeechConvert
            Call OtherProcessingFunctionsIfNeeded
        Switch to DisplayResults Main Window
    

    As such you never destroy the Main Event Thread as there is no need to -- you just switch between the various Windows you are using -- and if you sub-classed these various windows you can encapsulate what they do such that should you need a change to a single piece it you can easily do that without affecting any of the other pieces

    Create a Main Event Thread -- running a Window -- running some computational functions -- destroying the Main Event Thread and creating a new one to run another Window --- is far more complexity that is required and simply bad methodology



  • @canol , I've met same issue in Spyder (debug is possible one time after start only).
    So i've found a workaround:

        app = QApplication.instance()
        if app == None:
            app = QApplication([])
    

    instead of usual

        app = QApplication([])
    

    Maybe it'll help for you. It did the trick for me.


Log in to reply