3

I have a PySide QMainWindow that I'm running in Nuke. Some widgets used by the application use .ui files created in Qt Designer.

Until recently, the QMainWindow class was not given a parent. Because of this, when Nuke was minimized or changed focus, the QMainWindow did not minimize or gain focus with it.

To fix that issue, when creating the QMainWindow, I used the QApplication.activeWindow() method to get an object to feed the QMainWindow as a parent.

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

If I do this, the QMainWindow will minimize and change focus with Nuke. However, when accessing subwidgets of any widget created with .ui files, it will raise an Exception

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

I'm using a method very similar to this to load the .ui files onto my QWidget classes

Why are the C++ objects being deleted (garbage-collected)? Why does the behavior change when I specify a parent for the QMainWindow? Is there another way to parent the QMainWindow to Nuke so that in minimizes and focuses correctly or a different way to load the .ui files without experiencing this garbage collection issue?

Brendan Abel
  • 35,343
  • 14
  • 88
  • 118
  • 1
    Can you show how the parent is being passed to the ui loading method and the code for the ui loader if it differs from the one in the link. I suspect there is a bug in how the parent of the widgets from the ui file is being specified I'm the ui loader, causing them to be garbage collected. – three_pineapples Jan 16 '16 at 11:26
  • I don't have an answer to your question, but in general, I would recommend using an approach that emulates the `uic.loadUiType` function from PyQt (similar to [this example](http://stackoverflow.com/questions/4442286/python-code-genration-with-pyside-uic/14195313#14195313)). In other words, parsing your `.ui` files once when a module is imported and generating Python classes that your custom widgets inherit (or don't, depending on how much setup you need to do). – nrusch Feb 02 '16 at 19:04

2 Answers2

3

The problem occurs when one of the parent widgets gets garbage-collected because no python object reference exists. For instance:

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

When the function returns, the parent object goes out of scope and the C++ pyobject it represents will eventually get garbage collected. It is strange that this is only a problem for widgets created with .ui files. The solution is to just keep a reference to all the parent objects. I'm using a global variable to store references to them.

GC_PROTECT = []

def create_window():
    parent = QApplication.activeWindow()
    GC_PROTECT.append(parent)
    window = MyMainWindow(parent)
    return window
Brendan Abel
  • 35,343
  • 14
  • 88
  • 118
0

if the window is declared as a Global, it won't get destroyed until the window itself is closed. So you want the reference to the window/widget itself to continue existing somewhere, not necesarily the parent (as mentioned in a previous answer)

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