A Practical Introduction to PyQt's Undo/Redo Framework
Creating native and good-looking cross-platform applications is just about as easy and pleasant as it can get when you use PyQt (the Python bindings for the Qt application development framework), especially if you design your forms visually using Qt Designer. Using QActions or direct signal-slot connections, you can invoke any callable you like in response to user interaction, such as when the user clicks a button or chooses a menu option.
Here’s a quick reminder of just how simple it all is:
# simple.pyw import sys from PyQt4.QtCore import * from PyQt4.QtGui import * class Form(QDialog): def __init__(self, parent=None): super(Form, self).__init__(parent) self.buttonA = QPushButton("Button &A") self.buttonB = QPushButton("Button &B") self.label = QLabel("No button has been clicked") layout = QVBoxLayout() layout.addWidget(self.buttonA) layout.addWidget(self.buttonB) layout.addWidget(self.label) self.setLayout(layout) self.connect(self.buttonA, SIGNAL("clicked()"), self.pressedA) self.connect(self.buttonB, SIGNAL("clicked()"), self.pressedB) self.setWindowTitle("Simple") def pressedA(self): self.label.setText("Button A clicked") def pressedB(self): self.label.setText("Button B clicked") app = QApplication(sys.argv) form = Form() form.show() app.exec_()
This code produces the application shown in Figure 1. I could have used lambda or partial-function application and connected both buttons to a single method, but that isn’t the concern here.
Figure 1 The simple.pyw application.
This application shows one feature that’s common to many PyQt (and C++/Qt) applications: Each action is connected directly to a method that carries out the action. This is easy to program and maintain. As I’ll show shortly, however, you must take a slightly different approach if you want to provide undo/redo facilities.