2016-08-23 66 views
2

在pyqt4中,在this answer中給出的退出時崩潰的解決方法工作。在pyQt5中退出時出現分段錯誤,但不在pyQt4中

但是不能使用pyqt5,其中經常(超過一半的時間)出現分段錯誤。

只有進口線改變

#!/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_()) 

這裏是回溯,from the core dump(作爲一個側面說明,GDB裏,有沒有崩潰)

[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 ??() 

爲什麼PyQt4的和pyqt5之間的區別?

這肯定與Object Destruction on Exit有關,但是怎麼樣?

什麼是避免這種崩潰的正確方法?

+1

python3在不同的時間刪除對象,然後python2。嘗試在sys.exit之前使用顯式del對象:del grview; del scene; del app ;. –

+1

用'QtCore.QTimer.singleShot(1000,app.quit)'替換所有圖形內容,這樣只創建一個'QApplication'。如果仍然崩潰,請使用'QCoreApplication'來代替。這可能有助於縮小問題的根源。 – ekhumoro

+0

@ekhumoro將所有圖形的東西替換爲'QTimer.singleShot(1000,app.quit)',沒有崩潰。 – ederag

回答

2

我不能讓你的例子使用Fedora 24的PyQt崩潰。

但是我也看到這個問題,並沒有關於如何清理python退出前清理Qt對象的明確答案。我的應用程序有1000個Qt對象,我對hopw一點都不清楚,我會追查所有未清理的對象。

我認爲關鍵是你必須刪除所有以相反的構造順序創建的對象。注意從任何引用其他對象的Qt對象中刪除對象。例如佈局中的小部件。

正如我在評論中所說的,不同之處在於從python2到python3的變化與對象刪除和垃圾收集有關。

使用sys.exit()來避免清理不夠好。

您需要使用os._exit(代碼)來防止python運行onExit處理程序。這更有可能抑制seg故障。但是您需要確保運行任何重要的onExit處理程序。例如刪除臨時文件。

試試像這樣退出,看看你的問題是否消失。

grview.show() 
rc = app.exec_() 

del grview 
del scene 
del app 

sys.exit(rc) 
+0

在這兩種情況下,我都使用相同的Python版本(Python 2.7.12),那麼差異將如何解釋爲「從python2到python3的更改」? – ederag

+0

Qt版本是4.8.6和5.4.2 – ederag

+0

隨着你的建議,沒有崩潰。交換del場景和del grview線也沒有崩潰。按順序刪除應用程序,場景和grview,也不會崩潰。實際上'del grview'和'del scene'對於防止崩潰沒有必要。只有'del app'很重要。爲什麼? – ederag

相關問題