#!/usr/bin/env python3 # -*- coding: utf-8 -*- ''' PyQt4 conversion of Qt Tutorial 9 In this example we become graphic by drawing a cute little blue cannon. The only differences from 108_battle.pyw are: 1. Added a short-cut key to the Quit button (In Windows, you have to press ALT to make the short-cut visible) 2. re-written paintEvent() method in the CannonField class to draw the cannon 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 BEHAVIOUR: ========= When the slider is operated the angle of the drawn cannon changes accordingly. The Q on the Quit button is now underlined, and Alt+Q does what you think it does. last modified: 2012-01-20 jg ref: http://doc.trolltech.com/3.3/tutorial1-09.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, QRect) 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): p = QPainter(self) p.setBrush(Qt.blue) # brush colour for filling object p.setPen(Qt.NoPen) # no special edges # set QPainter's origin (0,0) coords to the bottom-left p.translate(self.rect().bottomLeft()) # draw a quarter circle in the bottom left corner p.drawPie(QRect(-35, -35, 70, 70), 0, 90 * 16) # rotate counter-clockwise 'ang' degrees around the origin # and draw the cannon's barrel p.rotate(-self.ang) p.drawRect(QRect(33, -4, 15, 8)) 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()
Sunday, January 22, 2012
Qt Tutorial #1-9 With Cannon You Can
This is from Qt Tutorial #1-9 With Cannon You Can
Labels:
Qt Tutorial 1