#!/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()
Sunday, January 22, 2012
Qt Tutorial #1-8 Preparing for Battle
This is from Qt Tutorial #1-8 Preparing for Battle
Labels:
Qt Tutorial 1