我有一个简单的程序,它创建一个QGraphicsScene
/ View
然后执行一个给定的文件(通过python的exec
语句)和一些全局函数导出。
我的目标是只在新文件中定义场景代码,并且已经定义了一些辅助函数。
我的主程序中还有一个提供回调的线程,我想在回调的qgraphicsitems上做一些事情。
此处的示例定义了一个链接到一个回调的隐身动画:
from PySide import QtGui
# definition of an animation of invisibility
class AnimInvisible:
def __init__(self, item):
self.item = item
def on_callback(self, tag):
self.item.setVisible(tag.getProperty() != 0)
# creation of a simple QGraphicsRectItem
mon_rect = QtGui.QGraphicsRectItem(400, 300, 100, 50)
mon_rect.setBrush(QtGui.QBrush(QtGui.QColor('red')))
# this will add the rect to the scene defined in the file
# where the exec statement is done (exported by exec)
addItem(mon_rect)
a = AnimInvisible(mon_rect)
# this connect the a.on_callback on some changes from a thread. (exported from exec)
addCallback(a.on_callback, 'system:cmdamg')
这非常有效。但现在,如果我将AnimInvisible的代码放在另一个模块中 - 说动画 - 我在上面取代:
from animations import AnimInvisible
我收到错误,说内部C ++对象(PySide.QtGui.QGraphicsRectItem)已被删除..
这是一个我不理解的非常奇怪的行为。我也尝试使用PyQt而不是PySide,我得到了相同的行为(当AnimInvisible
的代码在模块中时对象被删除,如果它在同一个文件中则没有问题。)
答案 0 :(得分:1)
感谢你的评论alexisdm和varela,我发现了问题。
我做的是这样的事情:
class Synoptique:
def __init__(self, w, h):
self.view = QGraphicsView()
self.scene = SynopScene()
# some initialization ...
def openSynop(buApp, fname, w, h):
synop = Synoptique(w, h)
var_export = {
'addItem': synop.addItem,
'addCallback': buApp.addCallback,
}
exec open(fname) in var_export
synop.view.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
# buApp creation
openSynop(buApp, 'synop.py', 800, 600)
app.exec_()
但似乎对synop对象(包含QGraphicsView和Scene)的引用丢失了,因为它是openSynop函数中的局部变量。因此,引用QGraphicsView,场景和场景中的对象也会丢失。
处理它的一种方法是在函数外部,主调用中声明synop实例,或者从函数返回并保存synop引用。这解决了我的问题,例如:
def openSynop(buApp, fname, w, h):
# same as before...
return synop
if __name__ == '__main__':
# same as before...
s = openSynop(buApp, 'synop.py', 800, 600)
app.exec_()
我现在明白我必须在QGraphicsView / scene上保留一个参考,以便稍后操作场景内的QGraphicsItem ......哇,这对我来说不太明显,再次感谢!