suppose I have a class which at some point in time will need to open a GUI, provided through a PySide implementation.
For example (and simplified) it could be looking something like this:
class MyBackgroundClass:
def __init__(self):
#init stuff
def open_gui(self):
self.gui = MyGui()
At some point in time the method open_gui()
will be called, which should initialize the GUI, which is implemented somehow like this:
class MyGui():
def __init__(self):
app = QApplication(sys.argv)
self.window = MainWindow()
sys.exit(app.exec())
In this case MainWindow
is another class which adds all elements to the GUI, which is not important here.
So basically MyGUI
is just an implementation similar to how you typically implement a PySide/PyQT GUI, by using a QApplication
and using sys.exit(app.exec())
.
My Problem is, that because of sys.exit
, the program termiantes completely when the GUI is closed, which is not what I want. I need the GUI to close when requested, but the main program MyBackgroundClass
in this example needs to keep running.
I don't really know how to solve this problem.
This is my first attempt:
I tried removing sys.exit(app.exec())
which led to following behaviour:
- When I just run a script which opens the GUI, the GUI closes instantly.
- But when I run my background script and create an instance of my GUI class, the GUI opens just fine. I think this is the case because in the second case, the GUI is not the main program.
I tried using self.destroy()
and self.close()
(where self
refers to an object of the MainWindow
class -> see init of MyGUI class) to close the GUI, because I am not using sys.exit(app.exec())
anymore, which worked to some extend:
I was able to open and then close the GUI without any problems, but when I tried to reopen the GUI, this error occurred:
app = QApplication(sys.argv)
RuntimeError: Please destroy the QApplication singleton before creating a new QApplication instance.
So the program fails when it tries to open the GUI again after it has been opened once, because there is still a QApplication which was not destroyed. The problem is, I don't know how to destroy the QApplication
(in my case called "app"), because self.destroy()
and self.close()
only close the window, which is called "self.window" in my case.
Normally the QApplication would be destroyed when the program terminates, because of sys.exit(app.exec())
. But because of the reasons above, sys.exit(app.exec())
had to be removed.
My solution (for now):
Because I cant create another QApplication
when there already is one because of the error above, I came up with this solution for MyGui
:
class MyGui():
def __init__(self):
try:
app = QApplication(sys.argv)
except Exception as e:
print(e)
self.window = MainWindow()
So I basically just removed sys.exit(app.exec())
(because of the reasons above) and added a try/except block. The try/except block tries to create a QApplication
, which succeeds, when the GUI is opened for the first time, but fails when the GUI is reopened. Therefore, I wont get the error that there is still a QApplication
which did not get destroyed. And I can still created my GUI without any problems, because, well, the QApplication
is still there.
Conclusion
I did find this solution and it works just fine, but I am not satisfied with the result. Using the try/except block solved the problem for me, but is a very very bad way of solving this problem.
I hope I made myself clear and some of you have some other ideas to solve this problem in a more appropriate way.
Thanks in advance!