尝试复制pyside对象时发生问题 [英] Issue while trying to copy pyside object

查看:478
本文介绍了尝试复制pyside对象时发生问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 pyside 有一个令人沮丧的问题,我欢迎任何建议。



首先,一些上下文



我已经使用 Qt Designer 创建了一个简单的GUI使用 pyside-uic.exe 到我的 .ui 文件以生成关联的 档案 。 > ( 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 )

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 ++对象(Pyside.QtGui.QWidget)已删除


我可以在自己的 >

我在SO和其他网站上看到,使用 pyside 时,可能会出现问题,因为在 中没有提到它们。



然而,事实是,即使我移动这个代码到 pyside 生成的 .py 文件中的



还值得注意的是,我可以访问 my_tab

我可以在我的代码中从头开始创建另一个标签, main_dialog.my_tabs .addTab(new_tab,)在此上下文中工作完全正常。



经过一些实验,我意识到问题可能发生在副本的 my_tab 对象。事实上,复制一个我刚刚创建的Tab对象,我可以看到,试图添加副本到GUI选项卡失败,并有相同的错误。



像复制失败,或者该对象由于某种原因被立即删除。这是我正在推断...


$ b

我的问题



所有这一切,我想找到一种方式要么在对象副本中成功,要找到另一种方式使用现有的 pyside 对象作为其他类似对象的模板。 p>

可以 当然会从生成的文件中取出选项卡的代码,并自己编写代码 addTab()方法。但是,我希望从现有的 .ui 文件构建,避免硬编码GUI元素。



编辑:



使用 pickle 时:

  new_tab = pickle.loads(pickle.dumps(main_dialog.my_tab,-1))

我得到以下错误:


  new_tab = pickle。 load(pickle.dumps(main_dialog.my_tab,-1))

_pickle.PicklingError:Can not pickle< class'Pyside.QtCore.SignalInstance'> ;:属性查找Pyside.QtCore.SignalInstance失败。



解决方案

为要复制的小部件创建单独的ui文件的建议似乎是一个合理的解决方案。虽然似乎使用pyside-uic为小部件生成单独的gui模块与使用 QUiLoader (事实上,它会稍微更有效率)一样工作。



至于为什么克隆小部件使用eg的问题 copy.deepcopy 不工作:这是因为它将只复制python包装,而不是底层的C ++对象。有关更完整的说明,请参阅此答案


I am having a rather frustrating problem using pyside and I would welcome any advice.

First, some context

I have created a simple GUI using Qt Designer and I have used pyside-uic.exe onto my .ui file in order to generate the associated Python file.

I am using Python 3.3 and pyside 1.2.1 with Qt Designer 4 (Qt 4.8.5).

I am using the following code to launch my 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_())

What I would like to achieve

My GUI features several tabs. The number of tabs is not pre-determined and is evaluated at run time. As a result, I've decided to create one tab in Qt Designer, to use as a template.

The first time I need to add a tab, I modify this template, and if I need any additionnal tab, I was planning on making a copy of that tab and then modify that copy appropriately.

The issue I have encountered

My problem is that I can't seem to find a way to copy the tab widget. After some research, I thought the copy module (or the pickle module, see edit) might do the trick (the following code was inserted at (1)):

new_tab = copy.deepcopy(main_dialog.my_tab)
main_dialog.my_tabs.addTab(new_tab, "")

But that triggered the following error:

    main_dialog.my_tabs.addTab(new_tab, "")

RuntimeError: Internal C++ object (Pyside.QtGui.QWidget) already deleted

What I could find on my own

I have seen on SO and other sites that there may be issues, when using pyside, of objects being collected because there is no reference to them in Python.

The fact remains, however, that even if I move this code to very setupUi() method in the .py file generated by pyside, I still get the exact same error.

It is also worth noting that I am able to access the my_tab object to modify its content without any trouble.

I am able to create another tab from scratch in my code and main_dialog.my_tabs.addTab(new_tab, "") works perfectly fine in that context.

After some experimentations, I realized the problem probably occurs at the copy of the my_tab object. Indeed, copying a tab object that I just created, I could see that trying to add the copy to the GUI tabs failed too, and with the same error.

It looks like the copy fails somehow, or the object is being immediately deleted for some reason. That's what I'm infering anyway...

My question

Considering all this, I would like to find a way to either succeed in the object copy, find another way to use an existing pyside object as template for other similar objects.

I could of course take the code for the tab out of the generated file and code my own addTab() method. However, I am expected to build from an existing .ui file and avoid hardcoding GUI elements.

EDIT:

When using pickle:

new_tab = pickle.loads(pickle.dumps(main_dialog.my_tab, -1))

I get the following error:

    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.

解决方案

The suggestion of creating a separate ui file for the widget you want to copy seems a reasonable solution. Although it would seem that generating a separate gui module for the widget using pyside-uic would work just as well as using QUiLoader (in fact, it would be slightly more efficient).

As for the question of why cloning widget using e.g. copy.deepcopy doesn't work: this is because it will only copy the python wrapper, and not the underlying C++ object. A somewhat fuller explanation can be found in this answer.

这篇关于尝试复制pyside对象时发生问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆