我一直在为我的基于 PyQt 的项目开发一些调试/测试基础设施。我用特殊的调试属性标记了大多数小部件,即使小部件是在 C++ 端创建的。
但是,多次访问 a 中的同一个按钮QFileDialog
似乎会产生新的sip 包装器实例。也就是说,如果我多次访问“取消”按钮,PyQt 不会每次都返回相同的 Python 对象。
这是可用于重现该问题的最小测试程序:
from PyQt4.QtCore import QTimer
from PyQt4.QtGui import QApplication, QFileDialog, QDialogButtonBox
def print_debug_stuff():
# Find the dialog from among the top-level widgets
dlg = filter( lambda w: isinstance(w, QFileDialog), QApplication.topLevelWidgets() )[0]
# Find the button box in the dialog, then find the cancel button
buttonBox = dlg.findChild(QDialogButtonBox, "buttonBox")
cancelButton = buttonBox.children()[2]
# Does it have our debug attribute? Can we add it?
print "Tagging button: '{}' ({})".format( cancelButton.text(), cancelButton )
print "...had my_debug_tag?", hasattr(cancelButton, "my_debug_tag")
# Add the debug attribute
buttonBox.children()[2].my_debug_tag = "hello"
print "...has my_debug_tag?", hasattr(cancelButton, "my_debug_tag")
app = QApplication([])
# Repeatedly print debug info until the program quits
timer = QTimer(timeout=print_debug_stuff)
timer.setInterval( 100.0 )
timer.start()
# Open a (non-native!) file save dialog
QFileDialog.getSaveFileName(options=QFileDialog.DontUseNativeDialog)
我希望这可以编程输出如下内容:
Tagging button: 'Cancel' (<PyQt4.QtGui.QPushButton object at 0x1013c8cb0>)
...had my_debug_tag? False
...has my_debug_tag? True
Tagging button: 'Cancel' (<PyQt4.QtGui.QPushButton object at 0x1013c8cb0>)
...had my_debug_tag? True
...has my_debug_tag? True
Tagging button: 'Cancel' (<PyQt4.QtGui.QPushButton object at 0x1013c8cb0>)
...had my_debug_tag? True
...has my_debug_tag? True
...但是,这就是我实际看到的。注意cancelButton
对象每次的地址都不一样,而且我添加的调试属性丢失了:
Tagging button: 'Cancel' (<PyQt4.QtGui.QPushButton object at 0x1013c8cb0>)
...had my_debug_tag? False
...has my_debug_tag? True
Tagging button: 'Cancel' (<PyQt4.QtGui.QPushButton object at 0x1013c8ef0>)
...had my_debug_tag? False
...has my_debug_tag? True
Tagging button: 'Cancel' (<PyQt4.QtGui.QPushButton object at 0x1013c8e60>)
...had my_debug_tag? False
...has my_debug_tag? True
Tagging button: 'Cancel' (<PyQt4.QtGui.QPushButton object at 0x1013c8dd0>)
...had my_debug_tag? False
...has my_debug_tag? True
所以看起来 PyQt 正在“丢失”它之前创建的 Python 对象,然后为每次重复访问创建一个“新”对象。这是预期的吗?
顺便说一句,此测试程序在 Mac OS X (10.7) 和 Linux (Ubuntu 12) 上的行为相同。我正在使用 PyQt 4.8.5。