每次拖放(从一个QListWidget到另一个QListWidget)时,我都会因为它的强度和复杂性而变得疯狂。我知道AssertionError
是由类实例的一个属性引起的(类实例变量通过.setData()附加到QListWidget项上)。其中一个属性与pickle
不兼容。如果您能告诉我如何处理这个问题以及如何有效地调试它,我将不胜感激。到目前为止,唯一的解决方案是逐个检查每个class属性,将其设置为None,然后检查这是否解决了Assertion Error
问题。但这样的方法非常乏味和耗时。在
经过几个小时的调试,我已经把代码压缩到了最低限度。它与我在Qt小部件(如QListWidget)无法使用pickle
执行任务时遇到的相同问题进行了复制。在
简短信息:
声明了ClassA和ClassB的两个实例。然后instB存储在instA属性中。反之亦然:instA存储到instB属性。通过list()直接分配给setitem。拖放该项会导致pickle失败。 请就今后如何避免这种情况提出建议。是什么原因造成的。如果有可能解决的话。在
from PyQt4 import QtCore, QtGui
class Base(dict):
def __init__(self):
super(Base, self).__init__()
def setInstB(self, instB):
self['instB']=instB
class ClassA(Base):
def __init__(self):
super(ClassA, self).__init__()
class ClassB(Base):
def __init__(self):
super(ClassB, self).__init__()
def setInstA(self, instA):
self.instA=instA
instA=ClassA()
instB=ClassB()
instA.setInstB(instB)
instB.setInstA(instA)
class Dialog(QtGui.QMainWindow):
def __init__(self, instA):
super(QtGui.QMainWindow,self).__init__()
widget = QtGui.QWidget()
layout = QtGui.QVBoxLayout()
widget.setLayout(layout)
self.listA=QtGui.QListWidget()
self.listA.setAcceptDrops(True)
self.listA.setDragDropMode(QtGui.QAbstractItemView.DragDrop)
self.listA.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
listItem=QtGui.QListWidgetItem(str(id(instA) ) )
listItem.setData(QtCore.Qt.UserRole, instA)
self.listA.addItem(listItem)
self.listB=QtGui.QListWidget()
self.listB.setAcceptDrops(True)
self.listB.setDragDropMode(QtGui.QAbstractItemView.DragDrop)
self.listB.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
layout.addWidget(self.listA)
layout.addWidget(self.listB)
self.setCentralWidget(widget)
app = QtGui.QApplication(sys.argv)
dialog=Dialog(instA)
dialog.show()
dialog.resize(480,320)
sys.exit(app.exec_())
问题似乎是循环引用-
instA
引用instB
,反之亦然。 以下是我的工作:在
instB.setInstA(instA)
中添加注释将导致复制错误消息。 因此,如果您可以在没有循环引用的情况下生存,这可能是最简单的解决方法。在googling for
pyqt pickle protocol
显示,有一个接口可以设置PyQt的pickle协议:参见:http://freecode.com/projects/pyqt/releases/354104
所以
^{pr2}$可能会成功。在
相关问题 更多 >
编程相关推荐