【问题标题】:PySide widgets using .ui files being garbage-collected unexpectedly使用 .ui 文件的 PySide 小部件意外地被垃圾收集
【发布时间】:2016-01-15 23:59:32
【问题描述】:

我有一个在 Nuke 中运行的 PySide QMainWindow。应用程序使用的一些小部件使用在 Qt Designer 中创建的.ui 文件。

直到最近,QMainWindow 类还没有被赋予父级。因此,当 Nuke 被最小化或改变焦点时,QMainWindow 并没有最小化或获得焦点。

为了解决这个问题,在创建 QMainWindow 时,我使用了QApplication.activeWindow() 方法来获取一个对象以作为父级提供 QMainWindow。

parent = QApplication.activeWindow()
window = MyMainWindow(parent)

如果我这样做,QMainWindow 将最小化并使用 Nuke 更改焦点。但是,当访问使用.ui 文件创建的任何小部件的子小部件时,它会引发异常

Traceback (most recent call last):
    ...
RuntimeError: Internal C++ object (PySide.QtGui.QPushButton) already deleted.

我正在使用very similar to this 方法将.ui 文件加载到我的QWidget 类中

为什么要删除 C++ 对象(垃圾收集)?当我为 QMainWindow 指定父级时,为什么行为会发生变化?是否有另一种方法将 QMainWindow 设置为 Nuke 的父对象,以便正确最小化和聚焦,或者以不同的方式加载 .ui 文件而不会遇到此垃圾收集问题?

【问题讨论】:

  • 您能否展示父级如何传递给 ui 加载方法以及 ui 加载器的代码(如果它与链接中的代码不同)。我怀疑如何指定 ui 文件中小部件的父级存在错误,我是 ui 加载器,导致它们被垃圾收集。
  • 我没有回答您的问题,但总的来说,我建议使用模拟 PyQt 中的 uic.loadUiType 函数的方法(类似于 this example)。换句话说,在导入模块时解析一次您的 .ui 文件并生成您的自定义小部件继承的 Python 类(或不,取决于您需要做多少设置)。

标签: python qt garbage-collection pyside nuke


【解决方案1】:

当父小部件之一因为不存在 python 对象引用而被垃圾收集时,就会出现问题。例如:

def create_window():
    parent = QApplication.activeWindow()
    window = MyMainWindow(parent)
    return window

当函数返回时,parent 对象超出范围,它所代表的 C++ pyobject 最终会被垃圾回收。奇怪的是,这只是使用.ui 文件创建的小部件的问题。解决方案是只保留对所有父对象的引用。我正在使用全局变量来存储对它们的引用。

GC_PROTECT = []

def create_window():
    parent = QApplication.activeWindow()
    GC_PROTECT.append(parent)
    window = MyMainWindow(parent)
    return window

【讨论】:

    【解决方案2】:

    如果窗口被声明为全局,在窗口本身关闭之前它不会被销毁。因此,您希望对窗口/小部件本身的引用继续存在于某处,而不一定是父级(如上一个答案中所述)

    def create_window():
        parent = QApplication.activeWindow()
        # not necesarily the best practice to declare it here, but comfortable
        Global window
        window = MyMainWindow(parent)
        return window
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-10
      • 2019-11-15
      • 1970-01-01
      • 2010-10-07
      • 1970-01-01
      相关资源
      最近更新 更多