PyQt application closes successfully, but process is not killed? - python

i just noticed that when i run a pyqt application and close it, the application closes , but the process is still alive. Apparently the process that was running does not close even after closing the application.
Traceback (most recent call last):
File "F:\Projects\XYZ\XYZ\XYZ.py", line 414, in <module>
sys.exit(app.exec_())
SystemExit: 0
When i searched online , its says that if the return value is 0 , it is a normal termination. As you see the process keep on pilling up as i run the application.
So how do i overcome this problem?

SOLUTION
This a quick fix , that i was able to make to solve this problem.
import psutil, os
def kill_proc_tree(pid, including_parent=True):
parent = psutil.Process(pid)
for child in parent.children(recursive=True):
child.kill()
if including_parent:
parent.kill()
app = QtGui.QApplication(sys.argv)
MainWindow = QtGui.QMainWindow() # <-- Instantiate QMainWindow object.
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
app.exec_()
me = os.getpid()
kill_proc_tree(me)

This looks like a problem specific to IDLE.
There are several issues on the python bug tracker that are closely related (e.g. 8093 and 12540), but they are now closed and resolved as "fixed".
Since it appears that you are using a very old version of python (2.5), you should be able to solve the problem by upgrading.

Have you tried the following?
sys.exit(app.exec_)
It's common practice among PyQt developers, and an easy way to cleanly quit your program. You should, however, upgrade to Python 2.7 or Python 3.3.

Related

How to debug sporadic freezing of PyQt5 application after exiting?

I'm developing PyQt5 application of medium complexity. It has various widgets (both native and third-party) and Qthreads. It woks fine most of the time, but once in about 5 times the application hangs in the background after I exit it.
Here is how I define closeEvent:
def closeEvent(self, event):
qApp.quit()
And I also have defined a quit_action and connected it to the qApp.quit() like this:
self.quit_action.triggered.connect(qApp.quit)
I launch the PyQt5 application the standard way:
app = QApplication([])
window = GUIWindow()
window.show()
sys.exit(app.exec())
I have no idea how to debug such strange error. It happens only once in a few times and I can't reproduce the error.
I run the application in the console:
python main.py
and usually I can close the application without a problem. But once in a few times after I close the application (either by clicking on "x" button of the window or by triggering the quit_action in the menu) the window disappears and the process hangs in the background. I have to press "Ctlr+Z" and then kill the process.
What is the strategy to debug such strange error? How can find what exactly causes the freezing of the application?
This kind of bugs are hard to isolate. It looks like my particular bug emerges as a result of combination of several widgets of the app and it's hard to even provide a minimal working example that reproduces the error. Not to mention the error only happens once in a few runs.
It looks like I've found the main culprit for the bug by inspecting the hanging process through the gdb (see the question from stackoverflow Is there a way to attach a debugger to a multi-threaded Python process?).
When my application has frozen again - I attached to the process via the gdb, investigated threads and found the problematic thread.
EDIT: A temporary solution to make PyQt application close even when qApp.quit() doesn't help:
def closeEvent(self, event):
qApp.quit()
sys.exit()

Python Kernel crashes after closing an PyQt4 Gui Application

Ok here is my problem:
I want to create a PyQt4 Gui, which can be executed from a python console (tested with IDLE, Spyder Console and IPython Console) and then allows the user to change and view variables. After closing the app the user should be able to do further work with the variables in the console. But by closing the Gui the Kernel crashes and it is not possible to make any new input to the console.
I'm working with Python 2.7 and PyQt4. I am using the following code to start an close the application:
app=QtGui.QApplication(sys.argv)
MainApp=plottest()
MainApp.show()
sys.exit(app.exec_())
The easy solution here https://www.reddit.com/r/learnpython/comments/45h05k/solved_kernel_crashing_when_closing_gui_spyder/
only put
if __name__ == "__main__":
app=0 #This is the solution
app = QtGui.QApplication(sys.argv)
MainApp = Dice_Roller()
MainApp.show()
sys.exit(app.exec_())
What you need to do is:
Check that there isn't already a QApplication instance when trying to create a new one
Ensure that the QApplication object is deleted after it's been closed
(See simple IPython example raises exception on sys.exit())
# Check if there's a pre-existing QApplication instance
# If there is, use it. If there isn't, create a new one.
app = QtGui.QApplication.instance()
if not app:
app = QtGui.QApplication(sys.argv)
# Ensure that the app is deleted when we close it
app.aboutToQuit.connect(app.deleteLater)
# Execute the application
MainApp = plottest()
MainApp.show()
sys.exit(app.exec_())
Using this code you can rerun the application as many times as you want in IPython, or anywhere else. Every time you close your Qt application, the app object will be deleted in python.
I do not think you mean a kernel crash. Rather, I think you are talking about exiting the python console. This is caused by sys.exit(app.exec_()). For example try (for example in spyder) the following two codes:
import sys
from PyQt4 import QtGui
app = QtGui.QApplication(sys.argv)
widget = QtGui.QWidget()
widget.setWindowTitle('simple')
widget.show()
#sys.exit(app.exec_())
Here you should get an empty window and the python console will stay alive. The second one, where sys.exit(app.exec_()) is included, will exit the python console at the end and the window disappears:
import sys
from PyQt4 import QtGui
app = QtGui.QApplication(sys.argv)
widget = QtGui.QWidget()
widget.setWindowTitle('simple')
widget.show()
sys.exit(app.exec_())
I hope this helps.
I still don't know the issue and solution. None of the above worked for me. Currently I am coding in the spyder GUI and running on "cmd" by giving 'python' command. In CMD, it is working fine.
Update the solution if I get it. :-)
I think that your problem is that python console closes (its not kernel crash). For example in Spyder python icon on top of console window becomes grey and you cant do anything besides running another console.
Anyway, you should write app.exec() instead of sys.exit(app.exec()).
I believe sys.exit(app.exec()) passes exit code to console and closes it. Using simple app.exec() won't close console.
Concluding your code should look like:
app=QtGui.QApplication(sys.argv)
MainApp=plottest()
MainApp.show()
app.exec_()
I hope it helps.
hdunn's answer worked for me. Have deleted sys.exit() to avoid exiting the application totally. Performing the first step alone, as suggested by others in github forum, solved part of the problem but window never showed up, nor any error message. Performing the second part solved everything like a charm! Thans, hdunn!
# Check if there's a pre-existing QApplication instance
# If there is, use it. If there isn't, create a new one.
app = QtGui.QApplication.instance()
if not app:
app = QtGui.QApplication(sys.argv)
# Ensure that the app is deleted when we close it
app.aboutToQuit.connect(app.deleteLater)
# Execute the application
MainApp = plottest()
MainApp.show()
app.exec_()

PyQt4 application on Windows is crashing on exit

I am writting a desktop application with PyQt4 and all of the sudden it started to crash on exit.
I reviewed all of my code to make sure I wasn't doing anything funny to make it crash and I don't think there's anything wrong with the code.
I have seen some complaints about this before but it was related to a previous version and people advised to upgrade PyQt4 to the latest version and so I did, but that didn't help with the crashing problem.
So I ask, is there anything that can lead to this behavior with PyQt4, do I need to do some kind on termination procedure to cleanup Qt or anything else I am missing?
I had the same problem with a simple hello world application (QDialog with 20 labels). Weirdly the problem disappears with 10 labels.
I solved by forcing exit as follows:
def closeEvent(self, event):
exit()
This happens on Windows with PyQt v4.10.3 for Python v2.7 (x32) on VirtualBox.
A debugger will only tell us what we already know: The application crashes on exit.
You probably need to set an active window which, when closed, will result in deterministic garbage collection and a clean application exit. There are more proper ways to do this, but the simpl;e example below should require minimum code changes, and is based on a dialog application that I wrote and works fine.
#The application
app = QtGui.QApplication(sys.argv)
#The main window
MainWindow = QtGui.QMainWindow()
app.setActiveWindow(MainWindow) #<---- This is what's probably missing
#the ui
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
#start the application's exec loop, return the exit code to the OS
exit(app.exec_())

Execute Python code from within PyQt event loop

I am testing a gui built using PyQt and I would like the ability to interact with the gui using python code that is executed after the PyQt event loop starts (app.exec_()). Another way of saying this is I would like the call to app.exec_ to return immediately as if the gui were modeless, followed by further python code which interacts with the gui.
I found this example of running the PyQt loop in a thread but don't want to do something so unconventional. Is there any way to get the PyQt message loop to continue processing messages while also executing python code in the main thread after exec_ has been called?
One option here is to use a QtCore.QTimer.singleShot() call to start your python code after calling `exec_()'.
For example:
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
# Setup the GUI.
gui = MyGui()
gui.showMainWindow()
# Post a call to your python code.
QtCore.QTimer.singleShot(1000, somePythonFunction)
sys.exit(app.exec_())
This will execute the function somePythonFunction() after 1 second. You can set the time to zero to have the function added immediately queued for execution.
As a possible easy answer, try not calling app.exec_() in your script and running your PyQt program using python -i My_PyQt_app.py.
For example:
## My_PyQt_app.py
import sys
from PyQt5.QtWidgets import QApplication, QWidget
app = QApplication(sys.argv)
window = QWidget()
window.show()
# Don't start the event loop as you would do normally!
# app.exec_()
Doing this should allow you to run the GUI through the terminal and interact with it in the command line.
I got it. I can execute the test script line-by-line from the main thread using exec and then run the gui from a worker thread.
Not exactly sure what you wanna do. Are you looking for something like Py(known as PyCrust) for PyQt?
The easiest way is to use IPython:
ipython --gui=qt4
See ipython --help or the online documentation for more options (e.g. gtk, tk, etc).

PyQt debugging in main loop

Can I debug PyQt application when is main loop running ?
Pdb, NetBeans, PyDev, all "freeze" when sys.exit(app.exec_()) is executed.
I probably missing something obvious. Or what can be problem, please ?
I apologize for my "creepy" english. Thanks.
I'm assuming your main() function looks something like this:
def __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
myapp = MyApplication()
myapp.show()
sys.exit(app.exec_())
If not, post some example code to help determine what coudl be wrong.
If that is what your code looks like, you can debug any part of you program using IDLE (included in Python install). Once in IDLE, goto Debug-->Debugger to turn DEBUGGING ON. Then open your .py file, and run it (F5). You can set breakpoints by right-clicking on any line in the file, and choosing Set Breakpoint.
Check this other SO question for more info and good links to alternative debuggers/IDEs:
Cleanest way to run/debug python programs in windows

Categories

Resources