pyqt4: как отобразить немодальный диалог?

#python #qt #qt4 #pyqt #pyqt4

#python #qt #qt4 #pyqt #pyqt4

Вопрос:

хоть убей, я не могу в этом разобраться … при нажатии кнопки у меня есть код:

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

все, что происходит, — это окно, которое на короткое время появляется без какого-либо содержимого, а затем исчезает. Повторное нажатие кнопки не помогает.

Используется Python 2.6, последняя версия PyQt4.

Комментарии:

1. не могли бы вы попробовать d.exec_() вместо show?

2. @utdmr: да, и это правильно отобразило бы модальный диалог.

Ответ №1:

Если я не ошибаюсь, похоже, что у кого-то еще была похожая проблема. Похоже, что происходит то, что вы определяете локальную переменную d и инициализируете ее как QDialog , затем показываете ее. Проблема в том, что как только buttonPressed обработчик завершает выполнение, ссылка на d выходит за пределы области видимости, и поэтому она уничтожается сборщиком мусора. Попробуйте сделать что-то вроде self.d = QtGui.QDialog() , чтобы сохранить его в области видимости.

Комментарии:

1. ах да, я только что понял это .. я не понимаю, почему они сделали бы это таким образом, если вы спросите меня .. ну, я делаю на каком-то уровне, но я чувствую, что, поскольку QT в любом случае имеет ссылку на него (он должен отображать его, верно?), он должен сохранять его до тех пор, пока не будет нажата кнопка «Отмена» или что-то еще.

2. Я не совсем уверен, как QT ссылается на это, хотя да, я ожидал бы, что он сохранит какой-то дескриптор объекта. Интересно, QtGui.QDialog().show() допустимо ли… Если это так, то я бы подумал, что локальной переменной не будет и, возможно, сборщик мусора оставит ее в покое. Однако у меня такое чувство, что я настроен оптимистично.

3. нет, я сомневаюсь, что это сработало бы = P. это привело бы к GC’ed еще быстрее.

4. Достаточно справедливо. В этом случае, я думаю, сборщик мусора просто великолепно выполняет свою работу. Если бы он оставил диалог в покое, он стал бы осиротевшим, как только вы вышли за пределы области видимости.

Ответ №2:

Вы должны передать родительский элемент в диалоговое окно, когда вы создали его следующим образом:

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

Это сохранит ссылку на объект QDialog, сохраняя его в области видимости. Это также обеспечивает правильное поведение диалога, если вы передаете соответствующий QMainWindow и т.д. В качестве родительского.

Комментарии:

1. Я знаю, что это старая тема, но это очень правильный ответ, и он должен быть принятым ответом. QDialog (от которого наследуется любой диалог) принимает parent в качестве параметра в своем __init__ . Передавая ваше окно в качестве родительского, ваш диалог не прерывается.