#!/usr/bin/env python3 # -*- coding: utf-8 -*- ''' PyQt4 conversion of Qt Tutorial 8 In this example, we introduce the first custom widget that can paint itself. We also add a useful keyboard interface (with two lines of code). NOTES: ===== The original example in C++ was split across five files, here they have been combined into one module containing the following classes: LCDRange CannonField MyWidget CannonField has a custom pyqtSignal named 'angleChanged' BEHAVIOUR: ========= The keyboard arrow keys, Home, End, PageUp and PageDown all move the 'angle' widget slider. When the slider is operated, the CannonField displays the new angle value. Upon resizing, CannonField is given as much space as possible. last modified: 2012-01-20 jg ref: http://doc.trolltech.com/3.3/tutorial1-08.html ''' import sys from PyQt4.QtGui import (QApplication, QWidget, QPushButton, QFont, QVBoxLayout, QGridLayout, QLCDNumber, QSlider, QColor, QPainter, QSizePolicy) from PyQt4.QtCore import (Qt, pyqtSlot, pyqtSignal, qWarning) class LCDRange(QWidget): ''' A two digit QLCDNumber and QSlider widget. ''' def __init__(self, parent=None): super(LCDRange, self).__init__(parent) lcd = QLCDNumber(2, self); self.slider = QSlider(Qt.Horizontal, self); self.slider.setRange(0, 99); self.slider.setValue(0); self.slider.valueChanged.connect(lcd.display) layout = QVBoxLayout() layout.addWidget(lcd) layout.addWidget(self.slider) self.setLayout(layout) # set the widget focus to the 'slider' object self.setFocusProxy(self.slider) def value(self): return self.slider.value() @pyqtSlot(int) def setValue(self, value): self.slider.setValue(value) # set the 'slider' range, if min and max values are not # between 0 and 99, print a warning message and leave # the slider values as they were def setRange(self, minVal, maxVal): if (minVal < 0 or maxVal > 99 or minVal > maxVal) : qWarning("LCDRange.setRange({0},{1})\n" "\tRange must be 0..99\n" "\tand minVal must not be greater than maxVal".format(minVal, maxVal)) return self.slider.setRange(minVal, maxVal) class CannonField(QWidget): def __init__(self, parent=None): super(QWidget, self).__init__(parent) self.setObjectName('cannonField') self.ang = 45 # set background colour pal = self.palette() pal.setColor(self.backgroundRole(), QColor(250, 250, 200)) self.setPalette(pal) self.setAutoFillBackground(True) # a custom signal angleChanged = pyqtSignal(int, name="angleChanged") def setAngle(self, degrees): if degrees < 5: degrees = 5 elif degrees > 70: degrees = 70 elif self.ang == degrees: return self.ang = degrees self.repaint() self.angleChanged.emit(self.ang) def paintEvent(self, event): s = "Angle = " + str(self.ang) p = QPainter(self) p.drawText(200, 200, s) def sizePolicy(self): return QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) class MyWidget(QWidget): def __init__(self, parent=None, name=''): super(MyWidget, self).__init__(parent) if name: self.setObjectName(name) quitBtn = QPushButton('Quit', self) quitBtn.setFont(QFont("Times", 18, QFont.Bold)) quitBtn.clicked.connect(QApplication.instance().quit) angle = LCDRange(self) angle.setRange(5, 70) cannonField = CannonField(self) angle.slider.valueChanged.connect(cannonField.setAngle) cannonField.angleChanged.connect(angle.setValue) grid = QGridLayout() grid.addWidget(quitBtn, 0, 0) grid.addWidget(angle, 1, 0, Qt.AlignTop) grid.addWidget(cannonField, 1, 1) grid.setColumnStretch(1, 10) self.setLayout(grid) angle.setValue(60) angle.setFocus() # give the LCDRange object keyboard focus def main(): app = QApplication(sys.argv) # required w = MyWidget() w.setGeometry(100, 100, 500, 355) w.show() sys.exit(app.exec_()) # start main event loop, exit when app closed if __name__ == '__main__': main()
Page List
▼
Sunday, January 22, 2012
Qt Tutorial #1-8 Preparing for Battle
This is from Qt Tutorial #1-8 Preparing for Battle