The workaround to a crash upon exit given in this answer works in pyqt4.
But not using pyqt5, where there is often (more than half the times) a segmentation fault.
Only the import lines changed
#!/usr/bin/python
import sys
#toolkit = "Qt4"
toolkit = "Qt5"
if toolkit == "Qt4":
# Qt4 (no crash)
from PyQt4.QtCore import *
from PyQt4.QtGui import *
elif toolkit == "Qt5":
# Qt5 (crash)
from PyQt5.QtWidgets import (
QApplication, QGraphicsScene, QGraphicsView
)
app = QApplication(sys.argv)
grview = QGraphicsView()
# no crash
scene = QGraphicsScene(parent=grview)
grview.setScene(scene)
grview.show()
sys.exit(app.exec_())
Here is the backtrace, from the core dump (as a side note, inside gdb, there is no crash)
[New LWP 4684]
[New LWP 4683]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
Core was generated by `python grview_qt5.py'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x00007f5233393e69 in ?? ()
(gdb) bt
#0 0x00007f5233393e69 in ()
#1 0x00007f522fee6f20 in ()
#2 0x0000000000e0d340 in ()
#3 0x00007f522fee6f20 in ()
#4 0x0000000000e0d5f0 in ()
#5 0x00007f523e0bc000 in _rtld_local () at /lib64/ld-linux-x86-64.so.2
#6 0x00007f523ae7285f in QThreadPrivate::start(void*) (arg=0xe0d340) at thread/qthread_unix.cpp:337
#7 0x00007f523d8780a4 in start_thread (arg=0x7f522fee7700) at pthread_create.c:309
#8 0x00007f523d5adcbd in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111
(gdb) info threads
Id Target Id Frame
2 Thread 0x7f523e06f700 (LWP 4683) 0x00007f523deb21c7 in munmap () at ../sysdeps/unix/syscall-template.S:81
* 1 Thread 0x7f522fee7700 (LWP 4684) 0x00007f5233393e69 in ?? ()
Why the difference between pyqt4 and pyqt5 ?
It is surely related to Object Destruction on Exit, but how ?
What is the correct way to avoid this crash ?
解决方案
I cannot make your example crash using Fedora 24's PyQt.
However I am also seeing this problem and do not have a definitive answer on how to clean up Qt objects before python exits. My app has 1000's of Qt objects and I'm not at all clear on hopw I will track down all the objects that fail to clean up.
I think the key is that you have to delete all the objects you have created in the reverse order of construction. Taking care to remove objects from any Qt object that has a reference to an other object. e.g widgets in a layout.
As I said in the comment the difference comes from changes from python2 to python3 to do with object deletion and garbage collection.
Using sys.exit() to avoid the clean up is not good enough.
You need to use os._exit( code ) which will prevent python from running onExit handlers. That is more likely to suppress the seg fault. But you will need to make sure that any important onExit handlers are run. For example to delete temp files.
Try exiting like this and see if for you the problem goes away.
grview.show()
rc = app.exec_()
del grview
del scene
del app
sys.exit( rc )