Python:PyQt 弹出窗口

29

所以我一直在为我的Python应用程序使用Qt创建GUI。现在我遇到了这样一种情况:在按钮被按下后,适当的延迟得到执行,我们执行一些任务,然后我需要打开一个包含一两件事情的单独窗口。但是我似乎无法弄清如何创建此新的单独窗口。是否有人可以给我一个如何创建一个新窗口的例子?

2个回答

55

一个常见的错误是忘记将你创建的弹出窗口的句柄存储在某个 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(...))。这样做将允许你打开多个弹出窗口。

1
不要忘记在第二个窗口或小部件的__init__中添加self.setupUi(self),如果你是使用Designer创建它的话。 - Vicky T

4

通常,您只需使用someQWidget.show()显示多个没有父窗口的窗口,例如:

w1 = QLabel("Window 1")
w2 = QLabel("Window 2")
w1.show()
w2.show()

但是很可能,您想要一个像这个标准对话框。还要确保理解模态对话框


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接