introduction to pyqt toolkit

69
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 by Phil 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 The Qt/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. The QtGui  !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

Upload: alex

Post on 06-Jul-2018

279 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: Introduction to PyQt Toolkit

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

Page 2: Introduction to PyQt Toolkit

8/18/2019 Introduction to PyQt Toolkit

http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 2/69

Page 3: Introduction to PyQt Toolkit

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

Page 4: Introduction to PyQt Toolkit

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

Page 5: Introduction to PyQt Toolkit

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.

Page 6: Introduction to PyQt Toolkit

8/18/2019 Introduction to PyQt Toolkit

http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 6/69

Page 7: Introduction to PyQt Toolkit

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&

Page 8: Introduction to PyQt Toolkit

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

Page 9: Introduction to PyQt Toolkit

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

Page 10: Introduction to PyQt Toolkit

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

Page 11: Introduction to PyQt Toolkit

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-(

Page 12: Introduction to PyQt Toolkit

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

Page 13: Introduction to PyQt Toolkit

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-(

Page 14: Introduction to PyQt Toolkit

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

Page 15: Introduction to PyQt Toolkit

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!.

Page 16: Introduction to PyQt Toolkit

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

Page 17: Introduction to PyQt Toolkit

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

Page 18: Introduction to PyQt Toolkit

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

Page 19: Introduction to PyQt Toolkit

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.

Page 20: Introduction to PyQt Toolkit

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

Page 21: Introduction to PyQt Toolkit

8/18/2019 Introduction to PyQt Toolkit

http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 21/69

Page 22: Introduction to PyQt Toolkit

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.

Page 23: Introduction to PyQt Toolkit

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

Page 24: Introduction to PyQt Toolkit

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

Page 25: Introduction to PyQt Toolkit

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

Page 26: Introduction to PyQt Toolkit

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+

Page 27: Introduction to PyQt Toolkit

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

Page 28: Introduction to PyQt Toolkit

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.

Page 29: Introduction to PyQt Toolkit

8/18/2019 Introduction to PyQt Toolkit

http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 29/69

Page 30: Introduction to PyQt Toolkit

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.

Page 31: Introduction to PyQt Toolkit

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

Page 32: Introduction to PyQt Toolkit

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.

Page 33: Introduction to PyQt Toolkit

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

Page 34: Introduction to PyQt Toolkit

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

Page 35: Introduction to PyQt Toolkit

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

Page 36: Introduction to PyQt Toolkit

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.

Page 37: Introduction to PyQt Toolkit

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+

Page 38: Introduction to PyQt Toolkit

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

Page 39: Introduction to PyQt Toolkit

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

Page 40: Introduction to PyQt Toolkit

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

Page 41: Introduction to PyQt Toolkit

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.

Page 42: Introduction to PyQt Toolkit

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

Page 43: Introduction to PyQt Toolkit

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(

Page 44: Introduction to PyQt Toolkit

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

Page 45: Introduction to PyQt Toolkit

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

Page 46: Introduction to PyQt Toolkit

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

Page 47: Introduction to PyQt Toolkit

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"(

Page 48: Introduction to PyQt Toolkit

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"(

Page 49: Introduction to PyQt Toolkit

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

Page 50: Introduction to PyQt Toolkit

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

Page 51: Introduction to PyQt Toolkit

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'

Page 52: Introduction to PyQt Toolkit

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.

Page 53: Introduction to PyQt Toolkit

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' :'

Page 54: Introduction to PyQt Toolkit

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.

Page 55: Introduction to PyQt Toolkit

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

Page 56: Introduction to PyQt Toolkit

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

Page 57: Introduction to PyQt Toolkit

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(

Page 58: Introduction to PyQt Toolkit

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.

Page 59: Introduction to PyQt Toolkit

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

Page 60: Introduction to PyQt Toolkit

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

Page 61: Introduction to PyQt Toolkit

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(

Page 62: Introduction to PyQt Toolkit

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

Page 63: Introduction to PyQt Toolkit

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

Page 64: Introduction to PyQt Toolkit

8/18/2019 Introduction to PyQt Toolkit

http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 64/69

Page 65: Introduction to PyQt Toolkit

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(

Page 66: Introduction to PyQt Toolkit

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

Page 67: Introduction to PyQt Toolkit

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

Page 68: Introduction to PyQt Toolkit

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.

Page 69: Introduction to PyQt Toolkit

8/18/2019 Introduction to PyQt Toolkit

http://slidepdf.com/reader/full/introduction-to-pyqt-toolkit 69/69

 

-igure Tetris