Upload
alex
View
261
Download
3
Embed Size (px)
Citation preview
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 1/69
ntroduction to PyQt4 toolkit
About this tutorial
This is an introductory PyQt4 tutorial. The purpose of this tutorial is to get
you started with the PyQt4 toolkit. The tutorial has been created and tested on
Linux.
About PyQt
PyQt is a toolkit for creating GI applications. It is a blending of python
progra!!ing language and the successfull Qt library. Qt library is one of the
!ost powerful libraries on this planet. If not the !ost powerful. The official
ho!e site for PyQt is on www.ri"erbankco!puting.co.uk It was de"eloped byPhil
Tho!pson
.
PyQt is i!ple!ented as a set of python !odules. It has o"er #$$ classes and
al!ost %$$$ functions and !ethods. It is a !ultiplatfor! toolkit. It runs on all
!a&or operating syste!s. Including nix' (indows and )ac. PyQt is dual licenced.
*e"elopers can choose between GPL and co!!ercial licence. Pre"iously' GPL
"ersion was a"ailable only on nix. +tarting fro! PyQt "ersion 4' GPL licence is
a"ailable on all supported platfor!s.
,ecause there are a lot of classes a"ailable' they ha"e been di"ided into
se"eral !odules.
-igure PyQt4 )odules
TheQt/ore
!odule contains the core non0gui functionality. This !odule is used
for working with ti!e' files and directories' "arious data types' strea!s' urls'
!i!e types' threads or processes. TheQtGui
!odule contains the graphical
co!ponents and related classes. These include for exa!ple buttons' windows'status bars' toolbars' sliders' bit!aps' colors' fonts etc. The
Qt1etwork
!odule contains the classes for network progra!!ing. These classes allow to
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 2/69
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 3/69
Python is currently nu!ber . The :uby language has !ade into the toplist. The
closest co!petitors to Python are :uby and Perl.
Python toolkits
-or creating graphical user interfaces' python progra!!ers can choose a!ong
three decent options. PyGTH' wxPython and PyQt. (hich toolkit to choose' depends
on the circu!stances. There is also another option' called TkInter. A"oid.
-irst progra!s in PyQt4 toolkit
In this part of the PyQt4 tutorial we will learn so!e basic functionality. The
explanation will be slow' as if we would talk to a child. The first steps of a
child are awkward' so are the "ery first atte!pts of a newbie progra!!er.:e!e!ber' there are no stupid people. There are only laCy people and people'
that are not persistent enough.
+i!ple exa!ple
The code exa!ple is "ery si!plistic. It only shows a s!all window. Jet we can do
a lot with this window. (e can resiCe it. )axi!iCe it. )ini!iCe it. This
re9uires a lot of coding. +o!eone already coded this functionality. ,ecause it
repeats in !ost applications' there is no need to code it o"er again +o it has
been hidden fro! a progra!!er. PyQt is a high le"el toolkit. If we would code in
a lower le"el toolkit' the following code exa!ple could easily ha"e doCens of
lines.
#!/usr/bin/python
# simple.py
import sysfrom PyQt4 import QtGui
app = QtGui.QApplication(sys.argv
i"get = QtGui.Qi"get(i"get.resi$e(%&' )&'i"get.setin"o*itle(+simple+i"get.sho(
sys.e,it(app.e,ec-(
import sys from PyQt4 import QtGui
=ere we pro"ide the necessary i!ports. The basic GI widgets are located in
QtGui !odule.
app = QtGui.QApplication(sys.argv
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 4/69
@"ery PyQt4 application !ust create an application ob&ect. The application
ob&ect is located in the QtGui !odule. The sys.arg" para!eter is a list of
argu!ents fro! the co!!and line. Python scripts can be run fro! the shell. It is
a way' how we can control the startup of our scripts.
i"get = QtGui.Qi"get(
The Q(idget widget is the base class of all user interface ob&ects in PyQt4. (e
pro"ide the default constructor for Q(idget. The default constructor has no
parent. A widget with no parent is called a window.
i"get.resi$e(%&' )&'
The resiCe67 !ethod resiCes the widget. It is 8?$px wide and ;?$px high.
i"get.setin"o*itle(+simple+
=ere we set the title for our window. The title is shown in the titlebar.i"get.sho(
The show67 !ethod displays the widget on the screen.
sys.e,it(app.e,ec-(
-inally' we enter the !ainloop of the application. The e"ent handling starts
fro! this point. The !ainloop recei"es e"ents fro! the window syste! and
dispatches the! to the application widgets. The !ainloop ends' if we call the
exit67 !ethod or the !ain widget is destroyed. The sys.exit67 !ethod ensures a
clean exit. The en"iron!ent will be infor!ed' how the application ended.
Jou wonder why the execK67 !ethod has the underscore @"erything has a !eaning.
This is ob"iously because the exec is a python keyword. And thus' execK67 was
used instead.
-igure +i!ple
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 5/69
An application icon
The application icon is a s!all i!age' which is usually displayed in the top
left corner of the titlebar. In the following exa!ple we will show' how we do it
in PyQt4. (e will also introduce so!e new !ethods.
#!/usr/bin/python
# icon.py
import sysfrom PyQt4 import QtGui
class con(QtGui.Qi"get "ef --init--(self parent=0one QtGui.Qi"get.--init--(self parent
self.setGeometry(1'' 1'' %&' )&'
self.setin"o*itle(+con+ self.setin"ocon(QtGui.Qcon(+icons/eb.png+
app = QtGui.QApplication(sys.argvicon = con(icon.sho(sys.e,it(app.e,ec-(
The pre"ious exa!ple was coded in a procedural style. Python progra!!ing
language supports both procedural and ob&ect oriented progra!!ing styles.
Progra!!ing in PyQt4 !eans progra!!ing in P.
class con(QtGui.Qi"get "ef --init--(self parent=0one QtGui.Qi"get.--init--(self parent
The three !ost i!portant things in ob&ect oriented progra!!ing are classes' data
and !ethods. =ere we create a new class called Icon. The Icon class inherits
fro! QtGui.Q(idget class. This !eans' that we !ust call two constructors. The
first one for the Icon class and the second one for the inherited class.
self.setGeometry(1'' 1'' %&' )&'
self.setin"o*itle(+con+ self.setin"ocon(QtGui.Qcon(+icons/eb.png+
All three classes ha"e been inherited fro! the QtGui.Q(idget class. The
setGeo!etry67 does two things. It locates the window on the screen and sets the
siCe of the window. The first two para!eters are the x and y positions of the
window. The third is the width and the fourth is the height of the window. The
last !ethod sets the application icon. To do this' we ha"e created a QIcon
ob&ect. The QIcon recei"es the path to our icon to be displayed.
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 6/69
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 7/69
-igure Tooltip
/losing a window
The ob"ious way to how to close a window is to click on the x !ark on the
titlebar. In the next exa!ple' we will show' how we can progra!atically closeour window. (e will briefly touch signals and slots.
The following is the constructor of a QPush,utton' that we will use in our
exa!ple.
QPush8utton(string te,t Qi"get parent = 0one
The text para!eter is a text that will be displayed on the button. The parent is
the ancestor' onto which we place our button. In our case it is Q(idget.
#!/usr/bin/python
# 9uitbutton.py
import sysfrom PyQt4 import QtGui Qt2ore
class Quit8utton(QtGui.Qi"get "ef --init--(self parent=0one QtGui.Qi"get.--init--(self parent
self.setGeometry(1'' 1'' %&' )&' self.setin"o*itle(+con+
9uit = QtGui.QPush8utton(+2lose+ self 9uit.setGeometry()' )' :' 1&
self.connect(9uit Qt2ore.;G0A<(+clice"(+ QtGui.9App Qt2ore.;<6*(+9uit(+
app = QtGui.QApplication(sys.argv9b = Quit8utton(9b.sho(sys.e,it(app.e,ec-(
9uit = QtGui.QPush8utton(+2lose+ self 9uit.setGeometry()' )' :' 1&
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 8/69
(e create a push button and position it on the Q(idget &ust like we ha"e
positioned the Q(idget on the screen.
self.connect(9uit Qt2ore.;G0A<(+clice"(+ QtGui.9App Qt2ore.;<6*(+9uit(+
The e"ent processing syste! in PyQt4 is built with the signal M slot !echanis!.If we click on the button' the signal clicked67 is e!itted. The slot can be a
PyQt slot or any python callable. The Qt/ore.Q4b&ect.connect67 !ethod connects
signals with slots. In our case the slot is a predefined PyQt 9uit67 slot. The
co!!unication is done between two ob&ects. The sender and the recei"er. The
sender is the push button' the recei"er is the application ob&ect.
-igure 9uit button
)essage ,ox
,y default' if we click on the x button on the titlebar' the Q(idget is closed.
+o!eti!es we want to !odify this default beha"iour. -or exa!ple' if we ha"e a
file opened in an editor to which we did so!e changes. (e show a !essage box to
confir! the action.
#!/usr/bin/python
# messagebo,.py
import sysfrom PyQt4 import QtGui
class >essage8o,(QtGui.Qi"get "ef --init--(self parent=0one QtGui.Qi"get.--init--(self parent
self.setGeometry(1'' 1'' %&' )&' self.setin"o*itle(+message bo,+
"ef close7vent(self event
reply = QtGui.Q>essage8o,.9uestion(self +>essage+ ?Are you sure to 9uit@? QtGui.Q>essage8o,.esQtGui.Q>essage8o,.0o
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 9/69
if reply == QtGui.Q>essage8o,.es event.accept( else event.ignore(
app = QtGui.QApplication(sys.argv
9b = >essage8o,(9b.sho(sys.e,it(app.e,ec-(
If we close the Q(idget' the Q/lose@"ent is generated. To !odify the widget
beha"iour we need to rei!ple!ent the close@"ent67 e"ent handler.
reply = QtGui.Q>essage8o,.9uestion(self +>essage+ ?Are you sure to 9uit@? QtGui.Q>essage8o,.es QtGui.Q>essage8o,.0o
(e show a !essage box with two buttons. Jes and 1o. The first string appears on
the titlebar. The second string is the !essage text displayed by the dialog. The
return "alue is stored in the reply "ariable.
if reply == QtGui.Q>essage8o,.es event.accept( else event.ignore(
=ere we test the return "alue. If we clicked Jes button' we accept the e"ent
which leads to the closure of the widget and to the ter!ination of the
application. therwise we ignore the close e"ent.
-igure !essage box
/entering window on the screen
The following script shows' how we can center a window on the desktop screen.
#!/usr/bin/python
# center.py
import sysfrom PyQt4 import QtGui
class 2enter(QtGui.Qi"get "ef --init--(self parent=0one QtGui.Qi"get.--init--(self parent
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 10/69
self.setin"o*itle(+center+ self.resi$e(%&' )&' self.center(
"ef center(self screen = QtGui.QBestopi"get(.screenGeometry(
si$e = self.geometry( self.move((screen.i"th(Csi$e.i"th(/% (screen.height(Csi$e.height(/%
app = QtGui.QApplication(sys.argv9b = 2enter(9b.sho(sys.e,it(app.e,ec-(
self.resi$e(%&' )&'
=ere we resiCe the Q(idget to be 8?$px wide and ;?$px heigh.screen = QtGui.QBestopi"get(.screenGeometry(
(e figure out the screen resolution of our !onitor.
si$e = self.geometry(
=ere we get the siCe of our Q(idget.
self.move((screen.i"th(Csi$e.i"th(/% (screen.height(Csi$e.height(/%
=ere we !o"e the window to the center of the screen.
)enus and Toolbars in PyQt4
)ain (indow
The Q)ain(indow class pro"ides a !ain application window. This enables to create
the classic application skeleton with a statusbar' toolbars and a !enubar.
+tatusbar
The statusbar is a widget that si used for displaying status infor!ation.
#!/usr/bin/python
# statusbar.py
import sysfrom PyQt4 import QtGui
class >ainin"o(QtGui.Q>ainin"o "ef --init--(self QtGui.Q>ainin"o.--init--(self
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 11/69
self.resi$e(%&' )&' self.setin"o*itle(+statusbar+
self.status8ar(.sho>essage(+Dea"y+
app = QtGui.QApplication(sys.argvmain = >ainin"o(main.sho(sys.e,it(app.e,ec-(
self.status8ar(.sho>essage(+Dea"y+
To get the statusbar' we call the status,ar67 !ethod of the QApplication class.
The show)essage67 displays !essage on the statusbar.
)enubar
A !enubar is one of the !ost "isible parts of the GI application. It is a group
of co!!ands located in "arious !enus. (hile in console applications you had to
re!e!ber all those arcane co!!ands' here we ha"e !ost of the co!!ands grouped
into logical parts. There are accepted standards that further reduce the a!ount
of ti!e spending to learn a new application.
#!/usr/bin/python
# menubar.py
import sysfrom PyQt4 import QtGui Qt2ore
class >ainin"o(QtGui.Q>ainin"o "ef --init--(self QtGui.Q>ainin"o.--init--(self
self.resi$e(%&' )&' self.setin"o*itle(+menubar+
e,it = QtGui.QAction(QtGui.Qcon(+icons/e,it.png+ +7,it+ self
e,it.set;hortcut(+2trlEQ+ e,it.set;tatus*ip(+7,it application+ self.connect(e,it Qt2ore.;G0A<(+triggere"(+ Qt2ore.;<6*(+close(+
self.status8ar(
menubar = self.menu8ar( file = menubar.a"">enu(+F5ile+ file.a""Action(e,it
app = QtGui.QApplication(sys.argvmain = >ainin"o(main.sho(
sys.e,it(app.e,ec-(
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 12/69
menubar = self.menu8ar( file = menubar.a"">enu(+F5ile+ file.a""Action(e,it
-irst we create a !enubar with the !enu,ar67 !ethod of the Q)ain(indow class.
Then we add a !enu with the Add)enu67 !ethod. In the end we plug the action
ob&ect into the file !enu.
Toolbar
)enus group all co!!ands that we can use in an application. Toolbars pro"ide a
9uick access to the !ost fre9uently used co!!ands.
#!/usr/bin/python
# toolbar.py
import sysfrom PyQt4 import QtGui Qt2ore
class >ainin"o(QtGui.Q>ainin"o "ef --init--(self QtGui.Q>ainin"o.--init--(self
self.resi$e(%&' )&' self.setin"o*itle(+toolbar+
self.e,it = QtGui.QAction(QtGui.Qcon(+icons/e,it.png+ +7,it+ self self.e,it.set;hortcut(+2trlEQ+ self.connect(self.e,it Qt2ore.;G0A<(+triggere"(+
Qt2ore.;<6*(+close(+
self.toolbar = self.a""*ool8ar(+7,it+ self.toolbar.a""Action(self.e,it
app = QtGui.QApplication(sys.argvmain = >ainin"o(main.sho(sys.e,it(app.e,ec-(
self.e,it = QtGui.QAction(QtGui.Qcon(+icons/e,it.png+ +7,it+ self self.e,it.set;hortcut(+2trlEQ+
GI applications are controlled with co!!ands. These co!!ands can be launched
fro! a !enu' a context !enu' a toolbar or with a shortcut. PyQt si!plifies
de"elop!ent with the introduction ofactions
. An action ob&ect can ha"e !enu
text' an icon' a shortcut' status text' (hat>s This text and a tooltip. In
our exa!ple' we define an action ob&ect with an icon' a tooltip and a shortcut.
self.connect(self.e,it Qt2ore.;G0A<(+triggere"(+ Qt2ore.;<6*(+close(+
=ere we connect the action>s triggered67 signal to the predefined close67
signal.self.toolbar = self.a""*ool8ar(+7,it+
self.toolbar.a""Action(self.e,it
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 13/69
=ere we create a toolbar and plug and action ob&ect into it.
-igure toolbar
Putting it together
In the last exa!ple of this section' we will create a !enubar' toolbar and a
statusbar. (e will also create a central widget.
#!/usr/bin/python
# mainin"o.py
import sysfrom PyQt4 import QtGui Qt2ore
class >ainin"o(QtGui.Q>ainin"o "ef --init--(self QtGui.Q>ainin"o.--init--(self
self.resi$e(1&' %&' self.setin"o*itle(+mainin"o+
te,t7"it = QtGui.Q*e,t7"it( self.set2entrali"get(te,t7"it
e,it = QtGui.QAction(QtGui.Qcon(+icons/e,it.png+ +7,it+ self e,it.set;hortcut(+2trlEQ+ e,it.set;tatus*ip(+7,it application+
self.connect(e,it Qt2ore.;G0A<(+triggere"(+ Qt2ore.;<6*(+close(+
self.status8ar(
menubar = self.menu8ar( file = menubar.a"">enu(+F5ile+ file.a""Action(e,it
toolbar = self.a""*ool8ar(+7,it+ toolbar.a""Action(e,it
app = QtGui.QApplication(sys.argv
main = >ainin"o(main.sho(sys.e,it(app.e,ec-(
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 14/69
te,t7"it = QtGui.Q*e,t7"it( self.set2entrali"get(te,t7"it
=ere we create a text edit widget. (e set it to be the central widget of the
Q)ain(indow . The central widget will occupy all space that is left.
-igure !ainwindow
Layout !anage!ent in PyQt4
I!portant thing in progra!!ing is the layout !anage!ent. Layout !anage!ent is
the way how we place the widgets on the window. The !anage!ent can be done in
two ways. (e can useabsolute positioning
orlayout classes
.
Absolute positioning
The progra!!er specifies the position and the siCe of each widget in pixels.(hen you use absolute positioning' you ha"e to understand se"eral things.
• the siCe and the position of a widget do not change' if you resiCe a
window
• applications !ight look different on "arious platfor!s
• changing fonts in your application !ight spoil the layout
• if you decide to change your layout' you !ust co!pletely redo your layout'
which is tedious and ti!e consu!ing
#!/usr/bin/python
# absolute.py
import sys
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 15/69
from PyQt4 import QtGui
class Absolute(QtGui.Qi"get "ef --init--(self parent=0one QtGui.Qi"get.--init--(self parent
self.setin"o*itle(+2ommunication+
label = QtGui.Q<abel(+2oul"n+t+ self label.move()& )'
label = QtGui.Q<abel(+care+ self label.move(1& 4'
label = QtGui.Q<abel(+less+ self label.move(&& :&
label = QtGui.Q<abel(+An"+ self label.move())& :&
label = QtGui.Q<abel(+then+ self label.move()1& 4&
label = QtGui.Q<abel(+you+ self label.move())& %&
label = QtGui.Q<abel(+isse"+ self label.move()4& )'
label = QtGui.Q<abel(+me+ self label.move(%)& )'
self.resi$e(%&' )&'
app = QtGui.QApplication(sys.argv9b = Absolute(9b.sho(sys.e,it(app.e,ec-(
(e si!ply call the !o"e67 !ethod to position our widgets. In our case QLabel0s.
(e position the! by pro"iding the x and the y coordinates. The beginning of the
coordinate syste! is at the left top corner. The x "alues grow fro! left to
right. The y "alues grow fro! top to botto!.
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 16/69
-igure absolute positioning
,ox Layout
Layout !anage!ent with layout classes is !uch !ore flexible and practical. It is
the preferred way to place widgets on a window. The basic layout classes are
Q=,oxLayout
andQ5,oxLayout
. They line up widgets horiContally and
"ertically.
I!agine that we wanted to place two buttons in the right botto! corner. To
create such a layout' we will use one horiContal and one "ertical box. To create
the neccessary space' we will add astretch factor
.
#!/usr/bin/python
# bo,layout.py
import sysfrom PyQt4 import QtGui
class 8o,<ayout(QtGui.Qi"get "ef --init--(self parent=0one QtGui.Qi"get.--init--(self parent
self.setin"o*itle(+bo, layout+
o = QtGui.QPush8utton(?6H? cancel = QtGui.QPush8utton(?2ancel?
hbo, = QtGui.QI8o,<ayout( hbo,.a"";tretch() hbo,.a""i"get(o hbo,.a""i"get(cancel
vbo, = QtGui.QJ8o,<ayout( vbo,.a"";tretch() vbo,.a""<ayout(hbo,
self.set<ayout(vbo,
self.resi$e(1'' )&'
app = QtGui.QApplication(sys.argv9b = 8o,<ayout(9b.sho(sys.e,it(app.e,ec-(
o = QtGui.QPush8utton(?6H? cancel = QtGui.QPush8utton(?2ancel?
=ere we create two push buttons.
hbo, = QtGui.QI8o,<ayout( hbo,.a"";tretch()
hbo,.a""i"get(o hbo,.a""i"get(cancel
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 17/69
(e create a horiContal box layout. Add a stretch factor and both buttons.
vbo, = QtGui.QJ8o,<ayout( vbo,.a"";tretch() vbo,.a""<ayout(hbo,
To create the necessary layout' we put a horiContal lauout into a "ertical one.
self.set<ayout(vbo,
-inally' we set the !ain layout of the window.
-igure box layout
QGridLayout
The !ost uni"ersal layout class is the grid layout. This layout di"ides thespace into rows and colu!ns. To create a grid layout' we use the
QGridLayout
class.
#!/usr/bin/python
# gri"layout.py
import sysfrom PyQt4 import QtGui
class Gri"<ayout(QtGui.Qi"get
"ef --init--(self parent=0one QtGui.Qi"get.--init--(self parent
self.setin"o*itle(+gri" layout+
names = K+2ls+ +8c+ ++ +2lose+ +L+ +M+ +N+ +/+ +4+ +&+ +:+ +O+ +)+ +%+ +1+ +C+ +'+ +.+ +=+ +E+
gri" = QtGui.QGri"<ayout(
= ' pos = K(' ' (' ) (' % (' 1 () ' () ) () % () 1 (% ' (% ) (% % (% 1 (1 ' (1 ) (1 % (1 1
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 18/69
(4 ' (4 ) (4 % (4 1
for i in names button = QtGui.QPush8utton(i if == % gri".a""i"get(QtGui.Q<abel(++ ' % else gri".a""i"get(button posKK' posKK)
= E )
self.set<ayout(gri"
app = QtGui.QApplication(sys.argv9b = Gri"<ayout(9b.sho(sys.e,it(app.e,ec-(
In our exa!ple' we create a grid of buttons. To fill one gap' we add one QLabel
widget.
gri" = QtGui.QGri"<ayout(
=ere we create a grid layout.
if == % gri".a""i"get(QtGui.Q<abel(++ ' % else gri".a""i"get(button posKK' posKK)
To add a widget to a grid' we call the add(idget67 !ethod. The argu!ents are the
widget' the row and the colu!n nu!ber.
-igure grid layout
(idgets can span !ultiple colu!ns or rows in a grid. In the next exa!ple we
illustrate this.#!/usr/bin/python
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 19/69
# gri"layout%.py
import sysfrom PyQt4 import QtGui
class Gri"<ayout%(QtGui.Qi"get
"ef --init--(self parent=0one QtGui.Qi"get.--init--(self parent
self.setin"o*itle(+gri" layout+
title = QtGui.Q<abel(+*itle+ author = QtGui.Q<abel(+Author+ revie = QtGui.Q<abel(+Devie+
title7"it = QtGui.Q<ine7"it( author7"it = QtGui.Q<ine7"it( revie7"it = QtGui.Q*e,t7"it(
gri" = QtGui.QGri"<ayout( gri".set;pacing()'
gri".a""i"get(title ) ' gri".a""i"get(title7"it ) )
gri".a""i"get(author % ' gri".a""i"get(author7"it % )
gri".a""i"get(revie 1 ' gri".a""i"get(revie7"it 1 ) & )
self.set<ayout(gri" self.resi$e(1&' 1''
app = QtGui.QApplication(sys.argv9b = Gri"<ayout%(9b.sho(sys.e,it(app.e,ec-(
gri" = QtGui.QGri"<ayout( gri".set;pacing()'
(e create a grid layout and set spacing between widgets.
gri".a""i"get(revie7"it 1 ) & )
If we add a widget to a grid' we can pro"ide row span and colu!n span of the
widget. In our case' we !ake the re"iew@dit widget span ? rows.
@"ents and +ignals in PyQt4
In this part of the PyQt4 progra!!ing tutorial' we will explore e"ents and
singnals occuring in applications.
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 20/69
@"ents
@"ents are an i!portant part in any GI progra!. @"ents are generated by users
or by the syste!. (hen we call the application>s execK67 !ethod' the application
enters the !ain loop. The !ain loop fetches e"ents and sends the! to the
ob&ects. Trolltech has introduced a uni9ue signal and slot !echanis!.
+ignals M +lots
+ignals are e!itted' when users click on the button' drag a slider etc. +ignals
can be e!itted also by the en"iron!ent. -or exa!ple' when a clock ticks. A slot
is a !ethod' that reacts to a signal. In python' a slot can be any python
callable.
#!/usr/bin/python
# sigslot.py
import sysfrom PyQt4 import QtGui Qt2ore
class ;ig;lot(QtGui.Qi"get "ef --init--(self parent=0one QtGui.Qi"get.--init--(self parent
self.setin"o*itle(+signal F slot+
lc" = QtGui.Q<2B0umber(self
sli"er = QtGui.Q;li"er(Qt2ore.Qt.Iori$ontal self
vbo, = QtGui.QJ8o,<ayout( vbo,.a""i"get(lc" vbo,.a""i"get(sli"er
self.set<ayout(vbo, self.connect(sli"er Qt2ore.;G0A<(+value2hange"(int+ lc"
Qt2ore.;<6*(+"isplay(int+
self.resi$e(%&' )&'
app = QtGui.QApplication(sys.argv9b = ;ig;lot(9b.sho(sys.e,it(app.e,ec-(
In our exa!ple' we display an lcd nu!ber and a slider. (e change the lcd nu!ber
by dragging the slider.
self.connect(sli"er Qt2ore.;G0A<(+value2hange"(int+ lc"Qt2ore.;<6*(+"isplay(int+
=ere we connect a "alue/hanged67 signal of the slider to the display67 slot of
the lcd nu!ber.
The connect !ethod has four para!eters. Thesender
is an ob&ect that sends a
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 21/69
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 22/69
@!itting signals
b&ects created fro! Qt/ore.Q4b&ect can e!it signals. If we click on the button'
a clicked67 signal is generated. In the following exa!ple we will see' how we
can e!it signals.
#!/usr/bin/python
# emit.py
import sysfrom PyQt4 import QtGui Qt2ore
class 7mit(QtGui.Qi"get "ef --init--(self parent=0one QtGui.Qi"get.--init--(self parent
self.setin"o*itle(+emit+
self.resi$e(%&' )&' self.connect(self Qt2ore.;G0A<(+close7mitApp(+Qt2ore.;<6*(+close(+
"ef mousePress7vent(self event self.emit(Qt2ore.;G0A<(+close7mitApp(+
app = QtGui.QApplication(sys.argv9b = 7mit(9b.sho(sys.e,it(app.e,ec-(
(e create a new signal called close@!itApp67. This signal is e!itted' during a!ouse press e"ent.
"ef mousePress7vent(self event self.emit(Qt2ore.;G0A<(+close7mitApp(+
@!itting a signal with the e!it67 !ethod.
self.connect(self Qt2ore.;G0A<(+close7mitApp(+ Qt2ore.;<6*(+close(+
=ere we connect the !anually created close@!itApp67 signal with the close67
slot.
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 23/69
-igure grid layout8
@"ents and +ignals in PyQt4
In this part of the PyQt4 progra!!ing tutorial' we will explore e"ents and
singnals occuring in applications.
@"ents
@"ents are an i!portant part in any GI progra!. @"ents are generated by users
or by the syste!. (hen we call the application>s execK67 !ethod' the application
enters the !ain loop. The !ain loop fetches e"ents and sends the! to the
ob&ects. Trolltech has introduced a uni9ue signal and slot !echanis!.
+ignals M +lots
+ignals are e!itted' when users click on the button' drag a slider etc. +ignals
can be e!itted also by the en"iron!ent. -or exa!ple' when a clock ticks. A slot
is a !ethod' that reacts to a signal. In python' a slot can be any python
callable.
#!/usr/bin/python
# sigslot.py
import sysfrom PyQt4 import QtGui Qt2ore
class ;ig;lot(QtGui.Qi"get "ef --init--(self parent=0one
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 24/69
QtGui.Qi"get.--init--(self parent
self.setin"o*itle(+signal F slot+
lc" = QtGui.Q<2B0umber(self sli"er = QtGui.Q;li"er(Qt2ore.Qt.Iori$ontal self
vbo, = QtGui.QJ8o,<ayout( vbo,.a""i"get(lc" vbo,.a""i"get(sli"er
self.set<ayout(vbo, self.connect(sli"er Qt2ore.;G0A<(+value2hange"(int+ lc"
Qt2ore.;<6*(+"isplay(int+
self.resi$e(%&' )&'
app = QtGui.QApplication(sys.argv9b = ;ig;lot(
9b.sho(sys.e,it(app.e,ec-(
In our exa!ple' we display an lcd nu!ber and a slider. (e change the lcd nu!ber
by dragging the slider.
self.connect(sli"er Qt2ore.;G0A<(+value2hange"(int+ lc"Qt2ore.;<6*(+"isplay(int+
=ere we connect a "alue/hanged67 signal of the slider to the display67 slot of
the lcd nu!ber.
The connect !ethod has four para!eters. Thesender
is an ob&ect that sends a
signal. Thesignal
is the signal' which is e!itted. Therecei"er
is the
ob&ect' that recei"es the signal. -inally theslot
is the !ethod' that reacts
to the signal.
-igure signal M slot
:ei!ple!enting e"ent handler
@"ents in PyQt are processed !ainly by rei!ple!enting e"ent handlers .
#!/usr/bin/python
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 25/69
# escape.py
import sysfrom PyQt4 import QtGui Qt2ore
class 7scape(QtGui.Qi"get
"ef --init--(self parent=0one QtGui.Qi"get.--init--(self parent
self.setin"o*itle(+escape+ self.resi$e(%&' )&' self.connect(self Qt2ore.;G0A<(+close7mitApp(+Qt2ore.;<6*(+close(+
"ef eyPress7vent(self event if event.ey( == Qt2ore.Qt.Hey-7scape self.close(
app = QtGui.QApplication(sys.argv9b = 7scape(9b.sho(sys.e,it(app.e,ec-(
In our exa!ple' we rei!ple!ent the keyPress@"ent67 e"ent handler.
"ef eyPress7vent(self event if event.ey( == Qt2ore.Qt.Hey-7scape self.close(
If we click the escape button' we close the application.
@!itting signals
b&ects created fro! Qt/ore.Q4b&ect can e!it signals. If we click on the button'
a clicked67 signal is generated. In the following exa!ple we will see' how we
can e!it signals.
#!/usr/bin/python
# emit.py
import sysfrom PyQt4 import QtGui Qt2ore
class 7mit(QtGui.Qi"get "ef --init--(self parent=0one QtGui.Qi"get.--init--(self parent
self.setin"o*itle(+emit+ self.resi$e(%&' )&' self.connect(self Qt2ore.;G0A<(+close7mitApp(+Qt2ore.;<6*(+close(+
"ef mousePress7vent(self event self.emit(Qt2ore.;G0A<(+close7mitApp(+
app = QtGui.QApplication(sys.argv
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 26/69
9b = 7mit(9b.sho(sys.e,it(app.e,ec-(
(e create a new signal called close@!itApp67. This signal is e!itted' during a
!ouse press e"ent.
"ef mousePress7vent(self event self.emit(Qt2ore.;G0A<(+close7mitApp(+
@!itting a signal with the e!it67 !ethod.
self.connect(self Qt2ore.;G0A<(+close7mitApp(+ Qt2ore.;<6*(+close(+
=ere we connect the !anually created close@!itApp67 signal with the close67
slot.
*ialogs in PyQt4
*ialog windows or dialogs are an indispensable part of !ost !odern GI
applications. A dialog is defined as a con"ersation between two or !ore persons.
In a co!puter application a dialog is a window which is used to talk to the
application. A dialog is used to input data' !odify data' change the application
settings etc. *ialogs are i!portant !eans of co!!unication between a user and a
co!puter progra!.
There are essentially two types of dialogs. Predefined dialogs and custo!
dialogs.
Predefined *ialogs
Q nput*ialog
The QInput*ialog pro"ides a si!ple con"enience dialog to get a single "alue fro!
the user. The input "alue can be a string' a nu!ber or an ite! fro! a list.
#!/usr/bin/python
# input"ialog.py
import sysfrom PyQt4 import QtGuifrom PyQt4 import Qt2ore
class nputBialog(QtGui.Qi"get "ef --init--(self parent=0one QtGui.Qi"get.--init--(self parent
self.setGeometry(1'' 1'' 1&' M' self.setin"o*itle(+nputBialog+
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 27/69
self.button = QtGui.QPush8utton(+Bialog+ self self.button.set5ocusPolicy(Qt2ore.Qt.0o5ocus
self.button.move(%' %' self.connect(self.button Qt2ore.;G0A<(+clice"(+ self.shoBialog self.set5ocus(
self.label = QtGui.Q<ine7"it(self self.label.move()1' %%
"ef shoBialog(self te,t o = QtGui.QnputBialog.get*e,t(self +nput Bialog+ +7nter yourname+
if o self.label.set*e,t(unico"e(te,t
app = QtGui.QApplication(sys.argv
icon = nputBialog(icon.sho(app.e,ec-(
The exa!ple has a button and a line edit widget. The button shows the input
dialog for getting text "alues. The entered text will be displayed in the line
edit widget.
te,t o = QtGui.QnputBialog.get*e,t(self +nput Bialog+ +7nter your name+
This line displays the input dialog. The first string is a dialog title' the
second one is a !essage within the dialog. The dialog returns the entered text
and a boolean "alue. If we clicked ok button' the boolean "alue is true'
otherwise false.
-igure Input *ialog
Q/olor*ialog
The Q/olor*ialog pro"ides a dialog widget for specifying colors.
#!/usr/bin/python
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 28/69
# color"ialog.py
import sysfrom PyQt4 import QtGuifrom PyQt4 import Qt2ore
class 2olorBialog(QtGui.Qi"get "ef --init--(self parent=0one
QtGui.Qi"get.--init--(self parent
color = QtGui.Q2olor(' ' '
self.setGeometry(1'' 1'' %&' )M' self.setin"o*itle(+2olorBialog+
self.button = QtGui.QPush8utton(+Bialog+ self self.button.set5ocusPolicy(Qt2ore.Qt.0o5ocus
self.button.move(%' %'
self.connect(self.button Qt2ore.;G0A<(+clice"(+ self.shoBialog self.set5ocus(
self.i"get = QtGui.Qi"get(self self.i"get.set;tyle;heet(?Qi"get R bacgroun"Ccolor Ss T?
S color.name( self.i"get.setGeometry()1' %% )'' )''
"ef shoBialog(self col = QtGui.Q2olorBialog.get2olor(
if col.isJali"( self.i"get.set;tyle;heet(?Qi"get R bacgroun"Ccolor Ss T? S col.name(
app = QtGui.QApplication(sys.argvc" = 2olorBialog(c".sho(app.e,ec-(
The application exa!ple shows a push button and a Q(idget . The widget backgroundis set to black color. sing the Q/olor*ialog ' we can change its background.
color = QtGui.Q2olorBialog.get2olor(
This line will pop up the Q/olor*ialog .
if col.isJali"( self.i"get.set;tyle;heet(?Qi"get R bacgroun"Ccolor Ss T? S col.name(
(e check if the color is "alid. If we click on the cancel button' no "alid color
is returned. If the color is "alid' we change the background color usingstylesheets.
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 29/69
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 30/69
self.connect(button Qt2ore.;G0A<(+clice"(+ self.shoBialog
self.label = QtGui.Q<abel(+Hnole"ge only matters+ self self.label.move()1' %'
hbo,.a""i"get(self.label ) self.set<ayout(hbo,
"ef shoBialog(self font o = QtGui.Q5ontBialog.get5ont( if o self.label.set5ont(font
app = QtGui.QApplication(sys.argvc" = 5ontBialog(c".sho(app.e,ec-(
In our exa!ple' we ha"e a button and a label. (ith Q-ont*ialog ' we change the
font of the label.
hbo,.a""i"get(self.label )
(e !ake the label resiCable. It is necessary' because when we select a different
font' the text !ay beco!e larger. therwise the label !ight not be fully
"isible.
font o = QtGui.Q5ontBialog.get5ont(
=ere we pop up the font dialog.
if o self.label.set5ont(font
If we clicked ok' the font of the label was changed.
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 31/69
-igure -ont dialog
Q-ile*ialog
The Q-ile*ialog is a dialog that allows users to select files or directories.
The files can be selected for both opening a sa"ing.
#!/usr/bin/python
# openfile"ialog.py
import sysfrom PyQt4 import QtGui
from PyQt4 import Qt2ore
class 6pen5ile(QtGui.Q>ainin"o "ef --init--(self parent=0one QtGui.Q>ainin"o.--init--(self parent
self.setGeometry(1'' 1'' 1&' 1'' self.setin"o*itle(+6pen5ile+
self.te,t7"it = QtGui.Q*e,t7"it( self.set2entrali"get(self.te,t7"it
self.status8ar( self.set5ocus(
e,it = QtGui.QAction(QtGui.Qcon(+open.png+ +6pen+ self
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 32/69
e,it.set;hortcut(+2trlE6+ e,it.set;tatus*ip(+6pen ne 5ile+ self.connect(e,it Qt2ore.;G0A<(+triggere"(+ self.shoBialog
menubar = self.menu8ar( file = menubar.a"">enu(+F5ile+ file.a""Action(e,it
"ef shoBialog(self filename = QtGui.Q5ileBialog.get6pen5ile0ame(self +6pen file+ +/home+ file=open(filename "ata = file.rea"( self.te,t7"it.set*e,t("ata
app = QtGui.QApplication(sys.argvc" = 6pen5ile(c".sho(app.e,ec-(
The exa!ple shows a !enubar' centrally set text edit widget and a statusbar. The
statusbar is shown only for desing purposes. The the !enu ite! shows the
Q-ile*ialog which is used to select a file. The contents of the file are loaded
into the text edit widget.
class 6pen5ile(QtGui.Q>ainin"o... self.te,t7"it = QtGui.Q*e,t7"it( self.set2entrali"get(self.te,t7"it
The exa!ple is based on the Q)ain(indow widget' because we centrally set the
text edit widget. This is easily done with the Q)ain(indow widget' without
resorting to layouts.
filename = QtGui.Q5ileBialog.get6pen5ile0ame(self +6pen file+ +/home+
(e pop up the Q-ile*ialog . The first string in the getpen-ile1a!e !ethod is the
caption. The second string specifies the dialog working directory. ,y default'
the file filter is set to All files 6N7.file=open(filename
"ata = file.rea"( self.te,t7"it.set*e,t("ata
The selected file na!e is read and the contents of the file are set to the text
edit widget.
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 33/69
-igure -ile dialog
PyQt4 (idgets
(idgets are basic building blocks of an application. The PyQt4 progra!!ing
toolkit has a wide range of "arious widgets. ,uttons' check boxes' sliders' list
boxes etc. @"erything a progra!!er needs for his &ob. In this section of the
tutorial' we will describe se"eral useful widgets.
Q/heck,ox
Q/heck,ox is a widget that has two states. n and ff. It is a box with a label.
(hene"er a checkbox is checked or cleared it e!its the signal state/hanged67.
#!/usr/bin/python
# checbo,.py
import sysfrom PyQt4 import QtGuifrom PyQt4 import Qt2ore
class 2hec8o,(QtGui.Qi"get "ef --init--(self parent=0one QtGui.Qi"get.--init--(self parent
self.setGeometry(1'' 1'' %&' )&'
self.setin"o*itle(+2hecbo,+
self.cb = QtGui.Q2hec8o,(+;ho title+ self self.cb.set5ocusPolicy(Qt2ore.Qt.0o5ocus
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 34/69
self.cb.move()' )' self.cb.toggle(U self.connect(self.cb Qt2ore.;G0A<(+state2hange"(int+self.change*itle
"ef change*itle(self value if self.cb.is2hece"(
self.setin"o*itle(+2hecbo,+ else self.setin"o*itle(++
app = QtGui.QApplication(sys.argvicon = 2hec8o,(icon.sho(app.e,ec-(
In our exa!ple' we will create a checkbox that will toggle the window title.
self.cb = QtGui.Q2hec8o,(+;ho title+ self
This is the Q/heck,ox constructor.
self.cb.set5ocusPolicy(Qt2ore.Qt.0o5ocus
(e connect the user defined changeTitle67 !ethod to the state/hanged67 signal.
The changeTitle67 !ethod will toggle the window title.
self.connect(self.cb Qt2ore.;G0A<(+state2hange"(int+ self.change*itle
,y default' the Q/heck,ox accepts focus. It is represented by a thin rectangle
o"er the checkbox label. The rectangle looks awful' so I disable it by setting
the widget focus policy to Qt.1o-ocus .
self.cb.toggle(U
(e set the window title' so we !ust also check the checkbox. ,y default' the
window title is not set and the check box is unchecked.
-igure Q/heck,ox
Toggle,utton
PyQt4 has no widget for a Toggle,utton. To create a Toggle,utton' we use a
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 35/69
QPush,utton in a special !ode. Toggle,utton is a button that has two states.
Pressed and not pressed. Jou toggle between these two states by clicking on it.
There are situations where this functionality fits well.
#!/usr/bin/python
# togglebutton.py
import sysfrom PyQt4 import QtGuifrom PyQt4 import Qt2ore
class *oggle8utton(QtGui.Qi"get "ef --init--(self parent=0one QtGui.Qi"get.--init--(self parent
self.color = QtGui.Q2olor(' ' '
self.setGeometry(1'' 1'' %M' )L' self.setin"o*itle(+*oggle8utton+
self.re" = QtGui.QPush8utton(+De"+ self self.re".set2hecable(*rue self.re".move()' )'
self.connect(self.re" Qt2ore.;G0A<(+clice"(+ self.setDe"
self.green = QtGui.QPush8utton(+Green+ self self.green.set2hecable(*rue self.green.move()' :'
self.connect(self.green Qt2ore.;G0A<(+clice"(+ self.setGreen
self.blue = QtGui.QPush8utton(+8lue+ self self.blue.set2hecable(*rue self.blue.move()' ))'
self.connect(self.blue Qt2ore.;G0A<(+clice"(+ self.set8lue
self.s9uare = QtGui.Qi"get(self self.s9uare.setGeometry()&' %' )'' )'' self.s9uare.set;tyle;heet(?Qi"get R bacgroun"Ccolor Ss T? Sself.color.name(
QtGui.QApplication.set;tyle(QtGui.Q;tyle5actory.create(+cleanloos+
"ef setDe"(self if self.re".is2hece"( self.color.setDe"(%&& else self.color.setDe"('
self.s9uare.set;tyle;heet(?Qi"get R bacgroun"Ccolor Ss T? Sself.color.name(
"ef setGreen(self if self.green.is2hece"( self.color.setGreen(%&& else self.color.setGreen('
self.s9uare.set;tyle;heet(?Qi"get R bacgroun"Ccolor Ss T? S
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 36/69
self.color.name(
"ef set8lue(self if self.blue.is2hece"( self.color.set8lue(%&& else self.color.set8lue('
self.s9uare.set;tyle;heet(?Qi"get R bacgroun"Ccolor Ss T? Sself.color.name(
app = QtGui.QApplication(sys.argvtb = *oggle8utton(tb.sho(app.e,ec-(
In our exa!ple' we create three Toggle,uttons. (e also create a Q(idget . (e set
the background color of the Q(idget to black. The togglebuttons will toggle the
red' green and blue parts of the color "alue. The background color will dependon which togglebuttons we ha"e pressed.
self.color = QtGui.Q2olor(' ' '
This is the initial color "alue. 1o red' green and blue e9uals to black.
Theoretically speaking' black is not a color after all.
self.re" = QtGui.QPush8utton(+De"+ self self.re".set2hecable(*rue
To create a Toggle,utton' we create a QPush,utton and !ake it checkable bycalling set/heckable67 !ethod.
self.connect(self.re" Qt2ore.;G0A<(+clice"(+ self.setDe"
(e connect a clicked67 signal to our user defined !ethod.
QtGui.QApplication.set;tyle(QtGui.Q;tyle5actory.create(+cleanloos+
I ha"e set the style of the application to cleanlooks. I did it' because the
default style for linux' plasti9ue has a design bug. Jou cannot easily tell
whether the Toggle,utton is pressed or not. /leanLooks style is better.
if self.re".is2hece"( self.color.setDe"(%&& else self.color.setDe"('
(e check' whether the button is pressed and change the color "alue accordingly.
self.s9uare.set;tyle;heet(?Qi"get R bacgroun"Ccolor Ss T? Sself.color.name(
To change the background color' we use stylesheets.
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 37/69
-igure Toggle,utton
Q+lider' QLabel
Q+lider is a widget that has a si!ple handle. This handle can be pulled back andforth. This way we are choosing a "alue for a specific task. +o!eti!es using a
slider is !ore natural' than si!ply pro"iding a nu!ber or using a spin box.
QLabel displays text or i!age.
In our exa!ple we will show one slider and one label. This ti!e' the label will
display an i!age. The slider will control the label.
#!/usr/bin/python
# sli"erClabel.py
import sysfrom PyQt4 import QtGuifrom PyQt4 import Qt2ore
class ;li"er<abel(QtGui.Qi"get "ef --init--(self parent=0one QtGui.Qi"get.--init--(self parent
self.setGeometry(1'' 1'' %&' )&' self.setin"o*itle(+;li"er<abel+
self.sli"er = QtGui.Q;li"er(Qt2ore.Qt.Iori$ontal self self.sli"er.set5ocusPolicy(Qt2ore.Qt.0o5ocus self.sli"er.setGeometry(1' 4' )'' 1' self.connect(self.sli"er Qt2ore.;G0A<(+value2hange"(int+self.changeJalue
self.label = QtGui.Q<abel(self self.label.setPi,map(QtGui.QPi,map(+mute.png+ self.label.setGeometry():' 4' M' 1'
"ef changeJalue(self value
pos = self.sli"er.value(
if pos == ' self.label.setPi,map(QtGui.QPi,map(+mute.png+
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 38/69
elif pos ' an" pos 3= 1' self.label.setPi,map(QtGui.QPi,map(+min.png+ elif pos 1' an" pos 3 M' self.label.setPi,map(QtGui.QPi,map(+me".png+ else self.label.setPi,map(QtGui.QPi,map(+ma,.png+
app = QtGui.QApplication(sys.argvicon = ;li"er<abel(icon.sho(app.e,ec-(
In our exa!ple we si!ulate a "olu!e control. ,y dragging the handle of a slider'
we change a i!age on the label.
self.sli"er = QtGui.Q;li"er(Qt2ore.Qt.Iori$ontal self
=ere we create a horiContal Q+lider .
self.label = QtGui.Q<abel(self self.label.setPi,map(QtGui.QPi,map(+mute.png+
(e create a Qlabel. And set an initial !ute i!age to it.
self.connect(self.sli"er Qt2ore.;G0A<(+value2hange"(int+ self.changeJalue
(e connect the "alue/hanged signal to the user defined change5alue67 !ethod.
pos = self.sli"er.value(
(e get the position of the slider by calling the "alue67 !ethod. (e change the
i!age on the label accordingly.
-igure +lider and Label
QProgress,ar
A progress bar is a widget that is used' when we process lengthy tasks. It is
ani!ated so that the user knows' that our task is progressing. The QProgress,ar
widget pro"ides a horiContal or "ertical progress bar in PyQt4 toolkit. The task
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 39/69
is di"ided into steps. The progra!!er can set the !ini!u! and !axi!u! "alues for
the progress bar. The default "alues are $' <<.
#!/usr/bin/python
# progressbar.py
import sysfrom PyQt4 import QtGuifrom PyQt4 import Qt2ore
class Progress8ar(QtGui.Qi"get "ef --init--(self parent=0one QtGui.Qi"get.--init--(self parent
self.setGeometry(1'' 1'' %&' )&' self.setin"o*itle(+Progress8ar+
self.pbar = QtGui.QProgress8ar(self
self.pbar.setGeometry(1' 4' %'' %&
self.button = QtGui.QPush8utton(+;tart+ self self.button.set5ocusPolicy(Qt2ore.Qt.0o5ocus self.button.move(4' M'
self.connect(self.button Qt2ore.;G0A<(+clice"(+ self.on;tart
self.timer = Qt2ore.Q8asic*imer( self.step = 'U
"ef timer7vent(self event if self.step = )'' self.timer.stop( return self.step = self.step E ) self.pbar.setJalue(self.step
"ef on;tart(self if self.timer.isActive( self.timer.stop( self.button.set*e,t(+;tart+ else self.timer.start()'' self
self.button.set*e,t(+;top+
app = QtGui.QApplication(sys.argvicon = Progress8ar(icon.sho(app.e,ec-(
In our exa!ple we ha"e a horiContal progress bar and a push button. The push
button starts and stops the progress bar.self.pbar = QtGui.QProgress8ar(self
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 40/69
QProgress,ar constructor.
self.timer = Qt2ore.Q8asic*imer(
To acti"ate the progress bar' we use the ti!er ob&ect.
self.timer.start()'' self
To launch the ti!er e"ents' we call the start67 !ethod. This !ethod has two
para!eters. The ti!eout and the ob&ect' which will recei"e the e"ents.
"ef timer7vent(self event if self.step = )'' self.timer.stop( return self.step = self.step E ) self.pbar.setJalue(self.step
@ach Q4b&ect and its descendants has a Q4b&ect.ti!er@"ent e"ent handler. In
order to react to ti!er e"ents' we rei!ple!ent the e"ent handler.
-igure Progress,ar
Q/alendar(idget
The Q/alendar(idget pro"ides a !onthly based calendar widget. It allows a user
to select a date in a si!ple and intuiti"e way.
#!/usr/bin/python
# calen"ar.py
import sysfrom PyQt4 import QtGuifrom PyQt4 import Qt2ore
class 2alen"ar(QtGui.Qi"get "ef --init--(self parent=0one QtGui.Qi"get.--init--(self parent
self.setGeometry(1'' 1'' 1&' 1'' self.setin"o*itle(+2alen"ar+
self.cal = QtGui.Q2alen"ari"get(self
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 41/69
self.cal.setGri"Jisible(*rue self.cal.move(%' %' self.connect(self.cal Qt2ore.;G0A<(+selection2hange"(+self.shoBate
self.label = QtGui.Q<abel(self
"ate = self.cal.selecte"Bate( self.label.set*e,t(str("ate.toPyBate( self.label.move()1' %:'
"ef shoBate(self "ate = self.cal.selecte"Bate( self.label.set*e,t(str("ate.toPyBate(
app = QtGui.QApplication(sys.argvicon = 2alen"ar(icon.sho(
app.e,ec-(
The exa!ple has a calendar widget and a label widget. The currently selected
date is displayed in the label widget.
self.cal = QtGui.Q2alen"ari"get(self
(e construct a calendar widget.
self.connect(self.cal Qt2ore.;G0A<(+selection2hange"(+ self.shoBate
If we select a date fro! the widget' a selection/hanged67 signal is e!itted. (e
connect this !ethod to the user defined show*ate67 !ethod.
"ef shoBate(self "ate = self.cal.selecte"Bate( self.label.set*e,t(str("ate.toPyBate(
(e retrie"e the selected date calling the selected*ate67 !ethod. Then we
transfor! the date ob&ect into string and set it to the label widget.
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 42/69
-igure /alendar widget
*rag and *rop in PyQt4
In this part of the PyQt4 tutorial' we will talk about drag M drop operations.
In co!puter graphical user interfaces' drag0and0drop is the action of 6orsupport for the action of7 clicking on a "irtual ob&ect and dragging it to a
different location or onto another "irtual ob&ect. In general' it can be used to
in"oke !any kinds of actions' or create "arious types of associations between
two abstract ob&ects. 6(ikipedia7
*rag and drop functionality is one of the !ost "isible aspects of the graphical
user interface. *rag and drop operation enables users to do co!plex things
intuiti"ely.
sually' we can drag and drop two things. *ata or so!e graphical ob&ects. If we
drag an i!age fro! one application to another' we drag and drop binary data. If
we drag a tab in -irefox and !o"e it to another place' we drag and drop a
graphical co!ponent.
+i!ple *rag and *rop
In the first exa!ple' we will ha"e aQLine@dit
and aQPush,utton
. (e will
drag plain text fro! the line edit widget and drop it onto the button widget.
#!/usr/bin/python
# "rag"rop.py
import sys
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 43/69
from PyQt4 import QtGui
class 8utton(QtGui.QPush8utton "ef --init--(self title parent QtGui.QPush8utton.--init--(self title parent self.setAcceptBrops(*rue
"ef "rag7nter7vent(self event if event.mimeBata(.has5ormat(+te,t/plain+ event.accept( else event.ignore(
"ef "rop7vent(self event self.set*e,t(event.mimeBata(.te,t(
class BragBrop(QtGui.QBialog "ef --init--(self parent=0one QtGui.QBialog.--init--(self parent
self.resi$e(%M' )&' self.setin"o*itle(+;imple Brag F Brop+
e"it = QtGui.Q<ine7"it(++ self e"it.setBrag7nable"(*rue e"it.move(1' :&
button = 8utton(?8utton? self button.move()L' :&
screen = QtGui.QBestopi"get(.screenGeometry( si$e = self.geometry(
self.move((screen.i"th(Csi$e.i"th(/%(screen.height(Csi$e.height(/%
app = QtGui.QApplication(sys.argvicon = BragBrop(icon.sho(app.e,ec-(
+i!ple drag M drop operation.
class 8utton(QtGui.QPush8utton "ef --init--(self title parent QtGui.QPush8utton.--init--(self title parent
In order to drop text on theQPush,utton
widget' we !ust rei!ple!ent so!e
!ethods. +o we create our own ,utton class' which will inherit fro! the
QPush,utton class.
self.setAcceptBrops(*rue
(e enable drop e"ents for the widget.
"ef "rag7nter7vent(self event if event.mimeBata(.has5ormat(+te,t/plain+
event.accept( else event.ignore(
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 44/69
-irst we rei!ple!ent the drag@nter@"ent67 !ethod. (e infor! about the data type'
we will accept. In our case it is plain text.
"ef "rop7vent(self event self.set*e,t(event.mimeBata(.te,t(
,y rei!ple!enting the drop@"ent67 !ethod' we will define' what we will do uponthe drop e"ent. =ere we change the text of the button widget.
e"it = QtGui.Q<ine7"it(++ self e"it.setBrag7nable"(*rue
TheQLine@dit
widget has a built0in support for drag operations. All we need
to do is to callset*rag@nabled67
!ethod to acti"ate it.
-igure +i!ple *rag M *rop
*rag M drop a button widget
In the following exa!ple' we will de!onstrate' how to drag M drop a button
widget.
#!/usr/bin/python
# "ragbutton.py
import sysfrom PyQt4 import QtGuifrom PyQt4 import Qt2ore
class 8utton(QtGui.QPush8utton "ef --init--(self title parent QtGui.QPush8utton.--init--(self title parent
"ef mouse>ove7vent(self event
if event.buttons( != Qt2ore.Qt.Dight8utton return
mimeBata = Qt2ore.Q>imeBata(
"rag = QtGui.QBrag(self "rag.set>imeBata(mimeBata "rag.setIot;pot(event.pos( C self.rect(.top<eft(
"ropAction = "rag.start(Qt2ore.Qt.>oveAction
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 45/69
if "ropAction == Qt2ore.Qt.>oveAction self.close(
"ef mousePress7vent(self event QtGui.QPush8utton.mousePress7vent(self event
if event.button( == Qt2ore.Qt.<eft8utton print +press+
class Brag8utton(QtGui.QBialog "ef --init--(self parent=0one QtGui.QBialog.--init--(self parent
self.resi$e(%M' )&' self.setin"o*itle(+2lic or >ove+ self.setAcceptBrops(*rue
self.button = 8utton(+8utton+ self self.button.move()'' :&
screen = QtGui.QBestopi"get(.screenGeometry( si$e = self.geometry( self.move((screen.i"th(Csi$e.i"th(/%
(screen.height(Csi$e.height(/%
"ef "rag7nter7vent(self event event.accept(
"ef "rop7vent(self event
position = event.pos( button = 8utton(+8utton+ self
button.move(position button.sho(
event.setBropAction(Qt2ore.Qt.>oveAction event.accept(
app = QtGui.QApplication(sys.argv"b = Brag8utton("b.sho(app.e,ec-(
In our code exa!ple' we ha"e aQPush,utton
on the window. If we click on the
button with a left !ouse button' we print >press> to the console. ,y right
clicking and !o"ing the button' we perfor! a drag M drop operation on the button
widget.
class 8utton(QtGui.QPush8utton "ef --init--(self title parent
QtGui.QPush8utton.--init--(self title parent
(e create a ,utton class' which will deri"e fro! the QPush,utton. (e also
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 46/69
rei!ple!ent two !ethods of the QPush,utton.!ouse)o"e@"ent67
and
!ousePress@"ent67
. The !ouse)o"e@"ent67 !ethod is the place' where the drag M
drop operation begins.
if event.buttons( != Qt2ore.Qt.Dight8utton return
=ere we decide' that we can perfor! drag M drop only with a right !ouse button.
The left !ouse button is reser"ed for clicking on the button.
mimeBata = Qt2ore.Q>imeBata(
"rag = QtGui.QBrag(self "rag.set>imeBata(mimeBata "rag.setIot;pot(event.pos( C self.rect(.top<eft(
=ere we create aQ*rag
ob&ect.
"ropAction = "rag.start(Qt2ore.Qt.>oveAction
if "ropAction == Qt2ore.Qt.>oveAction self.close(
Thestart67
!ethod of the drag ob&ect starts the drag M drop operation. If we
perfor! a !o"e drop action' we destroy the button widget. Technically' we
destroy a widget on the current position and recreate it on a new one.
"ef mousePress7vent(self event QtGui.QPush8utton.mousePress7vent(self event if event.button( == Qt2ore.Qt.<eft8utton print +press+
(e print >press> to the console' if we left click on the button with the !ouse.
1otice that we call !ousePress@"ent67 !ethod on the parent as well. therwise we
would not see the button being pushed.
position = event.pos( button = 8utton(+2lose+ self button.move(position button.sho(
In the drop@"ent67 !ethod we code' what happens after we release the !ouse
button and finish the drop operation. In our exa!ple' we create a new ,utton
widget at the current position of the !ouse pointer.
event.setBropAction(Qt2ore.Qt.>oveAction event.accept(
(e specify the type of the drop action. In our case it is a !o"e action.
*rawing in PyQt4
*rawing is used' when we want to change or enhance an existing widget. r if we
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 47/69
are creating a custo! widget fro! scratch. To do the drawing' we use the drawing
API pro"ided by the PyQt4 toolkit.
The drawing is done within the paint@"ent67 !ethod. The drawing code is placed
between the begin67 and end67 !ethods of the QPainter ob&ect.
*rawing text
(e begin with drawing so!e unicode text onto the window client area.
#!/usr/bin/python
# "rate,t.py
import sysfrom PyQt4 import QtGui Qt2ore
class Bra*e,t(QtGui.Qi"get "ef --init--(self parent=0one QtGui.Qi"get.--init--(self parent
self.setGeometry(1'' 1'' %&' )&' self.setin"o*itle(+Bra *e,t+
self.te,t = u+u'4)bu'41&u'41% u'4)"u'41Mu'41au'41eu'41bu'41'u'41&u'41%u'41Mu'44L u'4%%u'41eu'41bu'44)u'44%u'41eu'41N nu'4)'u'41"u'41"u'41' u'4)au'41'u'44'u'41&u'41"u'41Mu'41"u'41'+
"ef paint7vent(self event paint = QtGui.QPainter( paint.begin(self paint.setPen(QtGui.Q2olor():M 14 1 paint.set5ont(QtGui.Q5ont(+Becorative+ )' paint."ra*e,t(event.rect( Qt2ore.Qt.Align2enter self.te,t paint.en"(
app = QtGui.QApplication(sys.argv"t = Bra*e,t("t.sho(app.e,ec-(
In our exa!ple' we draw so!e text in aCbuka. The text is "ertically and
horiContally aligned.
"ef paint7vent(self event
*rawing is done within a paint e"ent.
paint = QtGui.QPainter( paint.begin(self
... paint.en"(
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 48/69
The QPainter class is responsible for all the low0le"el painting. All the
painting !ethods go between begin67 and end67 !ethods.
paint.setPen(QtGui.Q2olor():M 14 1 paint.set5ont(QtGui.Q5ont(+Becorative+ )'
=ere we define pen and font' which we use to draw the text.paint."ra*e,t(event.rect( Qt2ore.Qt.Align2enter self.te,t
The drawText67 !ethod actually draws text on the window.
-igure *rawing Text
*rawing points
A point is the !ost si!ple graphics ob&ect' that can be drawn. It is a s!allspot on the window.
#!/usr/bin/python
# points.py
import sys ran"omfrom PyQt4 import QtGui Qt2ore
class Points(QtGui.Qi"get "ef --init--(self parent=0one
QtGui.Qi"get.--init--(self parent
self.setGeometry(1'' 1'' %&' )&' self.setin"o*itle(+Points+
"ef paint7vent(self event paint = QtGui.QPainter( paint.begin(self paint.setPen(Qt2ore.Qt.re" si$e = self.si$e( for i in range()''' , = ran"om.ran"int() si$e.i"th(C) y = ran"om.ran"int() si$e.height(C) paint."raPoint(, y paint.en"(
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 49/69
app = QtGui.QApplication(sys.argv"t = Points("t.sho(app.e,ec-(
In our exa!ple' we draw rando!ly ;$$$ red points on the client area.paint.setPen(Qt2ore.Qt.re"
(e set the pen to red color. (e use a predefined color constant.
si$e = self.si$e(
@ach ti!e we resiCe the window' a paint e"ent is generated. (e get the current
siCe of the window with the siCe67 !ethod.
paint."raPoint(, y
(e draw the point with the drawPoint67 !ethod.
-igure Points
/olors
A color is an ob&ect representing a co!bination of :ed' Green' and ,lue 6:G,7
intensity "alues. 5alid :G, "alues are in the range $ to 8??. (e can define a
color in "arious ways. The !ost co!!on are :G, deci!al "alues or hexadeci!al
"alues. (e can also use an :G,A "alue' which stands for :ed' Green' ,lue' Alpha.
=ere we add so!e extra infor!ation' regarding transparency. Alpha "alue of 8??
defines full opacity' $ is for full transparency' eg the color is in"isible.
#!/usr/bin/python
# colors.py
import sys ran"omfrom PyQt4 import QtGui Qt2ore
class 2olors(QtGui.Qi"get "ef --init--(self parent=0one
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 50/69
QtGui.Qi"get.--init--(self parent
self.setGeometry(1'' 1'' 1&' %M' self.setin"o*itle(+2olors+
"ef paint7vent(self event paint = QtGui.QPainter(
paint.begin(self
color = QtGui.Q2olor(' ' ' color.set0ame"2olor(+#"4"4"4+ paint.setPen(color
paint.set8rush(QtGui.Q2olor(%&& ' ' M' paint."raDect()' )& N' :'
paint.set8rush(QtGui.Q2olor(%&& ' ' ):' paint."raDect()1' )& N' :'
paint.set8rush(QtGui.Q2olor(%&& ' ' %&&
paint."raDect(%&' )& N' :'
paint.set8rush(QtGui.Q2olor()' ):1 % && paint."raDect()' )'& N' :'
paint.set8rush(QtGui.Q2olor():' )'' ' %&& paint."raDect()1' )'& N' :'
paint.set8rush(QtGui.Q2olor(:' )'' :' %&& paint."raDect(%&' )'& N' :'
paint.set8rush(QtGui.Q2olor(&' &' &' %&& paint."raDect()' )N& N' :'
paint.set8rush(QtGui.Q2olor(&' )&' &' %&& paint."raDect()1' )N& N' :'
paint.set8rush(QtGui.Q2olor(%%1 )1& )N %&& paint."raDect(%&' )N& N' :'
paint.en"(
app = QtGui.QApplication(sys.argv"t = 2olors("t.sho(app.e,ec-(
In our exa!ple' we draw < colored rectangles. The first row shows a red color'
with different alpha "alues.
color = QtGui.Q2olor(' ' ' color.set0ame"2olor(+#"4"4"4+
=ere we define a color using hexadeci!al notation.
paint.set8rush(QtGui.Q2olor(%&& ' ' M'U
paint."raDect()' )& N' :'
=ere we define a brush and draw a rectangle. Abrush
is an ele!entary graphics
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 51/69
ob&ect' which is used to draw the background of a shape. The draw:ect67 !ethod
accepts four para!eter. The first two are x' y "alues on the axis. The third and
fourth para!eters are width and height of the rectangle. The !ethod draws a
rectangle using current pen and current brush.
-igure /olors
QPen
QPen is an ele!entary graphics ob&ect. It is used to draw lines' cur"es and
outlines of rectangles' ellipses' polygons or other shapes.
#!/usr/bin/python
# penstyles.py
import sysfrom PyQt4 import QtGui Qt2ore
class Pen;tyles(QtGui.Qi"get "ef --init--(self parent=0one QtGui.Qi"get.--init--(self parent
self.setGeometry(1'' 1'' %M' %L' self.setin"o*itle(+penstyles+
"ef paint7vent(self event paint = QtGui.QPainter(
paint.begin(self
pen = QtGui.QPen(Qt2ore.Qt.blac % Qt2ore.Qt.;oli"<ine
paint.setPen(pen paint."ra<ine(%' 4' %&' 4'
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 52/69
pen.set;tyle(Qt2ore.Qt.Bash<ine paint.setPen(pen paint."ra<ine(%' M' %&' M'
pen.set;tyle(Qt2ore.Qt.BashBot<ine paint.setPen(pen
paint."ra<ine(%' )%' %&' )%'
pen.set;tyle(Qt2ore.Qt.Bot<ine paint.setPen(pen paint."ra<ine(%' ):' %&' ):'
pen.set;tyle(Qt2ore.Qt.BashBotBot<ine paint.setPen(pen paint."ra<ine(%' %'' %&' %''
pen.set;tyle(Qt2ore.Qt.2ustomBash<ine pen.setBashPattern(K) 4 & 4 paint.setPen(pen
paint."ra<ine(%' %4' %&' %4'
paint.en"(
app = QtGui.QApplication(sys.argv"t = Pen;tyles("t.sho(app.e,ec-(
In our exa!ple' we draw six lines. The lines are drawn in six different penstyles. There are fi"e predefined pen styles. (e can create also custo! pen
styles. The last line is drawn using custo! pen style.
pen = QtGui.QPen(Qt2ore.Qt.blac % Qt2ore.Qt.;oli"<ine
(e create a QPen ob&ect. The color is black. The width is set to 8 pixels' so
that we can see the differences between the pen styles. The Qt/ore.Qt.+olidLine
is one of the predefined pen styles.
pen.set;tyle(Qt2ore.Qt.2ustomBash<ine pen.setBashPattern(K) 4 & 4
paint.setPen(pen
=ere we define a custo! pen style. (e set a Qt/ore.Qt./usto!*ashLine pen style
and call a set*ashPattern67 !ethod. The list of nu!bers defines a style. There
!ust be an e"en nu!ber of nu!bers. dd nu!bers define a dash' e"en nu!bers
space. The greater the nu!ber' the greater the space or the dash. ur pattern is
;px dash 4px space ?px dash 4px space etc.
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 53/69
-igure Pen +tyles
Q,rush
Q,rush is an ele!entary graphics ob&ect. It is used to paint the background of
graphics shapes' such as rectangles' ellipses or polygons. A brush can be of
three different types. A predefined brush a gradien or a texture pattern.
#!/usr/bin/python
# brushes.py
import sysfrom PyQt4 import QtGui Qt2ore
class 8rushes(QtGui.Qi"get "ef --init--(self parent=0one QtGui.Qi"get.--init--(self parent
self.setGeometry(1'' 1'' 1&& %M' self.setin"o*itle(+8rushes+
"ef paint7vent(self event paint = QtGui.QPainter(
paint.begin(self
brush = QtGui.Q8rush(Qt2ore.Qt.;oli"Pattern paint.set8rush(brush paint."raDect()' )& N' :'
brush.set;tyle(Qt2ore.Qt.Bense)Pattern paint.set8rush(brush paint."raDect()1' )& N' :'
brush.set;tyle(Qt2ore.Qt.Bense%Pattern paint.set8rush(brush paint."raDect(%&' )& N' :'
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 54/69
brush.set;tyle(Qt2ore.Qt.Bense1Pattern paint.set8rush(brush paint."raDect()' )'& N' :'
brush.set;tyle(Qt2ore.Qt.Biag2rossPattern paint.set8rush(brush
paint."raDect()' )'& N' :'
brush.set;tyle(Qt2ore.Qt.Bense&Pattern paint.set8rush(brush paint."raDect()1' )'& N' :'
brush.set;tyle(Qt2ore.Qt.Bense:Pattern paint.set8rush(brush paint."raDect(%&' )'& N' :'
brush.set;tyle(Qt2ore.Qt.IorPattern paint.set8rush(brush paint."raDect()' )N& N' :'
brush.set;tyle(Qt2ore.Qt.JerPattern paint.set8rush(brush paint."raDect()1' )N& N' :'
brush.set;tyle(Qt2ore.Qt.8BiagPattern paint.set8rush(brush paint."raDect(%&' )N& N' :'
paint.en"(
app = QtGui.QApplication(sys.argv"t = 8rushes(
"t.sho(app.e,ec-(
In our exa!ple' we draw six different rectangles.
brush = QtGui.Q8rush(Qt2ore.Qt.;oli"Pattern paint.set8rush(brush paint."raDect()' )& N' :'
(e define a brush ob&ect. +et it to the painter ob&ect. And draw the rectangle
calling the draw:ect67 !ethod.
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 55/69
-igure ,rushes
/usto! (idgets in PyQt4
=a"e you e"er looked at an application and wondered' how a particular gui ite!
was created Probably e"ery wannabe progra!!er has. Then you were looking at a
list of widgets pro"ided by your fa"ourite gui library. ,ut you couldn>t find
it. Toolkits usually pro"ide only the !ost co!!on widgets like buttons' text
widgets' sliders etc. 1o toolkit can pro"ide all possible widgets.
There are actually two kinds of toolkits. +partan toolkits and hea"y weight
toolkits. The -LTH toolkit is a kind of a spartan toolkit. It pro"ides only the
"ery basic widgets and assu!es' that the progra!e!er will create the !ore
co!plicated ones hi!self. PyQt4 is a hea"y weight one. It has lots of widgets.
Jet it does not pro"ide the !ore specialiCed widgets. -or exa!ple a speed !eter
widget' a widget that !easures the capacity of a /* to be burned 6found e.g. in
nero7. Toolkits also don>t ha"e usually charts.
Progra!!ers !ust create such widgets by the!sel"es. They do it by using thedrawing tools pro"ided by the toolkit. There are two possibilities. A progra!!er
can !odify or enhance an existing widget. r he can create a custo! widget fro!
scratch.
,urning widget
This is a widget that we can see in 1ero' H#, or other /*2*5* burning software.
#!/usr/bin/python
# burning.py
import sysfrom PyQt4 import QtGui Qt2ore
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 56/69
class i"get(QtGui.Q<abel "ef --init--(self parent QtGui.Q<abel.--init--(self parent self.set>inimum;i$e() 1' self.parent = parent
self.num = KL& )&' %%& 1'' 1L& 4&' &%& :'' :L&
"ef paint7vent(self event paint = QtGui.QPainter( paint.begin(self
font = QtGui.Q5ont(+;erif+ L QtGui.Q5ont.<ight paint.set5ont(font
si$e = self.si$e( = si$e.i"th( h = si$e.height( c = self.parent.c
step = int(roun"( / )'.'
till = int((( / L&'.' O c full = int((( / L&'.' O L''
if c = L'' paint.setPen(QtGui.Q2olor(%&& %&& %&& paint.set8rush(QtGui.Q2olor(%&& %&& )M4 paint."raDect(' ' full h paint.setPen(QtGui.Q2olor(%&& )L& )L& paint.set8rush(QtGui.Q2olor(%&& )L& )L& paint."raDect(full ' tillCfull h
else paint.setPen(QtGui.Q2olor(%&& %&& %&& paint.set8rush(QtGui.Q2olor(%&& %&& )M4 paint."raDect(' ' till h
pen = QtGui.QPen(QtGui.Q2olor(%' %' %' ) Qt2ore.Qt.;oli"<ine paint.setPen(pen paint.set8rush(Qt2ore.Qt.0o8rush paint."raDect(' ' C) hC)
= '
for i in range(step )'Ostep step paint."ra<ine(i ' i & metrics = paint.font>etrics( f = metrics.i"th(str(self.numK paint."ra*e,t(iCf/% h/% str(self.numK = E )
paint.en"(
class 8urning(QtGui.Qi"get "ef --init--(self parent=0one QtGui.Qi"get.--init--(self parent
self.c = L&
self.sli"er = QtGui.Q;li"er(Qt2ore.Qt.Iori$ontal self
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 57/69
self.sli"er.set5ocusPolicy(Qt2ore.Qt.0o5ocus self.sli"er.setDange() L&' self.sli"er.setJalue(L& self.sli"er.setGeometry(1' 4' )&' 1'
self.i" = i"get(self
self.connect(self.sli"er Qt2ore.;G0A<(+value2hange"(int+self.changeJalue hbo, = QtGui.QI8o,<ayout( hbo,.a""i"get(self.i" vbo, = QtGui.QJ8o,<ayout( vbo,.a"";tretch() vbo,.a""<ayout(hbo, self.set<ayout(vbo,
self.setGeometry(1'' 1'' 1'' %%' self.setin"o*itle(+8urning+
"ef changeJalue(self event
self.c = self.sli"er.value( self.i".repaint(
app = QtGui.QApplication(sys.argv"t = 8urning("t.sho(app.e,ec-(
In our exa!ple' we ha"e a Q+lider and a custo! widget. The slider controls the
custo! widget. This widget shows graphically the total capacity of a !ediu! andthe free space a"ailable to us. The !ini!u! "alue of our custo! widget is ;' the
!axi!u! is D?$. If we reach "alue D$$' we begin drawing in red colour. This
nor!ally indicates o"erburning.
The burning widget is placed at the botto! of the window. This is achie"ed using
one Q=,oxLayout and one Q5,oxLayout
class i"get(QtGui.Q<abel "ef --init--(self parent QtGui.Q<abel.--init--(self parent
The burning widget it based on the QLabel widget.
self.set>inimum;i$e() 1'
(e change the !ini!u! siCe 6height7 of the widget. The default "alue is a bit
s!all for us.
font = QtGui.Q5ont(+;erif+ L QtGui.Q5ont.<ight paint.set5ont(font
(e use a s!aller font than the default one. That better suits our needs.
si$e = self.si$e( = si$e.i"th( h = si$e.height(
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 58/69
c = self.parent.c step = int(roun"( / )'.'
till = int((( / L&'.' O c full = int((( / L&'.' O L''
(e draw the widget dyna!ically. The greater the window' the greater the burning
widget. And "ice "ersa. That is why we !ust calculate the siCe of the widget
onto which we draw the custo! widget. The till para!eter deter!ines the total
siCe to be drawn. This "alue co!es fro! the slider widget. It is a proportion of
the whole area. The full para!eter deter!ines the point' where we begin to draw
in red color. 1otice the use of floating point arith!etics. This is to achie"e
greater precision.
The actual drawing consists of three steps. (e draw the yellow or red and yellow
rectangle. Then we draw the "ertical lines' which di"ide the widget into se"eral
parts. -inally' we draw the nu!bers' which indicate the capacity of the !ediu!.metrics = paint.font>etrics(
f = metrics.i"th(str(self.numK paint."ra*e,t(iCf/% h/% str(self.numK
(e use font !etrics to draw the text. (e !ust know the width of the text in
order to center it around the "ertical line.
-igure The burning widget
The Tetris ga!e in PyQt4
/reating a co!puter ga!e is "ery challenging. +ooner or later' a progra!!er will
want to create a co!puter ga!e one day. In fact' !any people beca!e interested
in progra!!ing' because they played ga!es and wanted to create their own.
/reating a co!puter ga!e will "astly help i!pro"ing your progra!!ing skills.
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 59/69
Tetris
The tetris ga!e is one of the !ost popular co!puter ga!es e"er created. The
original ga!e was designed and progra!!ed by a russian progra!!erAlexey
Pa&itno"
in ;<?. +ince then' tetris is a"ailable on al!ost e"ery co!puter
platfor! in lots of "ariations. @"en !y !obile phone has a !odified "ersion of
the tetris ga!e.
Tetris is called a falling block puCCle ga!e. In this ga!e' we ha"e se"en
different shapes calledtetro!inoes
. +0shape' O0shape' T0shape' L0shape' Line0
shape' )irroredL0shape and a +9uare0shape. @ach of these shapes is for!ed with
four s9uares. The shapes are falling down the board. The ob&ect of the tetris
ga!e is to !o"e and rotate the shapes' so that they fit as !uch as possible. If
we !anage to for! a row' the row is destroyed and we score. (e play the tetris
ga!e until we top out.
-igure Tetro!inoes
PyQt4 is a toolkit designed to create applications. There are other libraries
which are targeted at creating co!puter ga!es. 1e"ertheless' PyQt4 and other
application toolkits can be used to create ga!es.
The following exa!ple is a !odified "ersion of the tetris ga!e' a"ailable with
PyQt4 installation files.
The de"elop!ent
(e do not ha"e i!ages for our tetris ga!e' we draw the tetro!inoes using the
drawing API a"ailable in the PyQt4 progra!!ing toolkit. ,ehind e"ery co!puter
ga!e' there is a !athe!atical !odel. +o it is in tetris.
+o!e ideas behind the ga!e.
• (e useQt/ore.Q,asicTi!er67
to create a ga!e cycle
• The tetro!inoes are drawn
• The shapes !o"e on a s9uare by s9uare basis 6not pixel by pixel7
• )athe!atically a board is a si!ple list of nu!bers
#!/usr/bin/python
# tetris.py
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 60/69
import sysimport ran"omfrom PyQt4 import Qt2ore QtGui
class *etris(QtGui.Q>ainin"o "ef --init--(self
QtGui.Q>ainin"o.--init--(self
self.setGeometry(1'' 1'' )M' 1M' self.setin"o*itle(+*etris+ self.tetrisboar" = 8oar"(self
self.set2entrali"get(self.tetrisboar"
self.statusbar = self.status8ar( self.connect(self.tetrisboar"Qt2ore.;G0A<(?message*o;tatusbar(Q;tring?
self.statusbar Qt2ore.;<6*(?sho>essage(Q;tring?
self.tetrisboar".start( self.center(
"ef center(self screen = QtGui.QBestopi"get(.screenGeometry( si$e = self.geometry( self.move((screen.i"th(Csi$e.i"th(/%
(screen.height(Csi$e.height(/%
class 8oar"(QtGui.Q5rame 8oar"i"th = )' 8oar"Ieight = %% ;pee" = 1''
"ef --init--(self parent QtGui.Q5rame.--init--(self parent
self.timer = Qt2ore.Q8asic*imer( self.isaitingAfter<ine = 5alse self.curPiece = ;hape( self.ne,tPiece = ;hape( self.curV = ' self.cur = ' self.num<inesDemove" = ' self.boar" = K
self.set5ocusPolicy(Qt2ore.Qt.;trong5ocus self.is;tarte" = 5alse self.isPause" = 5alse self.clear8oar"(
self.ne,tPiece.setDan"om;hape(
"ef shapeAt(self , y return self.boar"K(y O 8oar".8oar"i"th E ,
"ef set;hapeAt(self , y shape self.boar"K(y O 8oar".8oar"i"th E , = shape
"ef s9uarei"th(self return self.contentsDect(.i"th( / 8oar".8oar"i"th
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 61/69
"ef s9uareIeight(self return self.contentsDect(.height( / 8oar".8oar"Ieight
"ef start(self if self.isPause" return
self.is;tarte" = *rue self.isaitingAfter<ine = 5alse self.num<inesDemove" = ' self.clear8oar"(
self.emit(Qt2ore.;G0A<(?message*o;tatusbar(Q;tring?str(self.num<inesDemove"
self.nePiece( self.timer.start(8oar".;pee" self
"ef pause(self if not self.is;tarte"
return
self.isPause" = not self.isPause" if self.isPause" self.timer.stop( self.emit(Qt2ore.;G0A<(?message*o;tatusbar(Q;tring? ?pause"? else self.timer.start(8oar".;pee" self self.emit(Qt2ore.;G0A<(?message*o;tatusbar(Q;tring?
str(self.num<inesDemove"
self.up"ate(
"ef paint7vent(self event painter = QtGui.QPainter(self rect = self.contentsDect(
boar"*op = rect.bottom( C 8oar".8oar"Ieight O self.s9uareIeight(
for i in range(8oar".8oar"Ieight for in range(8oar".8oar"i"th shape = self.shapeAt( 8oar".8oar"Ieight C i C ) if shape != *etrominoes.0o;hape self."ra;9uare(painter rect.left( E O self.s9uarei"th( boar"*op E i O self.s9uareIeight( shape
if self.curPiece.shape( != *etrominoes.0o;hape for i in range(4 , = self.curV E self.curPiece.,(i y = self.cur C self.curPiece.y(i self."ra;9uare(painter rect.left( E , O self.s9uarei"th( boar"*op E (8oar".8oar"Ieight C y C ) Oself.s9uareIeight( self.curPiece.shape(
"ef eyPress7vent(self event if not self.is;tarte" or self.curPiece.shape( == *etrominoes.0o;hape
QtGui.Qi"get.eyPress7vent(self event return
ey = event.ey(
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 62/69
if ey == Qt2ore.Qt.Hey-P self.pause( return if self.isPause" return elif ey == Qt2ore.Qt.Hey-<eft self.try>ove(self.curPiece self.curV C ) self.cur
elif ey == Qt2ore.Qt.Hey-Dight self.try>ove(self.curPiece self.curV E ) self.cur elif ey == Qt2ore.Qt.Hey-Bon self.try>ove(self.curPiece.rotate"Dight( self.curV self.cur elif ey == Qt2ore.Qt.Hey-Wp self.try>ove(self.curPiece.rotate"<eft( self.curV self.cur elif ey == Qt2ore.Qt.Hey-;pace self."ropBon( elif ey == Qt2ore.Qt.Hey-B self.one<ineBon( else QtGui.Qi"get.eyPress7vent(self event
"ef timer7vent(self event if event.timer"( == self.timer.timer"( if self.isaitingAfter<ine self.isaitingAfter<ine = 5alse self.nePiece( else self.one<ineBon( else QtGui.Q5rame.timer7vent(self event
"ef clear8oar"(self for i in range(8oar".8oar"Ieight O 8oar".8oar"i"th self.boar".appen"(*etrominoes.0o;hape
"ef "ropBon(self ne = self.cur hile ne ' if not self.try>ove(self.curPiece self.curV ne C ) brea ne C= )
self.pieceBroppe"(
"ef one<ineBon(self if not self.try>ove(self.curPiece self.curV self.cur C ) self.pieceBroppe"(
"ef pieceBroppe"(self for i in range(4 , = self.curV E self.curPiece.,(i y = self.cur C self.curPiece.y(i self.set;hapeAt(, y self.curPiece.shape(
self.remove5ull<ines(
if not self.isaitingAfter<ine self.nePiece(
"ef remove5ull<ines(self num5ull<ines = '
ros*oDemove = K
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 63/69
for i in range(8oar".8oar"Ieight n = ' for in range(8oar".8oar"i"th if not self.shapeAt( i == *etrominoes.0o;hape n = n E )
if n == )' ros*oDemove.appen"(i
ros*oDemove.reverse(
for m in ros*oDemove for in range(m 8oar".8oar"Ieight for l in range(8oar".8oar"i"th self.set;hapeAt(l self.shapeAt(l E )
num5ull<ines = num5ull<ines E len(ros*oDemove
if num5ull<ines '
self.num<inesDemove" = self.num<inesDemove" E num5ull<ines self.emit(Qt2ore.;G0A<(?message*o;tatusbar(Q;tring?
str(self.num<inesDemove" self.isaitingAfter<ine = *rue self.curPiece.set;hape(*etrominoes.0o;hape self.up"ate(
"ef nePiece(self self.curPiece = self.ne,tPiece self.ne,tPiece.setDan"om;hape( self.curV = 8oar".8oar"i"th / % E ) self.cur = 8oar".8oar"Ieight C ) E self.curPiece.min(
if not self.try>ove(self.curPiece self.curV self.cur self.curPiece.set;hape(*etrominoes.0o;hape self.timer.stop( self.is;tarte" = 5alse self.emit(Qt2ore.;G0A<(?message*o;tatusbar(Q;tring? ?Game over?
"ef try>ove(self nePiece neV ne for i in range(4 , = neV E nePiece.,(i y = ne C nePiece.y(i if , 3 ' or , = 8oar".8oar"i"th or y 3 ' or y =8oar".8oar"Ieight return 5alse if self.shapeAt(, y != *etrominoes.0o;hape return 5alse
self.curPiece = nePiece self.curV = neV self.cur = ne self.up"ate( return *rue
"ef "ra;9uare(self painter , y shape
color*able = K','''''' ',22:::: ',::22:: ',::::22 ',2222:: ',22::22 ',::2222 ',BAAA''
color = QtGui.Q2olor(color*ableKshape
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 64/69
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 65/69
"ef setV(self in"e, , self.coor"sKin"e,K' = ,
"ef set(self in"e, y self.coor"sKin"e,K) = y
"ef minV(self m = self.coor"sK'K' for i in range(4 m = min(m self.coor"sKiK'
return m
"ef ma,V(self m = self.coor"sK'K' for i in range(4 m = ma,(m self.coor"sKiK'
return m
"ef min(self m = self.coor"sK'K) for i in range(4 m = min(m self.coor"sKiK)
return m
"ef ma,(self m = self.coor"sK'K) for i in range(4 m = ma,(m self.coor"sKiK)
return m
"ef rotate"<eft(self if self.piece;hape == *etrominoes.;9uare;hape return self
result = ;hape( result.piece;hape = self.piece;hape for i in range(4 result.setV(i self.y(i result.set(i Cself.,(i
return result
"ef rotate"Dight(self if self.piece;hape == *etrominoes.;9uare;hape return self
result = ;hape( result.piece;hape = self.piece;hape for i in range(4 result.setV(i Cself.y(i result.set(i self.,(i
return result
app = QtGui.QApplication(sys.argvtetris = *etris(
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 66/69
tetris.sho(sys.e,it(app.e,ec-(
I ha"e si!plified the ga!e a bit' so that it is easier to understand. The ga!e
starts i!!ediately' after it is launched. (e can pause the ga!e by pressing the
p key. The space key will drop the tetris piece i!!ediately to the botto!. The
ga!e goes at constant speed' no acceleration is i!ple!ented. The score is the
nu!ber of lines' that we ha"e re!o"ed.
self.statusbar = self.status8ar( self.connect(self.tetrisboar" Qt2ore.;G0A<(?message*o;tatusbar(Q;tring?
self.statusbar Qt2ore.;<6*(?sho>essage(Q;tring?
(e create a statusbar' where we will display !essages. (e will display three
possible !essages. The nu!ber of lines alredy re!o"ed. The paused !essage and
the ga!e o"er !essage.
... self.curV = ' self.cur = ' self.num<inesDemove" = ' self.boar" = K ...
,efore we start the ga!e cycle' we initialiCe so!e i!portant "ariables. The
self.board
"ariable is a list of nu!bers fro! $ ... D. It represents the
position of "arious shapes and re!ains of the shapes on the board.
for in range(8oar".8oar"i"th
shape = self.shapeAt( 8oar".8oar"Ieight C i C ) if shape != *etrominoes.0o;hape self."ra;9uare(painter rect.left( E O self.s9uarei"th( boar"*op E i O self.s9uareIeight( shape
The painting of the ga!e is di"ided into two steps. In the first step' we draw
all the shapes' or re!ains of the shapes' that ha"e been dropped to the botto!
of the board. All the s9uares are re!e!berd in theself.board
list "ariable.
(e access it using the shapeAt67 !ethod.
if self.curPiece.shape( != *etrominoes.0o;hape for i in range(4 , = self.curV E self.curPiece.,(i y = self.cur C self.curPiece.y(i self."ra;9uare(painter rect.left( E , O self.s9uarei"th( boar"*op E (8oar".8oar"Ieight C y C ) O self.s9uareIeight( self.curPiece.shape(
The next step is drawing of the actual piece' that is falling down.
elif ey == Qt2ore.Qt.Hey-<eft self.try>ove(self.curPiece self.curV C ) self.cur elif ey == Qt2ore.Qt.Hey-Dight
self.try>ove(self.curPiece self.curV E ) self.cur
In thekeyPress@"ent
we check for pressed keys. If we press the right arrow
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 67/69
key' we try to !o"e the piece to the right. (e say try' because the piece !ight
not be able to !o"e.
"ef try>ove(self nePiece neV ne for i in range(4 , = neV E nePiece.,(i y = ne C nePiece.y(i
if , 3 ' or , = 8oar".8oar"i"th or y 3 ' or y = 8oar".8oar"Ieight return 5alse if self.shapeAt(, y != *etrominoes.0o;hape return 5alse
self.curPiece = nePiece self.curV = neV self.cur = ne self.up"ate( return *rue
In thetry)o"e67
!ethod we try to !o"e our shapes. If the shape is at the edge
of the board or is ad&acent to so!e other piece' we return false. therwise weplace the current falling piece to a new position.
"ef timer7vent(self event if event.timer"( == self.timer.timer"( if self.isaitingAfter<ine self.isaitingAfter<ine = 5alse self.nePiece( else self.one<ineBon( else QtGui.Q5rame.timer7vent(self event
In the ti!er e"ent' we either create a new piece' after the pre"ious one was
dropped to the botto!' or we !o"e a falling piece one line down.
"ef remove5ull<ines(self num5ull<ines = '
ros*oDemove = K
for i in range(8oar".8oar"Ieight n = ' for in range(8oar".8oar"i"th if not self.shapeAt( i == *etrominoes.0o;hape
n = n E )
if n == )' ros*oDemove.appen"(i
ros*oDemove.reverse(
for m in ros*oDemove for in range(m 8oar".8oar"Ieight for l in range(8oar".8oar"i"th self.set;hapeAt(l self.shapeAt(l E ) ...
If the piece hits the botto!' we call there!o"e-ullLines67
!ethod. -irst we
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 68/69
find out all full lines. And we re!o"e the!. (e do it by !o"ing all lines abo"e
the current full line to be re!o"ed one line down. 1otice' that we re"erse the
order of the lines to be re!o"ed. therwise' it would not work correctly. In our
case we use anai"e gra"ity
. This !eans' that the pieces !ay be floating abo"e
e!pty gaps.
"ef nePiece(self self.curPiece = self.ne,tPiece self.ne,tPiece.setDan"om;hape( self.curV = 8oar".8oar"i"th / % E ) self.cur = 8oar".8oar"Ieight C ) E self.curPiece.min(
if not self.try>ove(self.curPiece self.curV self.cur self.curPiece.set;hape(*etrominoes.0o;hape self.timer.stop( self.is;tarte" = 5alse self.emit(Qt2ore.;G0A<(?message*o;tatusbar(Q;tring? ?Game over?
ThenewPiece67
!ethod creates rando!ly a new tetris piece. If the piece cannotgo into it>s initial position' the ga!e is o"er.
The+hape
class sa"es infor!ation about the tetris piece.
self.coor"s = KK'' for i in range(4
pon creation we create an e!pty coordinates list. The list will sa"e the
coordinates of the tetris piece. -or exa!ple' these tuples 6$' 0;7' 6$' $7' 6;'
$7' 6;' ;7 represent a rotated +0shape. The following diagra! illustrates the
shape.
-igure /oordinates
(hen we draw the current falling piece' we draw it atself.cur3
'self.curJ
position
. Then we look at the coordinates table and draw all the four s9uares.
8/18/2019 Introduction to PyQt Toolkit
http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 69/69
-igure Tetris