我在使用pyside时遇到了一个相当令人沮丧的问题,我欢迎任何建议。
首先,一些背景
我使用Qt Designer创建了一个简单的GUI,并且我使用了pyside-uic.exe
到我的.ui
文件以生成关联的 Python 文件。
我正在使用 Python 3.3 和 pyside 1.2.1 以及 Qt Designer 4(Qt 4.8.5)。
我使用以下代码来启动我的 GUI:
class my_dialog(QMainWindow, my_gui.Ui_main_window):
def __init__(self, parent=None):
super(my_dialog, self).__init__(parent)
self.setupUi(self)
if ("__main__" == name):
app = QApplication(sys.argv)
main_dialog = my_dialog()
# (1)
main_dialog.show()
sys.exit(app.exec_())
我想实现什么
我的 GUI 有几个选项卡。选项卡的数量不是预先确定的,而是在运行时评估的。因此,我决定在 Qt Designer 中创建一个选项卡,用作模板。
第一次需要添加选项卡时,我修改了此模板,如果我需要任何其他选项卡,我计划制作该选项卡的副本然后适当修改该副本。
我遇到的问题
我的问题是我似乎找不到复制选项卡小部件的方法。经过一番研究,我认为 copy
模块(或 pickle
模块,请参阅编辑)可能会解决这个问题(以下代码已插入 (1)):
new_tab = copy.deepcopy(main_dialog.my_tab)
main_dialog.my_tabs.addTab(new_tab, "")
但这引发了以下错误:
main_dialog.my_tabs.addTab(new_tab, "")
RuntimeError: Internal C++ object (Pyside.QtGui.QWidget) already deleted
我自己能找到什么
我在 SO 和其他网站上看到,使用 pyside 时,收集对象可能会出现问题,因为 中没有对它们的引用Python。
然而,事实仍然是,即使我将此代码移至非常 setupUi()
.py
中的方法由pyside生成的文件,我仍然得到完全相同的错误。
还值得注意的是,我能够访问 my_tab
对象轻松修改其内容。
我可以在我的代码中从头开始创建另一个选项卡 main_dialog.my_tabs.addTab(new_tab, "")
在这种情况下工作得很好。
经过一些实验,我意识到问题可能出现在my_tab
的副本上。目的。事实上,复制我刚刚创建的选项卡对象时,我可以看到尝试将副本添加到 GUI 选项卡也失败了,并且出现相同的错误。
看起来复制失败,或者由于某种原因该对象被立即删除。无论如何,这就是我的推断......
我的问题
考虑到这一切,我想找到一种方法来成功复制对象,找到另一种方法来使用现有的pyside对象作为其他类似的模板对象。
我当然可以从生成的文件中取出选项卡的代码并编写我自己的代码 addTab()
方法。但是,我预计会从现有的 .ui
进行构建文件并避免对 GUI 元素进行硬编码。
编辑:
当使用pickle
时:
new_tab = pickle.loads(pickle.dumps(main_dialog.my_tab, -1))
我收到以下错误:
new_tab = pickle.loads(pickle.dumps(main_dialog.my_tab, -1))
_pickle.PicklingError: Can't pickle <class 'Pyside.QtCore.SignalInstance'>: attribute lookup Pyside.QtCore.SignalInstance failed.
最佳答案
为要复制的小部件创建单独的 ui 文件的建议似乎是一个合理的解决方案。尽管使用 pyside-uic 为小部件生成单独的 gui 模块似乎与使用 QUiLoader 一样有效(事实上,它会稍微更高效)。
至于为什么克隆小部件使用例如copy.deepcopy
不起作用:这是因为它只会复制 python 包装器,而不是底层的 C++ 对象。更全面的解释可以在 this answer 中找到。 .
关于python - 尝试复制 pyside 对象时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22683755/