Tải bản đầy đủ (.pdf) (45 trang)

The book of qt 4 the art of building qt applications - phần 2 docx

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (940.72 KB, 45 trang )

1 Basics,Tools, and First Code
#include <QtGui>
However,these libraryheaderfilesare verylong,which considerablyincreasesthe
length of thecompilingprocess.Thiswon’t be aproblemifthe compilersupports
precompiledheaderfiles, butonlythemorerecentcompilers do (suchaswithGCC
from version 3.4on).
TheBaseLibraryQtCore
QtCoreisapartiallibraryrequired byeveryQt program.Among otherthings, it
makesavailable thefollowing:
Basic datatypes, such as QStringand QByteArray
Basicdatastructures, such as QList, QVector, andQHash
Input/output classessuchasQIODevice, QTextStream, andQFile
Classeswithwhich multiplethreads can be programmed(includingQWaitCon-
dition andQThread)
TheclassesQObject andQCoreApplication(thebaseclass for QApplication)
None of theseclassesdepends on GUI components.Thisseparationfromthe GUI
allowsQtapplications (suchascommand-lineprograms) to be written that do not
implementaGUI
In nongraphical programs theQCoreApplicationclass takesonthe role of theQAp-
plicationclass in GUI applications:Itmakesaneventloop available.Thisisuseful
if you requireasynchronouscommunication,whether between different threads or
via networksockets.
11
TheGUI LibraryQtGui
TheQtGui librarycontains allclassesthatare necessaryfor program ming graph ical
user in terfaces,including thefollowing:
TheQWidgetclass andclassesderived from it,suchasQLabeland QPushButton
Thelayoutclasses(includingQVBoxLayout, QHBoxLayout, andQGridLayout)
ClassessuchasQMainWindowandQMenu, which areneeded if you wanttoadd
menus to an application
11


QtCore doesnot containanynetworkclasses, butthe QtNetworklibrarycanbeusedwith
QtCore if networking is required.
44
1.5 Qt at aGlance
Classesfor drawing, such as QPainter,QPen, andQBrush
Classesprovidingready-to-usedialogs (including QFileDialog andQPrintDialog)
TheQApplicationclass
QtGui requires theQtCorelibrary.
TheNetworkLibraryQtNetwork
Thepartial libraryQtNetworkprovides classesfor writing networkapplications.
In addition to supporting simple socketcommunication via theQTcpSocketand
QUdpSocketclasses, this libraryalso enablesclient-sideHTTP andFTP withQHttp
andQFtp.
UnlikeQtGui,QtNetworkrequiresthe QtCorelibrary,but it can,ofcourse, be used
together withQtGui andthe otherlibraries.
TheOpenGLLibraryQtOpenGL
TheQtOpenGL libraryenablesOpenGLtobeusedinaQt program.Itprovides the
QGLWidgetclass—aQtwidgetinwhich you can drawusingOpenGLcommands.
QtOpenGL uses theQtCoreand QtGui libraries.
TheDatabaseLibraryQtSql
TheQtSql libraryclassesprovideaccess to SQLdatabases in Qt programs. This library
includes classesthatare used to establishaconnectionwithanSQL databaseand
to queryandmodifydata.Qtsupports arange of SQLdatabases,including the
opensourcedatabases PostgreSQL,MySQL, andSQLite.
QtSqlrequiresthe QtCorelibrary,and it is discussedatlengthinChapter 9(page
257).
TheXML LibraryQtXml
Asimple, nonvalidatingXML parser is provided bythepartial libraryQtXML.Itcan
be addresseddirectlythroughaSAX2 interface(SimpleAPI forXML).
QtXml also contains an implementation of theDOM standard(Document Ob ject

Model ). Thecorresponding classesallowyou to parse an XMLdocument,manipu-
late itstreestructure,publishthe modifieddocument againasanXML document,
or to create anewXMLdocument withDOM.
45
1 Basics,Tools, and First Code
This libraryrequires onlytheQtCorelibrary,and it is discussedinmoredepth in
Chapter 13 (page 353).
TheCompatibilityLibraryQt3Support
Comparedwithits predecessor, Qt 3, Qt 4has undergoneconsiderable develop-
ment:Someclassescontain changesthatare incompatible withthe Qt 3versions,
andothershavebeen replaced in Qt 4withcompletelynewclasseswithdifferent
names. In ordertosimplifytheporting of Qt 3programstoQt4,Trolltechincludes
thecorresponding Qt 3classesinthe Qt3Supportlibrary.However,you should not
usethislibraryfor newprograms, sincedevelopmentoftheir classeshas stopped.
Since this book explains programming withQt4,wewillnot usethese classesand
willnot discussthemfurther.
TheVectorGraphicsLibraryQtSvg
TheSVG vectorgraphicsformat, publishedbytheW3consortiumand basedon
XML, hasgreat potential.FromQt4.1 onwardthe QtSvglibrarysupports theSVG
profiles SVGBasic and SVGTiny,
12
which can be used to displaySVGfilesand
animations,althoughitcannotasyet create them or,asinXML,manipulatethem
throughaDOM tree.
TheQtAssistantClientLibrary
Theassistantclient libraryallowsyou to remotelycontrolthe Qt assistantapplica-
tion.Thisallowsyou to usethe assistantasaplatform-independenthelpbrowser
for yourapplication. Theheart of themodule is theQAssistantClient class.
Customized help pagesfor usewithQtassistantare provided in basicHTMLmarkup,
alongwithanXML filethatdescribesthe structureofthe documentation.

TheTestCaseLibraryQTestLib
Originallyreleased outsidethe Qt core distribution for payingcustomers, QTestLib
entered theregular Qt distribution starting withthe Qt 4.1.0release. Thelibrary
contains facilitiestowrite properunittests for newlywritten classes, andcoversa
scope similartoJUnit in Java.
12
See />46
1.5 Qt at aGlance
TheQtDBusLibrary
DBus is amessaging protocol that hasemerged as adefactostandardonLinuxand
otherUnixderivates.For instance,the LinuxHardwareAbstractionLayer (HAL)and
theupcomingKDE 4are usingDBusfor interprocesscommunication.Even though
ports for Windowsand MacOSXexist, Qt 4.2willoffertobuild this libraryonlyon
Unix.Thismay,however,changeinfutureversions.
ActiveQt andMigration Classes
Theplatform-specificextension ActiveQt for Windowsmakesitpossible to imple-
ment ActiveXcomponents withQtand to usetheminQtprograms. It is available
onlyin thecommercialQtdesktop edition, however.
Trolltechalsoprovides migrationsolutions for MFC-,Motif-, andXt-basedappli-
cations. Like ActiveQt,however,theyareavailable onlyas separatecommercial
add-ons for Qt 4, the Qt Solutions ,
13
andwillnot be discussedinthisbook.
1.5.2Toolsand Utilities
In addition to allthis, Qt includes threeGUI programsthatcan be used to display
Qt documentation, create dialogs accordingtothe WYSIWYGprinciple ( What You
See Is What YouGet), or translateprogramsintoother languages. Thetoolkitalso
provides aseriesofcommand-lineprogramsfor performing various tasks.
TheDocumentation Browser“Qt Assistant”
TheQtdocumentationconsistsofsimpleHTMLfilesthatcan be viewed withany

web browserorwiththe Qt Assistant. Unlikeaweb br owser, theAssistantdisplays
an indexof theentireQtdocumentationand allowsfor afull-textsearchofthat
documentation(Figure 1.10).
TheAssistant’skeyworddirectoryis particularlyuseful whenworking wit hQtdaily.
Forexample, if you requiredocumentationonaclass, on QLabel,simplyenter qlabel
in theindexinputbox.With




Enter you aretakenimmediatelyto theexcellent class
documentation.
13
See />47
1 Basics,Tools, and First Code
Figure 1.10:
TheQtAssistant
displays theQt
documentation.
TheAssistantisanimportant complement to this book because it notonlydoc-
umentsnewlyaddedAPI calls (oronesnot discussedinthisbook duetolack of
space), butalsoprovides additionalusage examples.
14
TheGUI Editor “QtDesigner”
TheQtDesignerallowsyou to create applicationdialogs andthe main application
windowin aWYSIWYG fashion(Figure 1.11),which is particularlyuseful when
creating complexdialogs andlayouts.You can addwidgets in theDesignervia
drag anddropand settheir properties. Forexample, you can chan ge thetextofa
QLabel or itscolor andtypeface.
Youcan usethe Designer to combineseveral widgets in alayout, andimmediately

seethe effect that thelayouthas on thewindow.You can even setupsignal/slot
connections between th ewidgets andthe Designer,ifnecessary.
TheDesigner’spreviewmode allowsyou to checkthe GUIsyou’vecreated:You can
seehowthelayouts react to changesinsize, testthe widgets,and seewhether the
signal/slotconnections havethe desiredeffects.
TheDesigneralsohas amode that specifies the tabsequence of thewidgets;that
is,the orderinwhich theuseraccessesthe individualwidgets whenpressing




tab
repeatedly.Thisisanimportant aspect of auserinterface, andone that you should
alwayscheck. Aprogram can onlybe operated intuitivelyfrom thekeyboardifthe
14
Forthose who prefer to read it in th eweb browser, theQtclass documentationcan be found
on theTrolltechwebsite at ht tp://doc.trolltech.com/.
48
1.5 Qt at aGlance
tabsequencemakessense.Notethatifyou do notset thesequenceyourself, Qt
sets it automatically,which maynotalwaysleadtodesirable results.
Figure 1.11:
Thetoolsofthe
Designer as multiple
top-level windows
In ordertouse dialogs created withDesignerinanapplicationprogram,you will
need aseparat econversi on program.The Qt Designersaves thedescription of the
draftversionsofaninterfaceinaseparateXML-formatted filewiththe filename
extension .ui. To usethisinterfaceinaprogram,C++ code mustbecreated from
theXML descriptionwiththe command-linetool uic(UserInterface Compiler ).

If you useqmake to create aproject,uic can be used to integrate aDesigner-created
interfaceveryeasily:Each .uifile to be used is added to theFORMSvariable byaline
in the.profile.For example, thefollowinglineinthe .pro fileadds thedescription
of thedialogfrommydialog.ui to theproject:
FORMS +=mydialog.ui
qmakethencreates acorresponding rule that generates theC++ fileui_mydialog.h
from mydialog.ui,using uic. Thelatter contains theinterfacedescription of the
code that implements thedialog. (Weexplainthisfile andits useinthe rest of the
code for theapplicationprogram in more detail in Chapter 3onpage 91.)
TheTranslation Tool “QtLinguist”
Qt Linguist is used to translateapplicationprogramsfromone language to another.
As aseparateGUI tool it allowsyou to integrate language translatorsinthe work
processofasoftwareproject more easily.LikeQtDesigner, Qt Linguist is used in
conjunction withexternalcommand-lineprograms, namelylupdateand lrelease,
to updatethe binariesofasoftwareproject andreplace thewords andphrases
49
1 Basics,Tools, and First Code
that aredisplayed to theuserwiththeir equivalents in adifferent language.lup-
dateextractsthe texts to be localized from thesourcecode of theprogram an d
generates translationfilesaccordingtoadefinition given in theproject file:
TRANSLATIONS =application_fr.ts \
application_nl.ts
TheGUI applicationLinguistserves as agraphical utilitywhentranslating (i.e., edit-
ing) thetranslation files generated in this way(Figure1.12).Finally,lreleasecreates
additionalbinaryfiles containing thetranslationsthatthe application, on request,
willload at startup, andhence appear translated.Byusinglupdate, Linguist,and
lrelease together in this way,the applicationcode doesnot havetoberewritten
andrecompiledinorder to produce arelease that supports anotherlanguage.
In orderfor allthistowork, thesourcecode of theapplicationmustfollowcertain
conventions. Specifically,strings representing textthatistobetranslated mustbe

passedontothe functionsQObject::tr()orQApplication::translate(). This accom-
plishestwothings.
It allowsQttochangestrings dynamically.Ifyou specifyonlythestring"Hello,
world!" in thesourcecode,thenonlythis will be used whenthe application
runs.But if you send thestringfirstthrough theQObject function tr() or to the
translate()function of theQApplicationclass,thenthisfunction willlook up the
translationand return astringcontainingit, which willbeusedinsteadofthe
original "Hello,world!".
It allowsthe lupdateutilityto look for such function calls an dthus identify
passagesinthe source code that aretobetranslated.
Figure 1.12:
TheQtLinguist
enables applications
to be translatedinto
other languages.
50
1.5 Qt at aGlance
Unfortunately,the simple “Hello,world!” program from Section1.1 cannotbe
translated into otherlanguages, sinceweusedneither tr() nortranslate()for the
string "Hello,world!".Torectifythis shortcomingwereplace theline
QLabel label("Hello, world!");
with
QLabel label(QApplication::translate("MyLabel","Hello, world!"));
Thefunction QApplication::translate()takesasthe first argument acontextlabel
for thetext, whereas theQObject::tr()function theclass name of thewidgetin
question is automaticallyused as thecontextlabel.
15
If, for example, you callup
tr() for aQLabelobject,Qtautomaticallyuses thecontextnameQLabel. This is
possible because QLabel is derived from QObject as thebaseclass andtherefore

inherits thetr()function.
Thecontextlabel is important because thesametextmayappearinseveral places,
withdifferent meanings.Ifthe target language uses distinct terms for thesevaria-
tions, theappropriate translations for theinstances of original textwill depend on
thecontext. Forexample, theEnglishtextOpenmayoccurinone dialog withthe
meaning openfile,but in anotherdialogwiththe meaning openInter netconnec-
tion;the German version of theprogram should render thefirstinstanceasÖffnen
andthe second as Aufbauen. When thetwoinstances aregiven different context
labels,QtLinguistcan distinguishthem.
Youshouldsendall textinyourprogram throughthe tr() or translate()function.
Youwillfind that theprogram can generallybe translated without greatdifficulty
whenitisdoneduringcode development, andthatitisverytedious to go through
theentiresourcetextofalargeprogram byhand andadd tr() or translate()calls
once thecoding is finished. Theexampleprogramsinthe remainderofthisbook
thereforewilluse tr() rightfromthe beginning.
(You ’ll finddetails on internationalizationand localizationinChapter 14.)
Creating theProject
As demonstrated in Section1.1.1,qmake creates platform-specificMakefiles from
system-independent projectfiles. Therules stored in theMakefile, make,ornmake
arethenusedtocompile andlinkthe application. nmake,however,onlyworks with
thecommercialQtversion,not withthe opensourceedition.
16
TheGPL variant of
15
Seealsopage380.
16
TheEULAofVisualStudioisincompatible withthe GP Lanywayonce thelibrariesfromVisual
Studio areincluded.
51
1 Basics,Tools, and First Code

Qt 4for Windowsusesthe GCCportMinGW,which insteadofnmake provides the
GNUmake knownfromLinux.
qmakeproject files don’t requireustoworryabouteitherthe compilerorlinker
options.For th is reason wewilluse qmakefor allthe examples in this book.
In Windowsyou can also create projectfilesfor Microsoft Visual Studio withqmake,
if you ownacommercialQtlicense.(TheQtintegration doesnot function in
thefreevariant of Visual Studio Express; th eseusers arealsodependent on the
command-line–basedversion,qmake.)
Figure 1.13:
Code::Blocksbuilds
our“Hello,world!”
program.
Foropensourcedevelopers in Windows, thedevelopmentenvironment Code::
Blocks
17
provides ausefu lalternative. It works together withthe MinGWincluded
in Qt, andeven hasatemplate for Qt 4projects. In orderfor it to worktogether
withqmake,however,you first havetostopitfromgeneratingthe Makefileitself.
To do this,selectProject→ Propertiesand mark theoptionThisisacustom Makefile.
Then look for thedialogunder Project → Build options andactivatethe Commands
tab. Then,inthe Pre-build stepsfield, enter thefollowingcommands:
qmake -project
qmake
make.bat
17
See />52
1.5 Qt at aGlance
To ensure that qmake is calledeven whenoth er programs(such as theQtDesigner)
add newfiles,selectthe optionAlwaysexecute, even if target is up-to-date. Figure
1.13 showsCode::Blocks after the“Hello,world!” program hasbeen compiled.

It is useful to storethe menu itemsfor starting theDesigner, theAssistant, or make
in theToolsmenu. Youcan also usethis, to acertain extent, to quicklystartyour
ownprograms, which you can specifyin thesubitem Configure tools
Figure 1.14:
Apple’s Xcode IDE
enables efficient
projectmanagement,
forwhich qmake
generates the
necessary files.
On MacOSX,the preferreddevelopmentenvironment is theXcode IDE. Apple
provides this softwarefreeofchargesince OS Xversion 10.3 (Panther), butitneeds
to be installedseparately.qmake on theMac convenientlycreates projectfilesfor
Xcode insteadofMakefiles.However,ifyou prefer to avoidXcode andrelyon
command linetoolsonly,simplyappend-spec macx-g++ to generate aMakefile:
qmake-spec macx-g++
In contrast,
qmake -spec macx-xcode
willcause qmaketogenerateMac OS Xproject files for Xcode in allQteditions.
qmakegenerates an Xcode projectfroma.pro file, which then turnsupinthe
projectmanagement tool of Xcode.
qmake -spec macx-g++
creates aMakefilefor direct usewithGCC.
When creating yourapplicationunder Linux,the developmentenvironment KDe-
velop
18
is probablythebestchoice. Version3.4 provides supportfor Qt 4projects.
KDevelop includes both,aprojecttem plateand agraphical management utilityfor
qmakeproject files,which can be integrated seamlesslyinto theIDE.
18

See />53
1 Basics,Tools, and First Code
Upon first startup, KDevelop willpresent an almost blank main window.Choosing
Project → NewProjectwillstart theproject wizardwhich guides throughthe initial
stepsofcreatingaKDevelop-basedproject.TocreateaQt 4project that uses
qmake, select C++ → QMake project → BasicQt4 applicationfromthe treeviewas
showninFigure1.15. Forthe first step to complete, thewizardalsoneedsaname
for theapplication, as wellasadirectorylocation to storeall files in.
Figure 1.15:
KDevelop provides a
qmake -based project
support.
In thenextstep,KDevelop asks for thenameofthe defaultauthor, an initialversion
number,and thelicense for theproject.Alsoitisimportant that you specifythe
full pathtothe Qt 4versionsofqmake anddesignerinthisstep.Thisensures that
KDevelop willnot pick theQt3version byaccidentifbothare installedinparallel.
Thenextstep allowsyou to pick asourcecode control. If you arenot usingsource
code management system,justkeep theNonedefault.The remainingstepsallow
for customizingthe templates th at areinserted into allheaderand implementa-
tion files.These usuallycontainthe license as wellasthe author’s name.Figure
1.16 showsamainwindowwiththe examplemain.cppfile after thewizardhas
completed.
54
1.5 Qt at aGlance
Pressing




Shift+F9 willbuild an dexecuteagiven project; thetextual output is visible

in theMessagesand Applicationtab on thebot tom, which willautomaticallyopen
during build andexecutionphases, respectively.
Figure 1.16:
TheKDevelop main
window afterthe
setup
Theqmake-project manager(QMakeManager)ishiddenbehindatabonthe right
bearingthe Qt symbol.Upon expansion,you can useittographicallyadd,re-
move, or openfiles. Theproject managerviewseparates between different types
of sources: KDevelop opens anewtabfor commonsourcefiles, while ui files are
automaticallylaunchedwiththe Qt Designer.
Figure 1.17:
TheKDE editor Kate
canquickly be
convertedtoa
powerfulsourcecode
editor.
Agood alternativefor thosewho dislikeafullblownIDE is theKateeditor(KDE
Advanced Text Editor), which includes apull-downmenufromwhich you can run
55
1 Basics,Tools, and First Code
thecompilerdirectly,asshowninFigure1.17. Dependingonyourdistribution,you
maywan ttoinstall thekate-pluginspackage first which—among others—provides
apluginfor code completion.Equippedthisway,Kategives an overviewof meth-
ods andmembervariablesinCandC++ files,and even allowsfor code snippet
administrationunder Settings → Configure Kate→ Application → Plugins.
Kate’ssetupdialogprovides asubitem,ExternalTools, in which you can storeyour
owncommands, as withCode::Blocks,which then appearunder Tools → External
Tools. Settings → Configure Shortcutslists keyboardshortcuts.
TheMeta-object Compiler moc

Thesignal/slot conceptinQtisnot pure C++, butratheranextension of theC++
standard. Forthisreasonthe command-lineprogram moc(meta objectcompiler )
is used to convertthe signal andslotconstructsintostandardC++. mocgener-
ates additionalC++ code for each classderived from QObject.Thisensures that
signal/slotconnections can be dynamicallygenerated at runtime. It also allowsthe
namesofclassesthathaveQObject as abaseclass to be dynamicallydeterminedat
runtime, andeven to determine whether aclass is abaseclass for an otherclass.
19
Qt also includes a propertysystem,for which mocgenerates thenecessarycode.
Propertiesare specialcharacteristics of aclass that can be queriedand set. For
example, theQLabelclass hasatextproperty,whose value is astringcontaining
thetextthatthe labeldisplays. Foreach propertythereare twofunctions: onethat
reveals itscurrent value,alsocalledthe getmethod ,and onethatchanges it,also
knownasthe set method.Inthe caseofQLabel, text()isthe getmethod returning
thelabel’s text, andsetText()isthe setmeth od providingthe labelwithanewtext.
Thesetwofunctions, marked in theclass definitionasproperties, allowthetext
to be queriedvia QObject::property() andbeset withQObject::setProperty(). Both
requir eastring,namely,the name of theproperty,asanargument.The Property
Editor of theDesignerdeterminesthe value of propertiesatruntimeand allows
thesepropertiestobechanged.Ifyou requirepropertiesinaseparateclass,these
mustbederived from QObject.
In short, mocisneeded whenever aclass uses QObject as abaseclass.The meta-
object compilermustpreprocesseveryfilethatimplementsthe definitionofsuch
aclass beforethe C++com pilerisrun. In each casethiscreates afile beginning
withthe prefixmoc_.
Forexample, if you write yourowndialogclass MyDialog withQObject as abase
class, withthe classdefinition in thefile MyDialog.h an dthe actualimplementation
19
By baseclass wemean notjustthe classfromwhich aclass is directlyderived,but all classesin
theinheritancesequencebeginning from aroot of theclass hierarchy.Thus QVB oxLayouthas

threebaseclasses(QBoxLayout, QLayout, andQObject), becauseQLayoutinherits from QObject,
QBoxLayoutfromQLayout, andQVBoxLayoutfromQBoxLayout.
56
1.5 Qt at aGlance
in MyDialog.cpp, themeta-object compilerhas to processMyDialog.h,thengener-
atethe filemoc_MyDialog.cpp, andintegrate thegenerated fileintothe complete
project. qmakedoesall of this automatically.
TheQtResources Compiler rcc
Almost everyprogram uses externalresources such as imagesorgraphics. These
resourcescan either lie in separatefilesorbeembeddeddirectlyin theexecutable
files to be generated.Qt4uses theresources compiler rcc for generated files.
Theresourcecompilerobtains itsinformation from resource descriptionfiles, the
namesofwhich endinthe exten sion .qrc.A.qrc filespecifiesfilesystem paths to
resourcesusedbytheprogram,beginning from thedirectoryin which the.qrcfile
resides.
If you includethe resource fileinthe qmakeproject,Qtautomaticallygenerates
arraysencodedinhexadecimalform, in which it stores thecontents of theresource
files.The Qt resource system en suresthatthe applicationprogram can accessthe
resourcesencodedinthiswayusingthe olddirectoryandfile names. A.qrcfile
describes(usingXML)which files areneeded bythefinished program.Itlooks
somethinglikethis:
<RCC>
<qresource>
<file>pics/symbols/stop.png</file>
<file>pics/symbols/start.png</file>
<file>pics/symbols/pause.png</file>
</qresource>
</RCC>
Thepathdetails arealwaysunderstood as relativetothe directoryin which the
resource fileislocated.For th is exam pleweassume that theaboveresourcefile is

calledsymbols.qrcand that thedirectorypics/symbols, which contains therequired
images, is beneaththe direct orywiththe source code (including theresourcefile).
In orderfor qmaketobeable to take theinformation from theresourcefile into
account,acorresponding RESOURCESdirectivemustbeaddedtothe projectfile:
RESOURCES =symbols.qrc
Theimage filestop.pngunder pics/symbolscan nowbe referenced in theapplica-
tion code as follows:
myLabel->setPixmap(QPixmap(":/pics/symbols/stop.png"));
That is,inorder to refertoaresource, you need onlyplaceacoloninfront of the
pathdetails specified in the.qrcfile.(Theleading slashisnot atypo; relativepaths
57
1 Basics,Tools, and First Code
in thefile system arespecifiedinthe logical pathnotationasabsolutepaths,with
thecode directoryas theroot.) If theresourcedescription fileisproperlyintegrated
into theproject,acalltoQPixmap()can correctlyresolvethe path, andthe label
willdisplayastopicon.
Afile in aresourcecan also be addressedwithalogical pathcompletelydifferent
from itsactualfile system path, as shownhere:
<RCC>
<qresource prefix="/player">
<file alias="stop.png">pics/symbols/stop.png</file>

</qresource>
</RCC>
Theprefixattribute for theqresource tagspecifiesaprefixto be used beforethe
pathdetails,whereas thealiasattribute specifies an alternativenameorpaththat
can be used insteadofthe actualpathdetails.Withthe combinationshownabove,
thestopiconcan nowalso be addressedinthe applicationcode as follows:
myLabel->setPixmap(QPixmap(":/player/stop.png"));
With thehelpofthe lang attribute andalternativeqresource entries, thesystem

can load othergraphicsdepending on thecurrent language setting:
<RCC>
<qresource>
<file>pics/symbols/stop.png</file>

</qresource>
<qresource lang="de">
<file>pics/symbols/de/stop.png</file>

</qresource>
</RCC>
Beginning withversion 4.1, Qt DesignerincludesaResource Editor (see page 99).
Unfortunately,inQt4.1.0this doesnot displaytherelativepaths to theindividual
resources, norwillithandlethe aliasattribute. Therefore, you should alwayscheck
theresourcedescription filethatisgenerated.
1.5.3Examplesand Demos
Acomplete Qt installation contains aseriesofexampleprogramsinthe examples
direct oryan dseveral demo programsinthe demo folder.
58
1.6 HowtoUse the Documentation
Theexampleprogramsare of particular help if you haveproblems usingspecific Qt
classes, whereas thedemoprogramsmainlydemonstrateall thethingsthatQtcan
do andare notappropriate as areference for howto usethe classlibraries.
1.6How to Usethe Documentation
TheHTMLdocumentationincludedbyTrolltechisrecommended as aconstantcom-
panioninQtprogramming,especiallybecause it describesall Qt classesindetail.
Also,you mayfinditusefulwhenreading this book to look up thedocumentation
for theclassesusedinthe various examples.
When Qt Assistantstarts, theprogram automaticallyloads thestart page doc/html/
index.html(Figure 1.10on page 48);itcan also be viewed in anyweb browser, and

is available on line.
20
In addition to theprecise documentationofthe Qt classes
alreadymentioned, thedocumentationincludesintroductorytexts;overviewsof
thesignal/slot concept, layouts,and theSQL,network, XML, andOpenGLmodules;
anddetaileddescriptionsofthe toolsand utilities.
Figure 1.18:
Theclass
documentationofthe
QWidget class
Theclass documentationiswhatismostfrequentlyused in day-to-dayworkwith
Qt. If you knowtheclass names, you can enter them in theIndextabofthe
Assistant. From thestart page you can also accessalistofall classesand alist
groupedaccordingtotopics.
20
ForQt4.1,see />59
1 Basics,Tools, and First Code
Thedocumentationofeach classbeginswithashortdescription of whatthe class
does, followed bythenameofthe headerfile that needstobeintegrated in order
to useit. ThekeywordInherits reveals from which direct base classesthe classis
derived,Inherited bylists theclassesthatinheritfromthisone (Figure1.18).
This information is followed byalistofthe functionsofthe classwhich is divided
into several categories. Thesecategoriesinclude theget andset methods for prop-
erties of theclass,public andprotected fu nctions, signals, andslots.
Onlythefunctionsthatare defined in theclass itself appearinthislist; thedoc-
umentationdoesnot discussmethods that theclass obtainsthrough inheritance
from base classes. Remember that if you arelookingfor aspecific function and
do notfind it in thelist—it maybe documented in abaseclass.Alternatively,
thelinkListofall members, includinginherited membersatthe beginning of the
classdocumentation, leads to alistofall functionsofthe class, includinginherited

functions.
Thefunction listisfollowed byadetaileddescription of theclass.Inaddition to a
descriptionofthe tasksthatthe classcarries out, it also explains some typical ways
in which theclass is used.
60
2
Chapter
TheToolsNeeded to
CreateDialogs
Nowthat you haveanoverviewof Qt, wewillturntoamore practical exampleto
seehowtheclassesworktogether.Our first extensiveprogram willconvertnum-
bers between decimal, hexadecimal, andbinarynotation;it’sshowninFigure2.1.
Figure 2.1:
Ourexample program
converts numbers
between decimal,
hexadecimal, and
binary notation.
61
2 TheToolsNeeded to CreateDialogs
Theuserofthisprogram can enter anyone-byte number (from0to 255) in anyof
thethree inpu tfields.The program updates th eother two Line-Edits inputfields
withthe converted value.
2.1What’sthe DifferenceBetween Dialogsand
Widgets?
Theprogram’s main() function is almost identical to themain() function of the
“Hello,world!” program discussedinSection 1.1:
// byteConverter/main.cpp
#include <QApplication>
#include "ByteConverterDialog.h"

intmain(intargc, char
*
argv[])
{
QApplication a(argc, argv);
ByteConverterDialog bc;
bc.setAttribute(Qt::WA_QuitOnClose);
bc.show();
returna.exec();
}
Thereisjustone exception: Thecla ss QLabel hasbeen replaced byByteConver-
terDialog.Thisclass inherits from QDialog,and itsclass definitionisplacedin
theheaderfile ByteConverterDialog.h.
1
The#includedirectivethatintegrates this
headerfile into theapplicationcode uses quotationmarks (”)insteadofangle
brackets (<>),since thefile is in thesamedirectoryas main.cpp.
We’vealsoaddedthe WA_QuitOnClose attribute to thedialogtoensurethatthe
program ends whenthe dialog is closed.Thiswas notnecessaryin theprevious
examples,because wedid notuse anyclassesinherited from QDialog as themain
window.Since dialogs usuallyonlyprovidein-between information,the attribute
is notactivebydefaultfor QDialog.After all, closingadialogshouldn’t terminate
theapplicationunlessthere’s aserious bug.
We surround thecontents of thefile ByteConverterDialog.h with includeguards ,
consisting of thethree preprocessorinstructions#ifndef label ,#de fine label and
#endif:
1
Forheader files that wecreateourselves,weuse theC/C++standardfile extension.h, to make
thefile type clear.
62

2.1 What’s theDifferenceBetween Dialogsand Widgets?
// byteConverter/ByteConverterDialog.h
#ifndef BYTECONVERTERDIALOG_H
#define BYTECONVERTERDIALOG_H
#include <QDialog>
class QLineEdit;
class ByteConverterDialog :public QDialog
{
Q_OBJECT
public:
ByteConverterDialog();
private:
QLineEdit
*
decEdit;
QLineEdit
*
hexEdit;
QLineEdit
*
binEdit;
} ;
#endif
Using includeguardsisastandardtechniqueinC/C++programming to avoidprob-
lems that occurifmorethanone source filetries to #include aheaderfile,which
can happeninlarge programs withmanyindependentlydevelopedmodules. Here,
thefirsttimeByteConverterDialog.h is processed, thekeywordBYTECONVER TER-
DIALOG_Hisdefined. If alater source fileattempts to #include ByteConverterDia-
log.hagain, th e#ifndef endif (“if notdefined”)directivecausesthe preprocessor
to skip theheaderfile’s contents.Without theinclude guards,the compilerwould

notice that thekeywords andclassesare beingmultiplydefined andsignalanerror.
We includethe headerfile QDialog,since theByteConverterDialog classinherits
from QDialog.Inorder for th efunctionsofQDialog to be available outsidethe
ByteConverterDialog classweuse theaccess controlpublic.
Theclass declaration classQLineEdit; is a forwarddeclaration.Objectsofthe
ByteConverterDialog classcontain threeprivatevariablesthatpoint to QLineEdit
objects, an dsothe C++compilerneedstoknowthat QLineEditisaclassinorder
to processthe ByteConverterDialog declaration, butitdoesnot need to knowthe
exact classdefinition at that point.
2
TheQ_OBJECT macromustbeusedinall derivations from theQObject base class,
includingindirectones, because it defines functionswithout which thesignal/slot
conceptcannotwork. (MoreonthisinSection 2.1.1.)
2
Alternatively,you couldinclude theQLineEdit header filebeforethe declarationofByteCon-
verterDialog, butthenthe parser would need to read this,which would slowdowncompiling
considerably,especiallyon slower machines.For this reason,wetry,inthisbook,tooptimize
theheader files so that onlythenecessaryones areincluded.
63
2 TheToolsNeeded to CreateDialogs
Theconstructor is theonlypublic function of theclass.Wewillstore pointersto
theQLineEditobjectsdisplayed bythebyte converter widgetinthe threemem-
bervariables(decEdit,hexEdit, andbinEdit) because wewishtoupdatethe input
fieldsinwhich theuserdoesnot enter dataimmediatelyto ensure that allthree
lineedits displaythesametext. Because this is an implementation detail of our
ByteConverterDialog class, wedeclare them as privatevariables.
2.1.1Inheriting from QObject
As mentioned previously,you mustalwaysuse theQ_OBJECT macrowhenaclass
inherits,directlyor indirectly,fromQObject.
3

This macrodefinesseveral functions
that implementthe signal/slotconcept.Unfortunately,ifthe macroismissing in
thedefinition of aclass that inherits from QObject,neither thecompilernor the
linkerwillreportanerror.Instead, thesignals andslots of theclass willremain
unknowntoQt, andatruntimethe corresponding connections willnot work.
Applications compiledwithdebugging information willwarnatruntime(in ater-
minalwindow)thatasignal or slot doesnot existwhenever code is executed that
triestoaccess an unknownsignalorslot. Theerror message is:
Object::connect:Nosuch slotQObject::decChanged(QString)
However,thiserror message is abit non-specific. Youwillalsosee it if you have
written thenameofthe signal or slot incorrectlyor if theargument listisincorrect.
Everyfilethatusesthe Q_OBJECT macromustbesubmitted to thecommand-line
program moc(seepage 56). This tool automaticallygenerates thecode converted
into pure C++code bythesignal/slot concept.
4
If you useqmake to create yourproject,the qmaketool searches allheaderand
source textfilesnam ed in the.profile for theQ_OBJECT macro. When it finds one,
qmakeautomaticallygenerates thenecessarybuild instructions for mocbased on
thecontents of thosefiles.
5
Forthistoworkyou must, of course,specifytheproject’s headerfilesinthe .pro
file. To do so,use theqmake variable HEADERS,asyou would theSOURCES variable
for so urce textfiles:
3
Some compilers issueerrorsifthe Q_OBJECT macroisterminatedwithasemicolon, which is
why,for reasonsofportability,werecommend that you alwaysomitit.
4
mocdoesnot modifyyourfiles; it provides thenewcode in separate files which you haveto
take care of whenwriting yourMakefilesbyhand.Ifyou useqmake as werecommend,you
don’t havetocare.

5
qmakewill notautomaticallynotice if theQ_OBJECT macroisinsertedintoafilelater on.
64
2.1 What’s theDifferenceBetween Dialogsand Widgets?
#byteConverter/byteConverter.pro
TEMPLATE =app
SOURCES =main.cpp \
ByteConverterDialog.cpp
HEADERS =ByteConverterDialog.h
If mocisnot invoked for files containing theQ_OBJECT macros,the linkercom-
plains of undefinedsymbols, andGCC issues this errormessage:
ld: Undefined symbols:
vtable forByteConverterDialog
ByteConverterDialog::staticMetaObject
If you seethiserror message,check thefollowing:
Havethe qmakevariable HEADERS been properlydefined?
Is theproblemresolved if theMakefiles areregenerated withqmake?
2.1.2MoreComplex Layouts
We nowturn to theimplementationofthe ByteConverterDialog class. When cre-
atinginstances of this class, theconstructor function generates allthe QLineEdit
widgets displayed bythenewByteConverterDialog object andinserts them into a
layout. However,thisisnolongerassimpleasbefore: In orderfor theapplication
to behaveinanintuitivemannerwhenthe user changesthe sizeofthe dialog, we
need to usenested layouts.Figure2.2 showshowQt ensuresthatthe inputfields
alwaysappear at thetop of thewindowandthatthe Quit buttonalwaysappears
at thelower rightcornerofthe win dow.
Figure 2.2:
HowQtlayouts react
to asize change in
thedialog

Butdon’t panic:Even though thesourcecode for theconstructor becomesquite
long,itusesonlysimple functions:
65
2 TheToolsNeeded to CreateDialogs
// byteConverter/ByteConverterDialog.cpp
#include "ByteConverterDialog.h"
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QGridLayout>
ByteConverterDialog::ByteConverterDialog()
{
// Generatethe necessary layouts
QVBoxLayout
*
mainLayout =newQVBoxLayout(this);
QGridLayout
*
editLayout =newQGridLayout;
QHBoxLayout
*
buttonLayout =newQHBoxLayout;
mainLayout->addLayout(editLayout);
mainLayout->addStretch();
mainLayout->addLayout(buttonLayout);
// Generatethe labelsand line-edits and add them
// tothe objectpointed atbyeditLayout
QLabel

*
decLabel =newQLabel(tr("Decimal"));
QLabel
*
hexLabel =newQLabel(tr("Hex"));
QLabel
*
binLabel =newQLabel(tr("Binary"));
decEdit=newQLineEdit;
hexEdit=newQLineEdit;
binEdit=newQLineEdit;
editLayout->addWidget(decLabel, 0,0);
editLayout->addWidget(decEdit,0,1);
editLayout->addWidget(hexLabel, 1, 0);
editLayout->addWidget(hexEdit,1,1);
editLayout->addWidget(binLabel, 2,0);
editLayout->addWidget(binEdit,2,1);
// Createthe Quitbutton and add ittothe objectpointed
// atbybuttonLayout
QPushButton
*
exitButton =newQPushButton(tr("Quit"));
buttonLayout->addStretch();
buttonLayout->addWidget(exitButton);

Figure 2.3showswhich layouts areinvolved withwhich widgets.Keep an eyeonit
whenwenowwalkthrough thecode above.
ThemainLayoutobject,avertical boxlayout, is responsible for thelayoutofthe
entire dialog. Therefore, wepassapointer to theByteConverterDialog object when
wecallits constructor. To do this weuse thethispointer,since weare in afunction

of theByteConverterDialog classitself.
66
2.1 What’s theDifferenceBetween Dialogsand Widgets?
Figure 2.3:
Thelayouts as used
by
ByteConverterDialog
TheeditLayoutobject is responsible for thelayoutofthe labels andline-edit widgets.
In ordertobeable to stack theseelementsneatly,and to organizethe widgets in a
single column, weuse agridlayout.
ThebuttonLayout, which wecreatewiththe thirdnewcall, will be responsible
for managing theQuitbutton. However,beforewecan generate widgets likethis
buttonand add them to editLayoutand buttonLayout, wemustadd thosetwo
layouts to themainLayoutusing addLayout(), which is thelayoutequivalentof
addWidget(). If you add widgets to alayoutnot yet associatedwithawidget, you
willreceivethisruntimeerror in aterminalwindow:
QLayout::addChildWidget:add layout toparentbeforeadding children to
layout.
andthe widgets willremaininvisible. Therefore, you should alwaysgeneratethe
basiclayoutfor yourclass first,thencontinue withthe nextlayout“layer,” andso
on.
To ensure that inputfields arealwaysplacedatthe topofthe ByteConverterDialog
andthatthe Quit buttonisalwayspositionedatits lower right, weuse stretches .
Figure 2.4:
Thedialogafter a
change in size when
stretches arenot used
Stretchesoccupythespacenot required bythewidgets andthus create empty
spacesinyourdialog. If you weretoomitstretchesinour exam ple, thewidgets
67

2 TheToolsNeeded to CreateDialogs
would occupytheentirespace. Were theusertoenlarge such adialog, without
stretch, he would seesometh inglikeFigure2.4.
To avoidthisbehavior, weadd astretchbetween th eeditLayoutand thebutton-
Layoutwiththe addStretch() function.
Nowwecan generate thelabelsand lineedits andentrust them to theeditLayout.
We savethe lineeditobjectsinthe privateclass variablesdecEdit, hexEdit, and
binEdit, because wewanttochangetheir contents throughcode stored in other
functions. Forall otherobjects, wecan manage without corresponding pointers
because wedonot need to accessthemoutside theconstructor.
To ensure that theQuitbuttonisalwaysdisplayed at thefar bottomright of the
dialog, wefirstfill thehorizontallayoutbuttonLayoutwithastretchbeforewe
adjustthe buttonitself.
Byaddingall thewidgets andsublayouts to themainLayoutobject or itschildren
usingQObject::addWidget()and QObject::addLayout(), weensurethatall objects
generated bytheconstructor withnewareinherited from theByteConverterDialog
object.Since theynowformaheap-allocatedobject hierarchythat Qt’smemory
management willhandlefor us,wedonot need to delete anyof them manually.
When theByteConverterDialog object is deleted,all itschildrendisappearauto-
matically.
Areyou becoming slightlydisillusioned because of thenot insignificantamount of
code that wehad to write just to create areallysimple dialog? Help is on theway
in Chapter 3, which explains howadialogcan be created usingthe Qt designer,
andcode automaticallygenerated.Moredetails andbackground information on
layouts is provided in Chapter 5.
2.1.3Increasing Usability
Despitethe improved layout, th edialogdoesnot yet behaveideallyin certainre-
spects:
Thewindowtitleatthe moment showsthe program name byteConverter.Some-
thingmoredescriptivemight be be tter.

TheQuitbuttonshouldbecomethe default button of thedialog. Thedefault
buttonisactivated by




Enter even if it currentlydoesnot havekeyboardfocus.
Most widgetstyleshighlight thedefault buttoninaparticular way.
Currentlyyou can enter an ynumbersinthe line-edit widgets.Weshouldrestrict
this to valid values, that is,onlywhole decimalnumbersbetween 0and255,
hexadecimalnumberswithamaximum of twodigits, an dbinarynumberswith
amaximum of eightbits.
68

×