我喜欢python和Qt,但对我来说很明显,Qt并不是用python设计的。有许多方法可以使PyQt / PySide应用程序崩溃,其中许多方法都非常难以调试,即使使用适当的工具也是如此。
我想知道:使用PyQt和PySide时,避免崩溃和锁定的好方法是什么?这些可以是从一般编程技巧和支持模块到高度特定的解决方法和要避免的错误。
答案 0 :(得分:48)
请注意Qt自动删除对象的情况。如果没有通知python包装器已删除C ++对象,那么访问它将导致崩溃。由于PyQt和PySide在跟踪Qt对象方面存在困难,因此可能会以多种方式发生这种情况。
从QTreeWidget中删除项目将导致删除任何关联的窗口小部件(使用QTreeWidget.setItemWidget设置)。
# Example:
from PyQt4 import QtGui, QtCore
app = QtGui.QApplication([])
# Create a QScrollArea, get a reference to one of its scroll bars.
w = QtGui.QWidget()
sa = QtGui.QScrollArea(w)
sb = sa.horizontalScrollBar()
# Later on, we delete the top-level widget because it was removed from the
# GUI and is no longer needed
del w
# At this point, Qt has automatically deleted all three widgets.
# PyQt knows that the QScrollArea is gone and will raise an exception if
# you try to access it:
sa.parent()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: underlying C/C++ object has been deleted
# However, PyQt does not know that the scroll bar has also been deleted.
# Since any attempt to access the deleted object will probably cause a
# crash, this object is 'toxic'; remove all references to it to avoid
# any accidents
sb.parent()
# Segmentation fault (core dumped)
答案 1 :(得分:4)
只是添加到这一点:
如果你必须在基于qt的程序中使用线程,你必须禁用自动垃圾收集器并在主线程上进行手动收集(如http://pydev.blogspot.com.br/2014/03/should-python-garbage-collector-be.html中所述) - 请注意你应该这样做如果你确定你的物体没有周期(有一个循环你基本上让你的物体存活直到蟒蛇循环垃圾收集器碰到,但有时如果你有一些例外,它可能是一个框架因此,在这种情况下,您的物体可能仍然比您预期的更长时间保持活着... ...在这种情况下,垃圾收集器可能会在次要线程中碰撞,这可能会导致qt to segfault(必须始终在主线程中收集qt小部件)。
答案 2 :(得分:4)
仅供参考,我将comment from the author of PyQt张贴在卢克的回答中:&#34;它是垃圾。&#34;
我认为这很重要,因为有人可以跳到这个帖子并且仍然对所有这些(不存在的)&#34;问题&#34;感到困惑。
答案 3 :(得分:0)
发射信号而不是同步UI控制是我在逻辑电路模拟器实现过程中避免出现问题的关键