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