3

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

直到最近,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.

我正在使用与此非常相似的方法将文件加载.ui到我的 QWidget 类中

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

4

2 回答 2

3

当其中一个父小部件因不存在 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
于 2016-02-02T19:45:22.183 回答
0

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

def create_window():
    parent = QApplication.activeWindow()
    # not necesarily the best practice to declare it here, but comfortable
    Global window
    window = MyMainWindow(parent)
    return window
于 2016-11-03T21:43:04.610 回答