Распространенная ошибка, которая может свести вас с ума, - забыть сохранить дескриптор всплывающего окна, которое вы создаете, в некоторой переменной python, которая останется активной (например, в элементе данных главного окна).
Ниже приведена простая программа, которая создает главное окно с кнопкой, при нажатии которой открывается всплывающее окно
#!/usr/bin/env python
#-*- coding: utf-8 -*-
import sys
from PyQt4.Qt import *
class MyPopup(QWidget):
def __init__(self):
QWidget.__init__(self)
def paintEvent(self, e):
dc = QPainter(self)
dc.drawLine(0, 0, 100, 100)
dc.drawLine(100, 0, 0, 100)
class MainWindow(QMainWindow):
def __init__(self, *args):
QMainWindow.__init__(self, *args)
self.cw = QWidget(self)
self.setCentralWidget(self.cw)
self.btn1 = QPushButton("Click me", self.cw)
self.btn1.setGeometry(QRect(0, 0, 100, 30))
self.connect(self.btn1, SIGNAL("clicked()"), self.doit)
self.w = None
def doit(self):
print "Opening a new popup window..."
self.w = MyPopup()
self.w.setGeometry(QRect(100, 100, 400, 200))
self.w.show()
class App(QApplication):
def __init__(self, *args):
QApplication.__init__(self, *args)
self.main = MainWindow()
self.connect(self, SIGNAL("lastWindowClosed()"), self.byebye )
self.main.show()
def byebye( self ):
self.exit(0)
def main(args):
global app
app = App(args)
app.exec_()
if __name__ == "__main__":
main(sys.argv)
. Что я думаю, может удивить пользователей Python и может быть проблема, с которой вы сталкиваетесь, заключается в том, чточто если вы не сохраните ссылку на новый виджет в главном, например, с помощью w = MyPopup(...)
вместо self.w = MyPopup(...)
, то окно, по-видимому, не появится (на самом деле оно создано и сразу же уничтожено).
Причина в том, что когда локальная переменная w
выходит из области видимости, поскольку никто явно не ссылается на виджет, виджет удаляется.Это хорошо видно, потому что если вы снова нажмете кнопку, вы увидите, что при появлении второго всплывающего окна первое закрывается.
Это также означает, что если вам нужно создать несколько всплывающих окон, например, нужнопоместите их в список Python, и вы должны удалить их из этого списка, как только пользователь закроет всплывающие окна.Эквивалентом в примере может быть изменение в конструкторе self.w = []
, а затем выполнение self.w.append(MyPopup(...))
.Это позволит вам открыть несколько всплывающих окон.