7

for the life of me I can't figure this out... on a button press I have the code:

@QtCore.pyqtSlot():
def buttonPressed(self):
    d = QtGui.QDialog()
    d.show()

all that happens is a window briefly pops up without any contents and then disappears. Hitting the button repeatedly doesn't help.

Using Python 2.6, latest PyQt4.

Claudiu
  • 224,032
  • 165
  • 485
  • 680

2 Answers2

8

If I am not mistaken, it seems that someone else had a similar issue. What seems to be happening is that you define a local variable d and initialize it as a QDialog, then show it. The problem is that once the buttonPressed handler is finished executing, the reference to d goes out of scope, and so it is destroyed by the garbage collector. Try doing something like self.d = QtGui.QDialog() to keep it in scope.

voithos
  • 68,482
  • 12
  • 101
  • 116
  • ah yea i just realized this.. i don't understand why they would do it that way if you ask me.. well i do on some level but i feel that since QT has a reference to it anyway (it has to to display it, right?) it should keep it around until 'cancel' is clicked or whatever. – Claudiu May 03 '11 at 19:18
  • I'm not quite sure how QT references it, although yes, I would expect that it would keep some sort of handle to the object. I wonder if `QtGui.QDialog().show()` is valid... If so, then I would think that there would be no local variable and perhaps the garbage collector would leave it alone. I have a feeling that I'm being optimistic, though. – voithos May 03 '11 at 19:44
  • no i doubt that would work =P. it would get GC'ed even faster. – Claudiu May 03 '11 at 19:45
  • Fair enough. In this case, I think the garbage collector is just doing its job superbly well. If it had left the dialog alone, it would become orphaned as soon as you went out of scope. – voithos May 03 '11 at 19:51
5

You should pass a parent to the dialog when you created it like this:

@QtCore.pyqtSlot():
def buttonPressed(self):
    d = QtGui.QDialog(self)
    d.show()

This will keep the reference to the QDialog object, keeping it in scope. It also allows proper behavior of the Dialog if you are passing the appropriate QMainWindow, etc. as the parent.

Andrew Ring
  • 3,185
  • 1
  • 23
  • 28
  • I know this is an old thread, but this is very much the correct answer and should be the accepted answer. `QDialog` (which any dialog inherits from) takes a `parent` as a parameter in its `__init__`. By passing your window as the parent, your dialog isn't killed. – delrocco Oct 11 '18 at 01:26