Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: PyQt Popup Window

Tags:

python

pyqt

So I've been creating my GUI with Qt for my Python application. 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?

like image 794
Morphine Avatar asked Jan 29 '11 19:01

Morphine


1 Answers

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 (e.g. in a data member of the main window).

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 e.g. by using w = MyPopup(...) instead of self.w = MyPopup(...) the window apparently doesn't appear (actually it's created and it's immediately destroyed).

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. 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. The equivalent in the example could be changing to self.w = [] in constructor and then doing self.w.append(MyPopup(...)). Doing that would allow you to open several popups.

like image 168
6502 Avatar answered Oct 05 '22 23:10

6502