简体   繁体   English

Python:PyQt弹出窗口

[英]Python: PyQt Popup Window

So I've been creating my GUI with Qt for my Python application. 所以我一直用我的Python应用程序用Qt创建我的GUI。 I've now come to a situation where after a button has been pushed the appropriate deferred gets executed, we perform some tasks then I need to open up a separate window that contains one or two things. 我现在遇到这样一种情况:按下按钮后执行适当的延迟执行,我们执行一些任务然后我需要打开一个包含一两件事的单独窗口。 But I can't seem to figure out how to create this new separate window. 但我似乎无法弄清楚如何创建这个新的单独窗口。 Could anyone give me an example of how to create one? 谁能给我一个如何创建一个的例子?

A common error that can drive you crazy is forgetting to store the handle of the popup window you create in some python variable that will remain alive (eg in a data member of the main window). 一个可以让你发疯的常见错误是忘记将你创建的弹出窗口的句柄存储在一些仍然存活的python变量中(例如在主窗口的数据成员中)。

The following is a simple program that creates a main window with a button where pressing the button opens a popup 以下是一个简单的程序,它创建一个带有按钮的主窗口,按下按钮打开一个弹出窗口

#!/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)

What I think can be surprising for Python users and may be is the problem you are facing is the fact that if you don't store a reference to the new widget in the main eg by using w = MyPopup(...) instead of self.w = MyPopup(...) the window apparently doesn't appear (actually it's created and it's immediately destroyed). 我认为对于Python用户来说可能会令人惊讶,并且可能是你面临的问题是如果你没有在主要中存储对新小部件的引用,例如通过使用w = MyPopup(...)而不是self.w = MyPopup(...)窗口显然没有出现(实际上它已经创建并立即被销毁)。

The reason is that when the local variable w goes out of scope as no one is explicitly referencing the widget the widget gets deleted. 原因是当局部变量w超出范围时,因为没有人明确地引用该小部件,所以小部件被删除。 This can be seen clearly because if you press again the button you'll see that as the second popup appears the first one is closed. 这可以清楚地看到,因为如果再次按下按钮,您将看到第二个弹出窗口显示第一个弹出窗口关闭。

This also means that if you need to create several popups you have for example to put them in a python list and you should remove them from this list once the popups are closed by the user. 这也意味着如果你需要创建几个弹出窗口,例如将它们放在python列表中,一旦弹出窗口被用户关闭,你应该从这个列表中删除它们。 The equivalent in the example could be changing to self.w = [] in constructor and then doing self.w.append(MyPopup(...)) . 示例中的等效项可能在构造函数中更改为self.w = [] ,然后执行self.w.append(MyPopup(...)) Doing that would allow you to open several popups. 这样做可以让你打开几个弹出窗口。

Generally, you just show multiple parentless windows with someQWidget.show() , like: 通常,您只需使用someQWidget.show()显示多个无父窗口,例如:

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

But most likely, you want a modal standard Dialog like this . 但最有可能的是,你想要一个像这样的模态标准对话框。 Also be sure to understand modal dialogs . 另外一定要了解模态对话框

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM