Professional Documents
Culture Documents
C GUI Programming With QT 4 Second Edition
C GUI Programming With QT 4 Second Edition
net/publication/234788146
CITATIONS READS
26 3,398
2 authors, including:
SEE PROFILE
Some of the authors of this publication are also working on these related projects:
All content following this page was uploaded by Jasmin Christian Blanchette on 04 May 2014.
Copyright
Foreword
Preface
- Acknowledgments
C++ GUI Programming with Qt 4 A Brief History of Qt
By Jasmin Blanchette, Mark Summerfield
Part 1: Basic Qt
!"#$%&'()* !"#$%&"'()** Chapter 1. Getting Started
!"#+,-.(* +,#"'-./'-001
!)%/.+0123456* 02.32.45-6726 Hello Qt
!)%/.+0123457* 754202.32.45-6723 Making Connections
!-8(&* 810
Laying Out Widgets
Using the Reference Documentation
Overview Chapter 2. Creating Dialogs
Subclassing QDialog
9:"';#*<';==%&%)*'>"?$2 !)&$%&"'@,%A"'$B'C$'6D.' !BE!)FF%#E
Signals and Slots in Depth
Rapid Dialog Design
9&%/8+:);$$.(<'=&+>.+?;"+<-/+#"%$@+%/@"&.)%-$4&.)(/8.'+ABB+-CC$%<-.%;/&+.'-.+)"/+/-.%D($?+;/
Shape-Changing Dialogs
E%/@;F&G+H%/"IJ9/%IG+K-<+L1+MG+-/@+(N#(@@(@+H%/"I44F%.';".+N-O%/8+&;")<(+<;@(+<'-/8(& +E%.'
.'%&+#;;O+:);$$.(<'+%/&%@()&+'-D(+F)%..(/+-+&.-).4.;4P%/%&'+8"%@(+.;+8(..%/8+8)(-.+)(&"$.&+F%.'+.'(+N;&. Dynamic Dialogs
C;F()P"$+D()&%;/+;P+>.+(D()+<)(-.(@*+>.+Q 5 Built-in Widget and Dialog Classes
Chapter 3. Creating Main Windows
9&%/8 !!"#$%"&'()'*++,-)".,/0"1/"2+?;"=$$+@%&<;D()+.'(+N;&.+(PP(<.%D(+>.+Q+C);8)-NN%/8 Subclassing QMainWindow
C-..()/&+-/@+.(<'/%R"(&+-&+?;"+N-&.()+O(?+.(<'/;$;8%(&+)-/8%/8+P);N+>.=&+N;@($JD%(F+-)<'%.(<.")( Creating Menus and Toolbars
.;+>.=&+C;F()P"$+/(F+S,+C-%/.+(/8%/( +:'(+-".';)&+C);D%@(+)(-@()&+F%.'+"/C-)-$$($(@+%/&%8'.+%/.;+>.=& Setting Up the Status Bar
(D(/.+N;@($+-/@+$-?;".+&?&.(N +:'(/G+"&%/8+)(-$%&.%<+(I-NC$(&G+.'(?+%/.);@"<(+&"C()%;)+.(<'/%R"(& Implementing the File Menu
P;)+(D()?.'%/8+P);N+#-&%<+T90+@(D($;CN(/.+.;+-@D-/<(@+@-.-#-&(+-/@+MKH+%/.(8)-.%;/ Using Dialogs
Storing Settings
• 0/<$"@(&+/(F+<'-C.()&+;/+>.+Q=&+N;@($JD%(F+-)<'%.(<.")(+-/@+>.=&+/(F+C$"8%/+&"CC;).G+-$;/8
Multiple Documents
F%.'+-+#)%(P+%/.);@"<.%;/+.;+>.;C%-+(N#(@@(@+C);8)-NN%/8
Splash Screens
Chapter 4. Implementing Application Functionality
• A;D()&+-$$+>.+P"/@-N(/.-$&G+P);N+@%-$;8&+-/@+F%/@;F&+.;+%NC$(N(/.%/8+-CC$%<-.%;/
The Central Widget
P"/<.%;/-$%.?
Subclassing QTableWidget
• 0/.);@"<(&+#(&.+C)-<.%<(&+P;)+$-?;".+N-/-8(N(/.+-/@+(D(/.+C);<(&&%/8 Loading and Saving
Implementing the Edit Menu
• 1';F&+';F+.;+N-O(+.'(+N;&.+;P+>.+Q=&+/(F+U!0&G+%/<$"@%/8+.'(+C;F()P"$+/(F+S,+C-%/.+(/8%/( Implementing the Other Menus
-/@+.'(+/(F+(-&?4.;4"&(+<;/.-%/()+<$-&&(& Subclassing QTableWidgetItem
Chapter 5. Creating Custom Widgets
• A;/.-%/&+<;NC$(.($?+"C@-.(@+N-.()%-$+%/+(D()?+<'-C.() Customizing Qt Widgets
Subclassing QWidget
• !)(&(/.&+-@D-/<(@+>.+Q+.(<'/%R"(&+<;D()(@+%/+/;+;.'()+#;;OG+P);N+<)(-.%/8+#;.'+>.+-/@ Integrating Custom Widgets with Qt Designer
-CC$%<-.%;/ C$"8%/&+.;+%/.()P-<%/8+F%.'+/-.%D(+U!0& Double Buffering
Part II: Intermediate Qt
• A;/.-%/&+-/+%/4@(C.'+-CC(/@%I+;/+ABBJ>.+C);8)-NN%/8+P;)+(IC()%(/<(@+V-D-+@(D($;C()& Chapter 6. Layout Management
Laying Out Widgets on a Form
:'(+-<<;NC-/?%/8+A,4WLK+%/<$"@(&+.'(+;C(/+&;")<(+(@%.%;/+;P+>.+Q 5 5+P;)+E%/@;F&G+K-<G+H%/"IG Stacked Layouts
-/@+N-/?+9/%I(&G+-&+F($$+-&+K%/TEG+-+&(.+;P+P)(($?+-D-%$-#$(+@(D($;CN(/.+.;;$&+.'-.+<-/+#(+"&(@+.; Splitters
#"%$@+>.+-CC$%<-.%;/&+;/+E%/@;F&G+-/@+-$&;+.'(+&;")<(+<;@(+P;)+.'(+#;;O=&+(I-NC$(&
Scrolling Areas
Dock Widgets and Toolbars
Multiple Document Interface
Chapter 7. Event Processing
Reimplementing Event Handlers
Installing Event Filters
Staying Responsive During Intensive Processing
Chapter 8. 2D and 3D Graphics
Painting with QPainter
Painter Transformations
High-Quality Rendering with QImage Interfacing with Native APIs
Printing Using ActiveX on Windows
Graphics with OpenGL Handling X11 Session Management
Chapter 9. Drag and Drop Chapter 21. Embedded Programming
Enabling Drag and Drop Getting Started with Qtopia
Supporting Custom Drag Types Customizing Qtopia Core
Clipboard Handling Appendix A. Installing Qt
Chapter 10. Item View Classes A Note on Licensing
Using the Item View Convenience Classes Installing Qt/Windows
Using Predefined Models Installing Qt/Mac
Implementing Custom Models Installing Qt/X11
Implementing Custom Delegates Appendix B. Introduction to C++ for Java and C# Programmers
Chapter 11. Container Classes Getting Started with C++
Sequential Containers Main Language Differences
Associative Containers The Standard C++ Library
Generic Algorithms About the Authors
Strings, Byte Arrays, and Variants Production
Chapter 12. Input/Output Index
Reading and Writing Binary Data
Reading and Writing Text
Traversing Directories
Embedding Resources
Inter-Process Communication
Chapter 13. Databases
Connecting and Querying
Presenting Data in Tabular Form
Implementing MasterDetail Forms
Chapter 14. Networking
Writing FTP Clients
Writing HTTP Clients
Writing TCP ClientServer Applications
Sending and Receiving UDP Datagrams
Chapter 15. XML
Reading XML with SAX
Reading XML with DOM
Writing XML
Chapter 16. Providing Online Help
Tooltips, Status Tips, and "What's This?" Help
Using QTextBrowser as a Simple Help Engine
Using Qt Assistant for Powerful Online Help
Part III: Advanced Qt
Chapter 17. Internationalization
Working with Unicode
Making Applications Translation-Aware
Dynamic Language Switching
Translating Applications
Chapter 18. Multithreading
Creating Threads
Synchronizing Threads
Communicating with the Main Thread
Using Qt's Classes in Secondary Threads
Chapter 19. Creating Plugins
Extending Qt with Plugins
Making Applications Plugin-Aware
Writing Application Plugins
Chapter 20. Platform-Specific Features
Copyright Foreword
K-/?+;P+.'(+@(&%8/-.%;/&+"&(@+#?+N-/"P-<.")()&+-/@+&($$()&+.;+@%&.%/8"%&'+.'(%)+C);@"<.&+-)(+<$-%N(@ E'?+>.e+E'?+@;+C);8)-NN()&+$%O(+"&+<';;&(+>.e+1")(G+.'()(+-)(+.'(+;#D%;"&+-/&F()&*+>.=&+&%/8$(4
-&+.)-@(N-)O& +E'()(+.';&(+@(&%8/-.%;/&+-CC(-)+%/+.'%&+#;;OG+-/@+.'(+C"#$%&'()+F-&+-F-)(+;P+- &;")<(+<;NC-.%#%$%.?G+%.&+P(-.")(+)%<'/(&&G+%.&+ABB+C()P;)N-/<(G+.'(+-D-%$-#%$%.?+;P+.'(+&;")<(+<;@(G
.)-@(N-)O+<$-%NG+.'(+@(&%8/-.%;/&+'-D(+#((/+C)%/.(@+F%.'+%/%.%-$+<-C%.-$+$(..()&+;)+%/+-$$+<-C%.-$& %.&+@;<"N(/.-.%;/G+.'(+'%8'4R"-$%.?+.(<'/%<-$+&"CC;).G+-/@+-$$+.'(+;.'()+%.(N&+N(/.%;/(@+%/
:);$$.(<'=&+8$;&&?+N-)O(.%/8+N-.()%-$& +:'%&+%&+-$$+D()?+F($$G+#".+%.+N%&&(&+.'(+N;&.+%NC;).-/.+C;%/.*
:'(+-".';)&+-/@+C"#$%&'()+'-D(+.-O(/+<-)(+%/+.'(+C)(C-)-.%;/+;P+.'%&+#;;OG+#".+N-O(+/;+(IC)(&&(@ >.+%&+&"<<(&&P"$+#(<-"&(+C);8)-NN()& 9,>7+%.
;)+%NC$%(@+F-))-/.?+;P+-/?+O%/@+-/@+-&&"N(+/;+)(&C;/&%#%$%.?+P;)+());)&+;)+;N%&&%;/& +3;+$%-#%$%.?+%&
-&&"N(@+P;)+%/<%@(/.-$+;)+<;/&(R"(/.%-$+@-N-8(&+%/+<;//(<.%;/+F%.'+;)+-)%&%/8+;".+;P+.'(+"&(+;P+.'( f;F+<;N(+C);8)-NN()&+$%O(+;/(+.(<'/;$;8?G+#".+@%&$%O(+-/;.'()e+!()&;/-$$?+0+#($%(D(+&;P.F-)(
%/P;)N-.%;/+;)+C);8)-N&+<;/.-%/(@+'()(%/ (/8%/(()&+(/c;?+.(<'/;$;8?+.'-.+P(($&+)%8'.G+#".+@%&$%O(+(D()?.'%/8+.'-.+@;(&/=. +gX(($&+)%8'.g+N(-/&
N-/?+.'%/8& +0/+.'(+>.+7+(@%.%;/+;P+.'(+#;;OG+0+N(/.%;/(@+:);$$.(<'=&+C';/(+&?&.(N+-&+-+C-).%<"$-)$?
:'(+C"#$%&'()+;PP()&+(I<($$(/.+@%&<;"/.&+;/+.'%&+#;;O+F'(/+;)@()(@+%/+R"-/.%.?+P;)+#"$O+C")<'-&(&+;) 8;;@+(I-NC$(+;P+&;N(+C-).%<"$-)$?+#-@+.(<'/;$;8? +:'(+C';/(+&?&.(N+@%@/=.+P(($+)%8'.G+#(<-"&(+%.
&C(<%-$+&-$(&G+F'%<'+N-?+%/<$"@(+($(<.);/%<+D()&%;/&+-/@J;)+<"&.;N+<;D()&+-/@+<;/.(/.+C-).%<"$-)+.; P;)<(@+"&+.;+@;+-CC-)(/.$?+)-/@;N+.'%/8&+@(C(/@%/8+;/+&;N(+(R"-$$?+)-/@;N+<;/.(I. +W-/@;N/(&&
?;")+#"&%/(&&G+.)-%/%/8+8;-$&G+N-)O(.%/8+P;<"&G+-/@+#)-/@%/8+%/.()(&.& +X;)+N;)(+%/P;)N-.%;/G+C$(-&( @;(&/=.+P(($+)%8'. +U/;.'()+.'%/8+.'-.+@;(&/=.+P(($+)%8'.+%&+)(C(.%.%D(/(&&+-/@+)(@"/@-/<? +T;;@
<;/.-<.* C);8)-NN()&+-)(+$-h? +E'-.+F(+$;D(+-#;".+<;NC".()&+<;NC-)(@+.;G+&-?G+8-)@(/%/8+%&+.'-.+F(+@;/=.
'-D(+.;+@;+.'(+&-N(+.'%/8&+;D()+-/@+;D()
!);8)-NN%/8+<-/+#(+-+$;.+$%O(+P%$$%/8+%/+.)-D($+)(%N#")&(N(/.+P;)N&G+;/$?+F;)&( +U/@+.'%&+%&+F'()(+>.
A;C?)%8'.+b+S66`+:);$$.(<'+U1
<;N(&+.;+.'(+)(&<"( +>.+%&+@%PP()(/. +X;)+;/(+.'%/8G+>.+N-O(&+&(/&( +U/@+P;)+-/;.'()G+>.+%&+P"/ +>.
$(.&+?;"+<;/<(/.)-.(+;/+?;")+.-&O& +E'(/+>.=&+;)%8%/-$+-)<'%.(<.&+P-<(@+-+C);#$(NG+.'(?+@%@/=.+c"&.
U$$+)%8'.&+)(&()D(@ +!)%/.(@+%/+.'(+9/%.(@+1.-.(&+;P+UN()%<- +:'%&+C"#$%<-.%;/+N-?+;/$?+#(+@%&.)%#".(@ $;;O+P;)+-+8;;@+&;$".%;/G+;)+.'(+&%NC$(&.+&;$".%;/ +:'(?+$;;O(@+P;)+.'( ',)0/+&;$".%;/G+-/@+.'(/+.'(?
&"#c(<.+.;+.'(+.()N&+-/@+<;/@%.%;/&+&(.+P;).'+%/+.'(+LC(/+!"#$%<-.%;/+H%<(/&(G+D5 6+;)+$-.()+Y.'( @;<"N(/.(@+%. +T)-/.(@+.'(?+N-@(+N%&.-O(&G+-/@+8)-/.(@+&;N(+;P+.'(%)+@(&%8/+@(<%&%;/&+@%@/=.+C-&&
$-.(&.+D()&%;/+%&+-D-%$-#$(+-. '..C*JJFFF ;C(/4<;/.(/. ;)8J;C(/C"#J[ .'(+.(&.+;P+.%N(G+#".+.'(?+&.%$$+8;.+-+$;.+;P+.'%/8&+)%8'.G+-/@+F'-.+F-&/=.+)%8'.+<;"$@+-/@+<-/+#(
<;))(<.(@ +j;"+<-/+&((+.'%&+#?+.'(+P-<.+.'-.+-+&?&.(N+;)%8%/-$$?+@(&%8/(@+.;+#)%@8(+E%/@;F&+\a+-/@
:);$$.(<'dG+>.dG+>.;C%-dG+-/@+.'(+:);$$.(<'+-/@+>.;C%-+$;8;&+-)(+)(8%&.()(@+.)-@(N-)O&+;P+:);$$.(<' 9/%IJK;.%P+/;F+"/%P%(&+N;@()/+@(&O.;C+&?&.(N&+-&+@%D()&(+-&+E%/@;F&+M!G+K-<+L1+MG+-/@
U1 T39JH%/"IG+-/@+C);D%@(&+.'(+P;"/@-.%;/+P;)+.'(+>.;C%-+-CC$%<-.%;/+C$-.P;)N+P;)+(N#(@@(@+H%/"I
:(I.+C)%/.(@+%/+.'(+9/%.(@+1.-.(&+;/+)(<?<$(@+C-C()+-.+A;")%()+%/+1.;"8'.;/G+K-&&-<'"&(..& H;/8+#(P;)(+>.+#(<-N(+&;+C;C"$-)+-/@+&;+F%@($?+"&(@G+.'(+@(@%<-.%;/+;P+>.=&+@(D($;C()&+.;+P%/@%/8
.'(+)%8'.+&;$".%;/&+N-@( >.+&C(<%-$ +:'-.+@(@%<-.%;/+%&+c"&.+-&+&.);/8+.;@-?+-/@+-PP(<.&+(D()?;/(+F';
X%)&.+C)%/.%/8G+V"/(+S66` @(D($;C&+-/@+N-%/.-%/&+>. +X;)+"&G+F;)O%/8+;/+>.+%&+-+)(&C;/&%#%$%.?+-/@+-+C)%D%$(8( +E(+-)(+C);"@+;P
'($C%/8+.;+N-O(+?;")+C);P(&&%;/-$+-/@+;C(/+&;")<(+$%D(&+(-&%()+-/@+N;)(+(/c;?-#$(
:'(+C")C;&(+;P+.'%&+#;;O+%&+.;+.(-<'+?;"+';F+.;+F)%.(+T90+C);8)-N&+"&%/8+>.+Q +:'(+#;;O+&.-).&+F%.'
gf($$;+>.g+-/@+R"%<O$?+C);8)(&&(&+.;+N;)(+-@D-/<(@+.;C%<&G+&"<'+-&+<)(-.%/8+<"&.;N+F%@8(.&+-/@
C);D%@%/8+@)-8+-/@+@);C +:'(+.(I.+%&+<;NC$(N(/.(@+#?+-+A,+.'-.+<;/.-%/&+.'(+&;")<(+<;@(+;P+.'(
(I-NC$(+C);8)-N& +:'(+A,+-$&;+%/<$"@(&+.'(+;C(/+&;")<(+(@%.%;/+;P+>.+Q 5 5+P;)+-$$+&"CC;).(@
C$-.P;)N&G+-&+F($$+-&+K%/TEG+-+&(.+;P+P)(($?+-D-%$-#$(+@(D($;CN(/.+.;;$&+.'-.+<-/+#(+"&(@+.;+#"%$@+>.
-CC$%<-.%;/&+;/+E%/@;F& UCC(/@%I+U+(IC$-%/&+';F+.;+%/&.-$$+.'(+&;P.F-)(
:'(+#;;O+%&+@%D%@(@+%/.;+.')((+C-).& !-).+0+<;D()&+-$$+.'(+<;/<(C.&+-/@+C)-<.%<(&+/(<(&&-)?+P;)
C);8)-NN%/8+T90+-CC$%<-.%;/&+"&%/8+>. +l/;F$(@8(+;P+.'%&+C-).+-$;/(+%&+&"PP%<%(/.+.;+F)%.(+"&(P"$+T90
-CC$%<-.%;/& !-).+00+<;D()&+<(/.)-$+>.+.;C%<&+%/+8)(-.()+@(C.'G+-/@ !-).+000+C);D%@(&+N;)(+&C(<%-$%h(@
-/@+-@D-/<(@+N-.()%-$ :'(+<'-C.()&+;P !-).&+00+-/@ 000+<-/+#(+)(-@+%/+-/?+;)@()G+#".+.'(?+-&&"N(
P-N%$%-)%.?+F%.'+.'(+<;/.(/.&+;P !-).+0
W(-@()&+;P+.'(+>.+7 (@%.%;/+;P+.'%&+#;;O+F%$$+P%/@+.'%&+/(F+(@%.%;/+P-N%$%-)+%/+#;.'+<;/.(/.+-/@+&.?$(
:'%&+(@%.%;/+'-&+#((/+"C@-.(@+.;+.-O(+-@D-/.-8(+;P+>.+Q=&+/(F+P(-.")(&+Y%/<$"@%/8+&;N(+.'-.+F()(
%/.);@"<(@+F%.'+>.+Q 5[+-/@+.;+C)(&(/.+<;@(+.'-.+&';F&+8;;@+%@%;N-.%<+>.+Q C);8)-NN%/8
.(<'/%R"(& +0/+N-/?+<-&(&G+F(+'-D(+"&(@+(I-NC$(&+&%N%$-)+.;+.'(+;/(&+"&(@+%/+.'(+>.+7+(@%.%;/ +:'%&
F%$$+/;.+-PP(<.+/(F+)(-@()&G+#".+F%$$+'($C+.';&(+F';+)(-@+.'(+C)(D%;"&+(@%.%;/+;)%(/.+.'(N&($D(&+.;+>.
Q=&+<$(-/()G+<$(-)()G+-/@+N;)(+(IC)(&&%D(+&.?$(
:'%&+(@%.%;/+%/<$"@(&+/(F+<'-C.()&+<;D()%/8+>.+Q=&+N;@($JD%(F+-)<'%.(<.")(G+.'(+/(F+C$"8%/
P)-N(F;)OG+-/@+(N#(@@(@+C);8)-NN%/8+F%.'+>.;C%-G+-&+F($$+-+/(F+-CC(/@%I +U/@+c"&.+$%O(+.'(+>.+7
#;;OG+.'(+(NC'-&%&+%&+;/+(IC$-%/%/8+>.+C);8)-NN%/8+)-.'()+.'-/+&%NC$?+)('-&'%/8+;)+&"NN-)%h%/8
>.=&+(I.(/&%D(+;/$%/(+@;<"N(/.-.%;/
E(+'-D(+F)%..(/+.'(+#;;O+F%.'+.'(+-&&"NC.%;/+.'-.+?;"+'-D(+-+#-&%<+O/;F$(@8(+;P+ABBG+V-D-G+;)
Am +:'(+<;@(+(I-NC$(&+"&(+-+&"#&(.+;P+ABBG+-D;%@%/8+N-/?+ABB+P(-.")(&+.'-.+-)(+)-)($?+/((@(@
F'(/+C);8)-NN%/8+>. +0/+.'(+P(F+C$-<(&+F'()(+-+N;)(+-@D-/<(@+ABB+<;/&.)"<.+%&+"/-D;%@-#$(G+%.+%&
(IC$-%/(@+F'()(+%.+%&+"&(@
0P+?;"+-$)(-@?+O/;F+V-D-+;)+Am+#".+'-D(+$%..$(+;)+/;+(IC()%(/<(+F%.'+ABBG+F(+)(<;NN(/@+.'-.+?;"
#(8%/+#?+)(-@%/8 UCC(/@%I+2G+F'%<'+C);D%@(&+&"PP%<%(/.+%/.);@"<.%;/+.;+ABB+.;+#(+-#$(+.;+"&(+.'%&
#;;O +X;)+-+N;)(+.';);"8'+%/.);@"<.%;/+.;+;#c(<.4;)%(/.(@+C);8)-NN%/8+%/+ABBG+F(+)(<;NN(/@
!!"?(."/("&'()'*++#?+f-)D(?+,(%.($+-/@+!-"$+,(%.($G+-/@+.'( !!"&',+7'+#?+1.-/$(?+2
H%CCN-/G+V;&n(+H-c;%(G+-/@+2-)#-)-+k +K;;
>.+N-@(+%.&+)(C".-.%;/+-&+-+<);&&4C$-.P;)N+P)-N(F;)OG+#".+#(<-"&(+;P+%.&+%/."%.%D(+-/@+C;F()P"$+U!0G
N-/?+;)8-/%h-.%;/&+"&(+>.+P;)+&%/8$(4C$-.P;)N+@(D($;CN(/. +U@;#(+!';.;&';C+U$#"N+%&+c"&.+;/(
(I-NC$(+;P+-+N-&&4N-)O(.+E%/@;F&+-CC$%<-.%;/+F)%..(/+%/+>. +K-/?+&;C'%&.%<-.(@+&;P.F-)(+&?&.(N&
%/+D().%<-$+N-)O(.&G+&"<'+-&+7,+-/%N-.%;/+.;;$&G+@%8%.-$+P%$N+C);<(&&%/8G+($(<.);/%<+@(&%8/+-".;N-.%;/
YP;)+<'%C+@(&%8/[G+;%$+-/@+8-&+(IC$;)-.%;/G+P%/-/<%-$+&()D%<(&G+-/@+N(@%<-$+%N-8%/8G+-)(+#"%$.+F%.'+>.
0P+?;"+-)(+N-O%/8+-+$%D%/8+F%.'+-+&"<<(&&P"$+E%/@;F&+C);@"<.+F)%..(/+%/+>.G+?;"+<-/+(-&%$?+<)(-.(
/(F+N-)O(.&+%/+.'(+K-<+L1+M+-/@+H%/"I+F;)$@&+&%NC$?+#?+)(<;NC%$%/8
>.+%&+-D-%$-#$(+"/@()+D-)%;"&+$%<(/&(& +0P+?;"+F-/.+.;+#"%$@+<;NN()<%-$+-CC$%<-.%;/&G+?;"+N"&.+#"?+-
<;NN()<%-$+>.+$%<(/&(i+%P+?;"+F-/.+.;+#"%$@+;C(/+&;")<(+C);8)-N&G+?;"+<-/+"&(+.'(+;C(/+&;")<(
YT!H[+(@%.%;/ +>.+%&+.'(+P;"/@-.%;/+;/+F'%<'+.'(+l+,(&O.;C+k/D%);/N(/.+Yl,k[+-/@+.'(+N-/?+;C(/
&;")<(+-CC$%<-.%;/&+.'-.+8;+F%.'+%.+-)(+#"%$.
0/+-@@%.%;/+.;+>.=&+'"/@)(@&+;P+<$-&&(&G+.'()(+-)(+-@@4;/&+.'-.+(I.(/@+>.=&+&<;C(+-/@+C;F() +1;N(
Acknowledgments A Brief History of Qt
L")+P%)&.+-<O/;F$(@8N(/.+%&+;P+k%)%O+A'-N#(4k/8G+:);$$.(<'=&+C)(&%@(/. +k%)%O+/;.+;/$? :'(+>.+P)-N(F;)O+P%)&.+#(<-N(+C"#$%<$?+-D-%$-#$(+%/+K-?+5\\a +0.+F-&+%/%.%-$$?+@(D($;C(@+#?+f--D-)@
(/.'"&%-&.%<-$$?+(/<;")-8(@+"&+.;+F)%.(+.'(+>.+7+(@%.%;/+;P+.'(+#;;OG+'(+-$&;+-$$;F(@+"&+.;+&C(/@+- 3;)@+Y:);$$.(<'=&+AkL[+-/@+k%)%O+A'-N#(4k/8+Y:);$$.(<'=&+C)(&%@(/.[ +f--D-)@+-/@+k%)%O+N(.+-.+.'(
<;/&%@()-#$(+-N;"/.+;P+;")+F;)O+.%N(+F)%.%/8+%. +k%)%O+-/@+:);$$.(<'+AkL+f--D-)@+3;)@+#;.'+)(-@+.'( 3;)F(8%-/+0/&.%.".(+;P+:(<'/;$;8?+%/+:);/@'(%NG+F'()(+.'(?+#;.'+8)-@"-.(@+F%.'+N-&.()=&+@(8)((&
N-/"&<)%C.+-/@+C);D%@(@+D-$"-#$(+P((@#-<O +:'(%)+8(/();&%.?+-/@+P;)(&%8'.+F-&+-%@(@+-/@+-#(..(@ %/+<;NC".()+&<%(/<(
#?+K-..'%-&+k..)%<'G+:);$$.(<'=&+$(-@+@(D($;C() +K-..'%-&+<'(()P"$$?+-<<(C.(@+;")+/(8$(<.+;P+@".?+-&
F(+;#&(&&(@+;D()+.'(+F)%.%/8+;P+.'(+P%)&.+(@%.%;/+;P+.'%&+#;;O+-/@+8-D(+"&+-+$;.+;P+-@D%<(+;/+8;;@+>. f--D-)@=&+%/.()(&.+%/+ABB+T90+@(D($;CN(/.+#(8-/+%/+5\ZZ+F'(/+'(+F-&+<;NN%&&%;/(@+#?+-
C);8)-NN%/8+&.?$( 1F(@%&'+<;NC-/?+.;+@(D($;C+-+ABB+T90+P)-N(F;)O +U+<;"C$(+;P+?(-)&+$-.()G+%/+.'(+&"NN()+;P+5\\6G
f--D-)@+-/@+k%)%O+F()(+F;)O%/8+.;8(.'()+;/+-+ABB+@-.-#-&(+-CC$%<-.%;/+P;)+"$.)-&;"/@+%N-8(& +:'(
X;)+.'(+>.+7+(@%.%;/G+F(+-&O(@+.F;+>.+<"&.;N()&G+!-"$+A").%&+-/@+l$-"&+1<'N%@%/8()G+.;+#(+;") &?&.(N+/((@(@+.;+#(+-#$(+.;+)"/+F%.'+-+T90+;/+9/%IG K-<%/.;&'G+-/@+E%/@;F& +L/(+@-?+.'-.
(I.()/-$+)(D%(F()& +2;.'+-)(+>.+(IC().&+F%.'+-/+-N-h%/8+-..(/.%;/+.;+.(<'/%<-$+@(.-%$G+F'%<'+.'(? &"NN()G+f--D-)@+-/@+k%)%O+F(/.+;".&%@(+.;+(/c;?+.'(+&"/&'%/(G+-/@+-&+.'(?+&-.+;/+-+C-)O+#(/<'G
C);D(@+#?+&C;..%/8+&;N(+D()?+&"#.$(+());)&+%/+;")+N-/"&<)%C.+-/@+&"88(&.%/8+/"N();"& f--D-)@+&-%@G+gE(+/((@+-/+;#c(<.4;)%(/.(@+@%&C$-?+&?&.(N g+:'(+)(&"$.%/8+@%&<"&&%;/+$-%@+.'(
%NC);D(N(/.& +U/@+F%.'%/+:);$$.(<'G+-$;/8&%@(+K-..'%-&G+;")+N;&.+&.-$F-).+)(D%(F()+F-&+W(8%/-$@ %/.($$(<."-$+P;"/@-.%;/+P;)+.'(+;#c(<.4;)%(/.(@+<);&&4C$-.P;)N+T90+P)-N(F;)O+.'(?+F;"$@+&;;/+8;+;/
1.-@$#-"() +f%&+.(<'/%<-$+%/&%8'.+F-&+%/D-$"-#$(G+-/@+'(+.-"8'.+"&+';F+.;+@;+&;N(+.'%/8&+%/+>.+.'-. .;+#"%$@
F(+@%@/=.+(D(/+O/;F+F()(+C;&&%#$(
0/+5\\5G+f--D-)@+&.-).(@+F)%.%/8+.'(+<$-&&(&+.'-.+(D(/."-$$?+#(<-N(+>.G+<;$$-#;)-.%/8+F%.'+k%)%O+;/
X;)+.'%&+>.+Q+(@%.%;/G+F(+'-D(+<;/.%/"(@+.;+#(/(P%.+P);N+.'(+"/&.%/.%/8+'($C+-/@+&"CC;).+;P+k%)%OG .'(+@(&%8/ +:'(+P;$$;F%/8+?(-)G+k%)%O+<-N(+"C+F%.'+.'(+%@(-+P;)+g&%8/-$&+-/@+&$;.&gG+-+&%NC$(+#".
f--D-)@G+-/@+K-..'%-& +l$-"&+1<'N%@%/8()+<;/.%/"(@+.;+8%D(+D-$"-#$(+P((@#-<OG+-/@+F%.'%/+:);$$.(<'G C;F()P"$+T90+C);8)-NN%/8+C-)-@%8N+.'-.+'-&+/;F+#((/+(N#)-<(@+#?+&(D()-$+;.'()+.;;$O%.&
;")+O(?+)(D%(F()&+F()(+U/@)(-&+U-)@-$+f-/&&(/G+f(/)%O+f-).hG+^%D%+T$o<O&.-@+l-)$&(/G+:)(/.;/ f--D-)@+.;;O+.'(+%@(-+-/@+C);@"<(@+-+'-/@4<;@(@+%NC$(N(/.-.%;/ +2?+5\\7G+f--D-)@+-/@+k%)%O+'-@
1<'"$hG+U/@?+1'-FG+-/@+!p$+@(+^%#( @(D($;C(@+>.=&+P%)&.+8)-C'%<&+O()/($+-/@+F()(+-#$(+.;+%NC$(N(/.+.'(%)+;F/+F%@8(.& +U.+.'(+(/@+;P+.'(
?(-)G+f--D-)@+&"88(&.(@+.'-.+.'(?+8;+%/.;+#"&%/(&&+.;8(.'()+.;+#"%$@+g.'(+F;)$@=&+#(&.+ABB+T90
0/+-@@%.%;/+.;+.'(+)(D%(F()&+N(/.%;/(@+-#;D(G+F(+)(<(%D(@+(IC().+'($C+P);N+f-)-$@+X()/(/8($ P)-N(F;)Og
Y@-.-#-&(&[G+^;$O()+f%$&'(%N()+YU<.%D(M[G+2)-@$(?+f"8'(&+YN"$.%.')(-@%/8[G+:);/@+lc()/p&(/+Y7,
8)-C'%<&+-/@+@-.-#-&(&[G+H-)&+l/;$$+YS,+8)-C'%<&+-/@+%/.()/-.%;/-$%h-.%;/[G+1-N+K-8/"&;/+Y qmake[G :'(+?(-)+5\\Q+#(8-/+%/-"&C%<%;"&$?+F%.'+.'(+.F;+?;"/8+C);8)-NN()&+F-/.%/8+.;+(/.()+-+F($$4
K-)%"&+2"88(+K;/&(/+Y%.(N+D%(F+<$-&&(&[G+,%N%.)%+!-C-@;C;"$;&+Y>.JM55[G+!-"$+L$-D+:D(.(+Y<"&.;N (&.-#$%&'(@+N-)O(.G+F%.'+/;+<"&.;N()&G+-/+"/P%/%&'(@+C);@"<.G+-/@+/;+N;/(? +X;)."/-.($?G+#;.'
F%@8(.&+-/@+(N#(@@(@+C);8)-NN%/8[G+W-%/()+1<'N%@+Y/(.F;)O%/8+-/@+MKH[G+UN)%.+!-$+1%/8' .'(%)+F%D(&+F()(+(NC$;?(@+-/@+.'()(P;)(+-#$(+.;+&"CC;).+.'(%)+'"&#-/@&+P;)+.'(+.F;+?(-)&+k%)%O+-/@
Y%/.);@"<.%;/+.;+ABB[G+-/@+T"//-)+1$(..-+YS,+8)-C'%<&+-/@+(D(/.+C);<(&&%/8[ f--D-)@+(IC(<.(@+.;+/((@+.;+@(D($;C+.'(+C);@"<.+-/@+&.-).+(-)/%/8+-/+%/<;N(
kI.)-+.'-/O&+-)(+@"(+.;+:);$$.(<'=&+@;<"N(/.-.%;/+-/@+&"CC;).+.(-N&+P;)+'-/@$%/8+@;<"N(/.-.%;/4 :'(+$(..()+=>=+F-&+<';&(/+-&+.'(+<$-&&+C)(P%I+#(<-"&(+.'(+$(..()+$;;O(@+#(-".%P"$+%/+f--D-)@=&+kN-<&
)($-.(@+%&&"(&+F'%$(+.'(+#;;O+<;/&"N(@+&;+N"<'+;P+;")+.%N(G+-/@+.;+:);$$.(<'=&+&?&.(N P;/. +:'(+=.=+F-&+-@@(@+.;+&.-/@+P;)+g.;;$O%.gG+%/&C%)(@+#?+M.G+.'(+M+:;;$O%. +:'(+<;NC-/?+F-&
-@N%/%&.)-.;)&+P;)+O((C%/8+;")+N-<'%/(&+)"//%/8+-/@+;")+/(.F;)O&+<;NN"/%<-.%/8+.');"8';".+.'( %/<;)C;)-.(@+;/+K-)<'+QG+5\\QG+;)%8%/-$$?+-&+>"-&-)+:(<'/;$;8%(&G+.'(/+-&+:);$$+:(<'G+-/@+.;@-?+-&
C);c(<. :);$$.(<'
L/+.'(+C);@"<.%;/+&%@(G+:)(/.;/+1<'"$h+<)(-.(@+.'(+-<<;NC-/?%/8+A,G+-/@+:);$$.(<'=&+A-.')%/(+2;)( 0/+UC)%$+5\\aG+.'-/O&+.;+-+<;/.-<.+N-@(+.');"8'+;/(+;P+f--D-)@=&+"/%D()&%.?+C);P(&&;)&G+.'(
'-/@$(@+.'(+<;/.)-<.&+-/@+$(8-$%.%(&+;/+;")+#('-$P +:'-/O&+-$&;+.;+3-.'-/+A$(N(/.+P;)+.'(+:);$$ 3;)F(8%-/+<;NC-/?+K(.%&+8-D(+.'(N+-+<;/.)-<.+.;+@(D($;C+&;P.F-)(+#-&(@+;/+>. +U);"/@+.'%&+.%N(G
%$$"&.)-.%;/& +U/@+$-&.+#".+/;. $(-&.G+.'-/O&+.;+H-)-+E?&;/8+P);N+!(-)&;/&G+P;)+'-/@$%/8+.'( :);$$.(<'+'%)(@+U)/.+T"$#)-/@&(/G+F';+@")%/8+'%&+&%I+?(-)&+-.+:);$$.(<'+@(D%&(@+-/@+%NC$(N(/.(@+-/
C);@"<.%;/+C)-<.%<-$%.%(&+&;+F($$ %/8(/%;"&+@;<"N(/.-.%;/+&?&.(N+-&+F($$+-&+<;/.)%#".%/8+.;+>.=&+<;@(
0/+K-)<'+5\\`G+.'(+k");C(-/+1C-<(+U8(/<?+#(<-N(+.'(+&(<;/@+>.+<"&.;N()G+F%.'+-+C")<'-&(+;P+.(/
<;NN()<%-$+$%<(/&(& +E%.'+"/F-D()%/8+P-%.'G+k%)%O+-/@+f--D-)@+'%)(@+-/;.'()+@(D($;C() +>.+6 \_+F-&
)($(-&(@+-.+.'(+(/@+;P+K-?G+-/@+;/+1(C.(N#()+SQG+5\\`G+>.+5 6+<-N(+;". +2?+.'(+(/@+;P+.'(+?(-)G
>.+'-@+)(-<'(@+D()&%;/+5 5i+(%8'.+<"&.;N()&G+(-<'+%/+-+@%PP()(/.+<;"/.)?G+'-@+#;"8'.+5Z+$%<(/&(&
#(.F((/+.'(N +:'%&+?(-)+-$&;+&-F+.'(+P;"/@%/8+;P+.'(+l,k+C);c(<.G+$(@+#?+K-..'%-&+k..)%<'
K-..'%-&+c;%/(@+:);$$.(<'+%/+5\\ZG+-/@+.'(+$-&.+N-c;)+>.+5+)($(-&(G+5 Q6G+F-&+N-@(+%/+1(C.(N#()+;P
.'-.+?(-) +>.+S 6+F-&+)($(-&(@+%/+V"/(+5\\\ +>.+S+'-@+-+/(F+;C(/+&;")<(+$%<(/&(G+.'(+>+!"#$%<
H%<(/&(+Y>!H[G+F'%<'+<;NC$%(@+F%.'+.'(+LC(/+1;")<(+,(P%/%.%;/ +0/+U"8"&.+5\\\G+>.+F;/+.'(
H%/"IE;)$@+-F-)@+P;)+#(&.+$%#)-)?J.;;$ +U);"/@+.'%&+.%N(G+:);$$.(<'+!.?+H.@+YU"&.)-$%-[+F-&
(&.-#$%&'(@ Part 1: Basic Qt
:);$$.(<'+)($(-&(@+>.;C%-+A;)(+Y.'(/+<-$$(@+>.JkN#(@@(@[+%/+S666 +0.+F-&+@(&%8/(@+.;+)"/+;/
(N#(@@(@+H%/"I+@(D%<(&+-/@+C);D%@(@+%.&+;F/+F%/@;F+&?&.(N+-&+-+$%8'.F(%8'.+)(C$-<(N(/.+P;)+M55
2;.'+>.JM55+-/@+>.;C%-+A;)(+F()(+/;F+;PP()(@+"/@()+.'(+F%@($?+"&(@+T39+T(/()-$+!"#$%<+H%<(/&(
YT!H[+-&+F($$+-&+"/@()+<;NN()<%-$+$%<(/&(& +2?+.'(+(/@+;P+S666G+:);$$.(<'+'-@+(&.-#$%&'(@+:);$$.(<' A'-C.()+5 +T(..%/8+1.-).(@
0/< Y91U[+-/@+'-@+)($(-&(@+.'(+P%)&.+D()&%;/+;P+>.;C%-G+-/+-CC$%<-.%;/+C$-.P;)N+P;)+N;#%$(+C';/(&
-/@+!,U& +>.;C%-+A;)(+F;/+.'(+H%/"IE;)$@+g2(&.+kN#(@@(@+H%/"I+1;$".%;/g+-F-)@+%/+#;.'+S665+-/@ A'-C.()+S +A)(-.%/8+,%-$;8&
S66SG+-/@+>.;C%-+!';/(+-<'%(D(@+.'(+&-N(+@%&.%/<.%;/+%/+S66Q
A'-C.()+7 +A)(-.%/8+K-%/+E%/@;F&
>.+7 6+F-&+)($(-&(@+%/+S665 +>.+F-&+/;F+-D-%$-#$(+;/+E%/@;F&G+K-<+L1+MG+9/%IG+-/@+H%/"I+Y@(&O.;C
-/@+(N#(@@(@[ +>.+7+C);D%@(@+QS+/(F+<$-&&(&+-/@+%.&+<;@(+(I<((@(@+a66G666+$%/(& +>.+7+F-&+- A'-C.()+Q +0NC$(N(/.%/8+UCC$%<-.%;/+X"/<.%;/-$%.?
N-c;)+&.(C+P;)F-)@+P);N+>.+SG+%/<$"@%/8+<;/&%@()-#$?+%NC);D(@+$;<-$(+-/@+9/%<;@(+&"CC;).G+-
<;NC$(.($?+/(F+.(I.+D%(F%/8+-/@+(@%.%/8+F%@8(.G+-/@+-+!()$4$%O(+)(8"$-)+(IC)(&&%;/+<$-&& +>.+7+F;/
A'-C.()+a +A)(-.%/8+A"&.;N+E%@8(.&
.'(+1;P.F-)(+,(D($;CN(/.+:%N(&+gV;$.+!);@"<.%D%.?+UF-)@g+%/+S66S
U$&;+%/+S66aG+:);$$.(<'+;C(/(@+-+)(C)(&(/.-.%D(+;PP%<(+%/+2(%c%/8+.;+C);D%@(+<"&.;N()&+%/+A'%/-+-/@
.'(+)(8%;/+F%.'+&-$(&+&()D%<(&G+.)-%/%/8G+-/@+.(<'/%<-$+&"CC;).+P;)+>.;C%-
1%/<(+:);$$.(<'=&+#%).'G+>.=&+C;C"$-)%.?+'-&+8);F/+"/-#-.(@+-/@+<;/.%/"(&+.;+8);F+.;+.'%&+@-? +:'%&
&"<<(&&+%&+-+)(P$(<.%;/+#;.'+;P+.'(+R"-$%.?+;P+>.+-/@+;P+';F+(/c;?-#$(+%.+%&+.;+"&( +0/+.'(+$-&.+@(<-@(G
>.+'-&+8;/(+P);N+#(%/8+-+C);@"<.+"&(@+#?+-+&($(<.+P(F+g%/+.'(+O/;Fg+.;+;/(+.'-.+%&+"&(@+@-%$?+#?
.';"&-/@&+;P+<"&.;N()&+-/@+.(/&+;P+.';"&-/@&+;P+;C(/+&;")<(+@(D($;C()&+-$$+-);"/@+.'(+F;)$@
gN;"&(+C)(&&g+-/@+-+gN;"&(+)($(-&(g+(D(/.+-)(+8(/()-.(@ +0/+.'%&+)(&C(<.G+T90+-CC$%<-.%;/&+@%PP()
@)-&.%<-$$?+P);N+<;/D(/.%;/-$+#-.<'+C);8)-N&G+F'%<'+.?C%<-$$?+C);<(&&+%/C".G+C);@"<(+)(&"$.&G+-/@
Chapter 1. Getting Started .()N%/-.(+F%.';".+'"N-/+%/.()D(/.%;/
0P+?;"+-$)(-@?+O/;F+V-D-+;)+Am+#".+'-D(+$%N%.(@+(IC()%(/<(+F%.'+ABBG+?;"+N%8'.+F-/.+.;+&.-).+#?
)(-@%/8+.'(+ABB+%/.);@"<.%;/+%/ UCC(/@%I+2
0.+%&+/;F+C;&&%#$(+.;+.)?+.'(+C);8)-N+;/+?;")+;F/+N-<'%/( +X%)&.G+?;"+F%$$+/((@+.;+%/&.-$$+>.+Q 5 5+Y;)
-+$-.()+>.+Q+)($(-&([G+-+C);<(&&+.'-.+%&+(IC$-%/(@+%/ UCC(/@%I+U +X);N+/;F+;/G+F(+F%$$+-&&"N(+.'-.
?;"+'-D(+-+<;))(<.$?+%/&.-$$(@+<;C?+;P+>.+Q+-/@+.'-.+>.=& bin+@%)(<.;)?+%&+%/+?;") PATH+(/D%);/N(/.
D-)%-#$( +YL/+E%/@;F&G+.'%&+%&+@;/(+-".;N-.%<-$$?+#?+.'(+>.+%/&.-$$-.%;/+C);8)-N [+j;"+F%$$+-$&;+/((@
.'(+C);8)-N=&+&;")<(+<;@(+%/+-+P%$(+<-$$(@ hello.cpp+%/+-+@%)(<.;)?+<-$$(@ hello +j;"+<-/+.?C(+%/
Hello Qt hello.cpp+?;")&($PG+;)+<;C?+%.+P);N+.'(+A,+C);D%@(@+F%.'+.'%&+#;;OG+F'()(+%.+%&+-D-%$-#$(+-&
/examples/chap01/hello/hello.cpp
H(.=&+&.-).+F%.'+-+D()?+&%NC$(+>.+C);8)-N +E(+F%$$+P%)&.+&."@?+%.+$%/(+#?+$%/(G+.'(/+F(+F%$$+&((+';F+.;
<;NC%$(+-/@+)"/+%.
X);N+-+<;NN-/@+C);NC.G+<'-/8(+.'(+@%)(<.;)?+.; helloG+.'(/+.?C(
1 #include <QApplication>
qmake -project
2 #include <QLabel>
3 int main(int argc, char *argv[])
4 {
5 QApplication app(argc, argv); .;+<)(-.(+-+C$-.P;)N4%/@(C(/@(/.+C);c(<.+P%$(+Yhello.pro[G+.'(/+.?C(
6 QLabel *label = new QLabel("Hello Qt!");
7 label->show();
8 return app.exec(); qmake hello.pro
9 }
.;+<)(-.(+-+C$-.P;)N4&C(<%P%<+N-O(P%$(+P);N+.'(+C);c(<.+P%$(
H%/(&+5+-/@+S+%/<$"@(+.'(+@(P%/%.%;/&+;P+.'( QApplication+-/@ QLabel+<$-&&(& +X;)+(D()?+>.+<$-&&G
.'()(+%&+-+'(-@()+P%$(+F%.'+.'(+&-N(+/-N(+Y-/@+<-C%.-$%h-.%;/[+-&+.'(+<$-&&+.'-.+<;/.-%/&+.'(+<$-&&=&
:?C( make+.;+#"%$@+.'(+C);8)-N rst+W"/+%.+#?+.?C%/8 hello+;/+E%/@;F&G ./hello+;/+9/%IG+-/@ open
@(P%/%.%;/
hello.app+;/+K-<+L1+M +:;+.()N%/-.(+.'(+C);8)-NG+<$%<O+.'(+<$;&(+#"..;/+%/+.'(+F%/@;F=&+.%.$(+#-)
K(!$'("/(",$"$+"2$"20("+(C2"(C&<63(="3(2D)"0&1(")$<("!%+L"M(63&8("20("3*+(
-("/*33"+$/"@%*3."20("&663*8&2*$+A"-("&))%<("20&2"#$%"0&1("8'(&2(."&".*'(82$'#"8&33(. quit
QLabel *label = new QLabel("Hello Qt!"); 8$+2&*+*+, quit.cppA"M%+ qmake"*+"20( quit".*'(82$'#"2$",(+('&2("20("6'$I(82"!*3(="20(+"'%+"*2"&,&*+"2$
,(+('&2("&"<&Q(!*3(="&)"!$33$/)L
&+."'(@%*3."20("&663*8&2*$+A"H)"20("(C&<63("*33%)2'&2()="*2D)"(&)#"2$"@'*,02(+"%6"&"42"&663*8&2*$+D)
%)('"*+2('!&8("%)*+,")$<(")*<63("NB:OP)2#3("!$'<&22*+,A
Laying Out Widgets
+"20*)")(82*$+= /("/*33"8'(&2("&")<&33"(C&<63("&663*8&2*$+"20&2".(<$+)2'&2()"0$/"2$"%)("3&#$%2)"2$
<&+&,("20(",($<(2'#"$!"/*.,(2)"*+"&"/*+.$/"&+."0$/"2$"%)(")*,+&3)"&+.")3$2)"2$")#+80'$+*[("2/$
/*.,(2)A"B0("&663*8&2*$+"&)Q)"!$'"20("%)('D)"&,(="/0*80"20("%)('"8&+"(+2('"@# <&+*6%3&2*+,"(*20('"&
Making Connections )6*+"@$C"$'"&")3*.('A
1 #include <QApplication>
42D)"/*.,(2)"(<*2 !"#$% "2$"*+.*8&2("20&2"&"%)('"&82*$+"$'"&"80&+,("$!")2&2("0&)"$88%''(.A UVW"X$' 2 #include <QHBoxLayout>
3 #include <QSlider>
4 #include <QSpinBox>
5 int main(int argc, char *argv[])
6 {
7 QApplication app(argc, argv);
8 QWidget *window = new QWidget;
9 window->setWindowTitle("Enter Your Age");
10 QSpinBox *spinBox = new QSpinBox;
11 QSlider *slider = new QSlider(Qt::Horizontal);
12 spinBox->setRange(0, 130);
13 slider->setRange(0, 130);
14 QObject::connect(spinBox, SIGNAL(valueChanged(int)),
15 slider, SLOT(setValue(int)));
16 QObject::connect(slider, SIGNAL(valueChanged(int)),
17 spinBox, SLOT(setValue(int)));
18 spinBox->setValue(35);
19 QHBoxLayout *layout = new QHBoxLayout;
20 layout->addWidget(spinBox);
21 layout->addWidget(slider);
22 window->setLayout(layout);
23 window->show();
24 return app.exec();
25 }
+"3*+()"^]"2$"``="/("3&#"$%2"20(")6*+"@$C"&+.")3*.('"/*.,(2)"%)*+,"& %$.&/'01$#$",+A"H"3&#$%2
O*+()"\"&+."]")(2"%6"20( QWidget"20&2"/*33")('1("&)"20("&663*8&2*$+D)"<&*+"/*+.$/A"-("8&33 <&+&,('"*)"&+"$@I(82"20&2")(2)"20(")*[("&+."6$)*2*$+"$!"20("/*.,(2)"20&2"3*("%+.('"*2)"'()6$+)*@*3*2#A
setWindowTitle()"2$")(2"20("2(C2".*)63&#(."*+"20("/*+.$/D)"2*23("@&'A 42"0&)"20'(("<&*+"3&#$%2"<&+&,('"83&))()L
42D)"&66'$&80"2$"@%*3.*+,"%)('"*+2('!&8()"*)")*<63("2$"%+.(')2&+."&+."1('#"!3(C*@3(A"B0("<$)2
8$<<$+"6&22('+"20&2"42"6'$,'&<<(')"%)("*)"2$"*+)2&+2*&2("20("'(R%*'(."/*.,(2)"&+."20(+")(2"20(*'
6'$6('2*()"&)"+(8())&'#A"?'$,'&<<(')"&.."20("/*.,(2)"2$"3&#$%2)="/0*80"&%2$<&2*8&33#"2&Q("8&'("$!
)*[*+,"&+."6$)*2*$+*+,A"f)('"*+2('!&8("@(0&1*$'"*)"<&+&,(."@#"8$++(82*+,"/*.,(2)"2$,(20('"%)*+,"42D)
)*,+&3)"&+.")3$2)"<(80&+*)<A
Using the Reference Documentation
42D)"'(!('(+8(".$8%<(+2&2*$+"*)"&+"())(+2*&3"2$$3"!$'"&+#"42".(1(3$6('=")*+8("*2"8$1(')"(1('#"83&))
&+."!%+82*$+"*+"42A"B0*)"@$$Q"<&Q()"%)("$!"<&+#"42"83&))()"&+."!%+82*$+)="@%2"*2".$()"+$2"8$1('"&33
$!"20(<="+$'".$()"*2"6'$1*.("(1('#".(2&*3"$!"20$)("20&2"&'("<(+2*$+(.A"B$",(2"20("<$)2"@(+(!*2"!'$<
42="#$%")0$%3."!&<*3*&'*[("#$%')(3!"/*20"20("42"'(!('(+8(".$8%<(+2&2*$+"&)"R%*8Q3#"&)"6$))*@3(A
B0(".$8%<(+2&2*$+"*)"&1&*3&@3("*+"NB:O"!$'<&2"*+"42D) doc/html".*'(82$'#"&+."8&+"@("'(&."%)*+,"&+#
/(@"@'$/)('A"g$%"8&+"&3)$"%)( 2'03 ! '$#'="20("42"0(36"@'$/)('="/0*80"0&)"6$/('!%3")(&'80*+,
&+."*+.(C*+,"!(&2%'()"20&2"<&Q("*2"R%*8Q('"&+."(&)*('"2$"%)("20&+"&"/(@"@'$/)('A"B$"3&%+80 2'
3 ! '$#'="83*8Q"42"@#"B'$332(80"1bACA#hH))*)2&+2"*+"20("72&'2"<(+%"$+"-*+.$/)="2#6( assistant"$+
20("8$<<&+."3*+("$+"f+*C="$'".$%@3(P83*8Q"H))*)2&+2"*+"20(":&8"57"J"X*+.('A
B0("'(!('(+8(".$8%<(+2&2*$+"!$'"20("8%''(+2"1(')*$+"$!"42"&+."!$'")$<("(&'3*('"1(')*$+)"*)"&1&*3&@3(
B0("3*+Q)"*+"20("eH? "M(!('(+8(e")(82*$+"$+"20("0$<("6&,("6'$1*.(".*!!('(+2"/&#)"$!"+&1*,&2*+,"42D)
$+3*+("&2 0226Lii.$8A2'$332(80A8$<iA"B0*)")*2("&3)$"0&)")(3(82(."&'2*83()"!'$< 2'02/$+',+%.="20("42
83&))()A"B0("eH33"F3&))()e"6&,("3*)2)"(1('#"83&))"*+"42D)"H? A"B0("e:&*+"F3&))()e"6&,("3*)2)"$+3#"20(
6'$,'&<<(')D"+(/)3(22('")(+2"2$"&33"8$<<('8*&3"3*8(+)(()A
<$)2"8$<<$+3#"%)(."42"83&))()A"H)"&+"(C('8*)(="#$%"<*,02"/&+2"2$"3$$Q"%6"20("83&))()"&+.
!%+82*$+)"20&2"/("0&1("%)(."*+"20*)"80&62('A
!"#$%&'(K(&G/L+%1&,C,!+,-+%&%C%$L.0%$%
-*20"42iJ^^"&+."42$6*&"F$'(="20(".(!&%32")2#3("*)"?3&)2*R%(="/0*80"%)()",'&.*(+2)"&+.
&+2*P&3*&)*+,"2$"6'$1*.("&"<$.('+"3$$Q"&+."!((3A"42"&663*8&2*$+"%)(')"8&+"$1(''*.("20(
Z$2("20&2"*+0('*2(."!%+82*$+) &'(".$8%<(+2(."*+"20("@&)("83&))Y"!$'"(C&<63(= QPushButton"0&)"+$ .(!&%32")2#3("@#"%)*+,"20( -style"8$<<&+.P3*+("$62*$+A"X$'"(C&<63(="2$"3&%+80"20("H,(
show()"!%+82*$+"$!"*2)"$/+="@%2"*2"*+0('*2)"$+("!'$<"*2)"&+8()2$' QWidgetA X*,%'("^A\")0$/)"0$/"20( &663*8&2*$+"%)*+,"20(":$2*!")2#3("$+"J^^=")*<63#"2#6(
83&))()"/("0&1(")((+")$"!&'"'(3&2("2$"(&80"$20('A
$+"20("8$<<&+."3*+(A
!"#$%&'('M(&N+,/78$9O1=%2!7!2&1/L+%1
Chapter 2. Creating Dialogs
• ()*+,&$$%'-" .%&,/-
• (%-'&,$"&'0"(,/!$"%'".12!3
• 4&2%0".%&,/-".1$%-'
• (3&21563&'-%'-".%&,/-$
• .7'&8%+".%&,/-$
• 9)%,!5%'":%0-1!"&'0".%&,/-"6,&$$1$
f+3*Q("20("$20('")2#3()="20("-*+.$/)"J?"&+.":&8")2#3()"&'("$+3#"&1&*3&@3("$+"20(*'"+&2*1(
63&2!$'<)=")*+8("20(#"'(3#"$+"20("63&2!$'<)D"20(<("(+,*+()A
B0*)"80&62('"/*33"2(&80"#$%"0$/"2$"8'(&2(".*&3$,"@$C()"%)*+,"42A">*&3$,"@$C()"6'()(+2"%)(')"/*20
$62*$+)"&+."80$*8()="&+."&33$/"20(<"2$")(2"20("$62*$+)"2$"20(*'"6'(!(''(."1&3%()"&+."2$"<&Q("20(*'
80$*8()A"B0(#"&'("8&33(.".*&3$,"@$C()="$'")*<63#"e.*&3$,)e="@(8&%)("20(#"6'$1*.("&"<(&+)"@#"/0*80
B0*)"80&62('"0&)"*+2'$.%8(."20("Q(#"8$+8(62)"$!")*,+&3)3$2"8$++(82*$+)"&+. 3&#$%2)A" 2"0&)"&3)$ %)(')"&+."&663*8&2*$+)"8&+"e2&3Q"2$e"(&80"$20('A
@(,%+"2$"'(1(&3"42D)"8$+)*)2(+2"&+."!%33#"$@I(82P$'*(+2(."&66'$&80"2$"20("8$+)2'%82*$+"&+."%)("$!
/*.,(2)A" !"#$%"@'$/)("20'$%,0"42D)".$8%<(+2&2*$+="#$%"/*33"!*+."&"%+*!$'<*2#"$!"&66'$&80"20&2 :$)2";f "&663*8&2*$+)"8$+)*)2"$!"&"<&*+"/*+.$/"/*20"&"<(+%"@&'"&+."2$$3@&'="&3$+,"/*20".$[(+)"$!
<&Q()"*2")2'&*,02!$'/&'."2$"3(&'+"0$/"2$"%)("+(/"/*.,(2)="&+."#$%"/*33"&3)$"!*+."20&2"42D)"8&'(!%33# .*&3$,)"20&2"8$<63(<(+2"20("<&*+"/*+.$/A" 2"*)"&3)$"6$))*@3("2$"8'(&2(".*&3$,"&663*8&2*$+)"20&2
80$)(+"+&<()"!$'"!%+82*$+)="6&'&<(2(')="(+%<)="&+.")$"$+="<&Q("6'$,'&<<*+,"*+"42")%'6'*)*+,3# '()6$+.".*'(823#"2$"20("%)('D)"80$*8() @#"6('!$'<*+,"20("&66'$6'*&2("&82*$+)"S!$'"(C&<63(="&
63(&)&+2"&+."(&)#A 8&38%3&2$'"&663*8&2*$+TA
Subclassing QDialog
5%'"!*')2"(C&<63("*)"&"X*+.".*&3$,"/'*22(+"(+2*'(3#"*+"FGGA"-("/*33"*<63(<(+2"20(".*&3$,"&)"&"83&))"*+
*2)"$/+"'*,02A"K#".$*+,")$="/("<&Q("*2"&+"*+.(6(+.(+2=")(3!P8$+2&*+(."8$<6$+(+2="/*20"*2)"$/+
)*,+&3)"&+.")3$2)A
!"#$%&)('(&40%& !:A&A!,+8"
1 #ifndef FINDDIALOG_H
2 #define FINDDIALOG_H
3 #include <QDialog>
4 class QCheckBox;
5 class QLabel;
6 class QLineEdit;
7 class QPushButton;
20(#"&'("&33"6$*+2(')"&+."/(".$+D2"&88())"20(<"*+"20("0(&.('"!*3(=")$"20("8$<6*3('".$()+D2"+((."20(
O*+()"^"&+."`"S&+."`cT"6'$2(82"20("0(&.('"!*3("&,&*+)2"<%32*63("*+83%)*$+)A !%33"83&))".(!*+*2*$+)A"-("8$%3."0&1("*+83%.(."20("'(3(1&+2"0(&.('"!*3()"S <QCheckBox>= <QLabel>="(28AT=
@%2"%)*+,"!$'/&'.".(83&'&2*$+)"/0(+"*2"*)"6$))*@3("<&Q()"8$<6*3*+,")$<(/0&2"!&)2('A
O*+("a"*+83%.()"20(".(!*+*2*$+"$! QDialog="20("@&)("83&))"!$'".*&3$,)"*+"42A QDialog"*+0('*2) QWidgetA
-("/*33"+$/ 3$$Q"&2 finddialog.cpp="/0*80"8$+2&*+)"20("*<63(<(+2&2*$+"$!"20( FindDialog"83&))A
O*+()"b"2$"c"&'("!$'/&'.".(83&'&2*$+)"$!"20("42"83&))()"20&2"/("/*33"%)("2$"*<63(<(+2"20(".*&3$,A"H
5&+6$+*0*,(%$+$'!&#"2(33)"20("FGG"8$<6*3('"20&2"&"83&))"(C*)2)="/*20$%2",*1*+,"&33"20(".(2&*3"20&2"&
83&))".(!*+*2*$+"S%)%&33#"3$8&2(."*+"&"0(&.('"!*3("$!"*2)"$/+T"6'$1*.()A"-("/*33")&#"<$'("&@$%2"20*) 1 #include <QtGui>
)0$'23#A 2 #include "finddialog.h"
+"20("83&))D)"6'*1&2(")(82*$+="/(".(83&'("2/$")3$2)A"B$"*<63(<(+2"20(")3$2)="/("/*33"+((."2$"&88())
<$)2"$!"20(".*&3$,D)"80*3."/*.,(2)=")$"/("Q((6"6$*+2(')"2$"20(<"&)"/(33A"B0( slots"Q(#/$'."*)="3*Q( 15 connect(lineEdit, SIGNAL(textChanged(const QString &)),
signals="&"<&8'$"20&2"(C6&+.)"*+2$"&"8$+)2'%82"20&2"20("FGG"8$<6*3('"8&+".*,()2A
16 this, SLOT(enableFindButton(const QString &)));
17 connect(findButton, SIGNAL(clicked()),
18 this, SLOT(findClicked()));
X$'"20("6'*1&2("1&'*&@3()="/("%)(."!$'/&'.".(83&'&2*$+)"$!"20(*'"83&))()A"B0*)"/&)"6$))*@3("@(8&%)( 19 connect(closeButton, SIGNAL(clicked()),
20 this, SLOT(close())); &%2$<&2*8&33#"'(6&'(+2(.A"B0(+="/0(+"20("<&*+"3&#$%2"*)"*+)2&33(."$+"20(".*&3$,"S3*+("adT="*2"@(8$<()
&"80*3."$!"20(".*&3$,="&+."&33"20("/*.,(2)"*+"20("3&#$%2)"&'("'(6&'(+2(."2$"@(8$<("80*3.'(+"$!"20(
.*&3$,A"B0("'()%32*+,"6&'(+280*3."0*('&'80#"*)".(6*82(."*+ X*,%'("`AaA
B0("6'*1&2(")3$2 enableFindButton(const QString &)"*)"8&33(."/0(+(1('"20("2(C2"*+"20("3*+("(.*2$'
80&+,()A"B0("6'*1&2(")3$2 findClicked()"*)"8&33(."/0(+"20("%)('"83*8Q)"20("X*+."@%22$+A"B0(".*&3$, !"#$%&)(;(&40%& !:A&A!,+8"B1&=,$%:/20!+A&$%+,/!8:10!=1
83$)()"*2)(3!"/0(+"20("%)('"83*8Q)"F3$)(A"B0( close()")3$2"*)"*+0('*2(."!'$< QWidget="&+."*2)".(!&%32
@(0&1*$'"*)"2$"0*.("20("/*.,(2"!'$<"1*(/"S/*20$%2".(3(2*+,"*2TA"-("/*33"3$$Q"&2"20("8$.("!$'"20(
enableFindButton()"&+. findClicked()")3$2)"3&2('"$+A
B0( connect()")2&2(<(+2"3$$Q)"3*Q("20*)L
X$' moc"2$"/$'Q"8$''(823#="/("<%)2"6%2"20("83&))".(!*+*2*$+"*+"&"0(&.('"!*3(=")(6&'&2("!'$<"20(
/0('( sender"&+. receiver"&'("6$*+2(')"2$ QObject)"&+."/0('( signal"&+. slot"&'("!%+82*$+
*<63(<(+2&2*$+"!*3(A"B0("8$.(",(+('&2(."@# moc"*+83%.()"20*)"0(&.('"!*3("&+."&..)")$<("FGG"<&,*8
)*,+&2%'()"/*20$%2"6&'&<(2('"+&<()A"B0( SIGNAL()"&+. SLOT()"<&8'$)"())(+2*&33#"8$+1('2"20(*'
$!"*2)"$/+A
&',%<(+2"2$"&")2'*+,A
E*)%&3"FGGD)"$%26%2")2&'2)"3*Q("20*)L -0(+"20(")*,+&3"*)"(<*22(.="20(")3$2)"&'("8&33(."$+("&!2('"20("$20('="*+"&+"%+)6(8*!*(."$'.('A
• 5,:L&1!":,+1&2,:&-%&28::%2/%A&/8&/0%&1,9%&1+8/P
finddialog.obj : error LNK2001: unresolved external symbol •
"public:~virtual int __thiscall MyClass::qt_metacall(enum QMetaObject • connect(lcd, SIGNAL(overflow()),
::Call,int,void * *)" • this, SLOT(handleMathError()));
• connect(calculator, SIGNAL(divisionByZero()),
• this, SLOT(handleMathError()));
!"20*)"(1('"0&66(+)"2$"#$%="'%+ qmake"&,&*+"2$"%6.&2("20("<&Q(!*3(="20(+"'(@%*3."20("&663*8&2*$+A
-0(+"(*20('")*,+&3"*)"(<*22(.="20(")3$2"*)"8&33(.A
Z$/"'%+"20("6'$,'&<A" !")0$'28%2"Q(#)"&'(")0$/+"$+"#$%'"63&2!$'<="1('*!#"20&2"20(")0$'28%2"Q(#)
H32G-="H32GF="H32GK="&+."H32GX"2'*,,('"20("8$''(82"@(0&1*$'A"?'())"B&@"2$"+&1*,&2("20'$%,0"20( • *&1!":,+&2,:&-%&28::%2/%A&/8&,:8/0%$&1!":,+P
/*.,(2)"/*20"20("Q(#@$&'.A"B0(".(!&%32"2&@"$'.('"*)"20("$'.('"*+"/0*80"20("/*.,(2)"/('("8'(&2(.A •
B0*)"8&+"@("80&+,(."%)*+, QWidget::setTabOrder()A • connect(lineEdit, SIGNAL(textChanged(const QString &)),
• this, SIGNAL(updateRecord(const QString &)));
?'$1*.*+,"&")(+)*@3("2&@"$'.('"&+."Q(#@$&'.")0$'28%2)"(+)%'()"20&2"%)(')"/0$".$+D2"/&+2"2$"S$'
8&++$2T"%)("&"<$%)("&'("&@3("2$"<&Q("!%33"%)("$!"20("&663*8&2*$+A"X%33"Q(#@$&'."8$+2'$3"*)"&3)$
-0(+"20("!*')2")*,+&3"*)"(<*22(.="20(")(8$+.")*,+&3"*)"(<*22(."&)"/(33A"H6&'2"!'$<"20&2=
&66'(8*&2(."@#"!&)2"2#6*)2)A
)*,+&3)*,+&3"8$++(82*$+)"&'("*+.*)2*+,%*)0&@3("!'$<")*,+&3)3$2"8$++(82*$+)A
+ F0&62('"a="/("/*33"%)("20("X*+.".*&3$,"*+)*.("&"'(&3"&663*8&2*$+="&+."/("/*33"8$++(82"20(
• @8::%2/!8:1&2,:&-%&$%98C%AP
findPrevious()"&+. findNext()")*,+&3)"2$")$<(")3$2)A
•
• disconnect(lcd, SIGNAL(overflow()),
• this, SLOT(handleMathError()));
B0("<(80&+*)<"*)"8&33(."20( 1,'$C&BD,('0 . ',1= &+."*2"6'$1*.()"2/$"Q(#")('1*8()L
B0*)"*)"'&'(3#"+((.(.="@(8&%)("42"&%2$<&2*8&33#"'(<$1()"&33"8$++(82*$+)"*+1$31*+,"&+"$@I(82 )*,+&3))3$2)"&+."*+2'$)6(82*$+A"B0("*+2'$)6(82*$+"!%+82*$+&3*2#"*)"+(8())&'#"!$'
/0(+"20&2"$@I(82"*)".(3(2(.A *<63(<(+2*+,")*,+&3)"&+.")3$2)="&+."&33$/)"&663*8&2*$+"6'$,'&<<(')"2$"$@2&*+"e<(2&P
*+!$'<&2*$+e"&@$%2 QObject")%@83&))()"&2"'%+P2*<(="*+83%.*+,"20("3*)2"$!")*,+&3)"&+.")3$2)
B$")%88())!%33#"8$++(82"&")*,+&3"2$"&")3$2"S$'"2$"&+$20('")*,+&3T="20(#"<%)2"0&1("20(")&<("6&'&<(2(' )%66$'2(."@#"20("$@I(82"&+."*2)"83&))"+&<(A"B0("<(80&+*)<"&3)$")%66$'2)"6'$6('2*()
2#6()"*+"20(")&<("$'.('L S!$' 2'04, !"#,+T"&+."2(C2"2'&+)3&2*$+"S!$'"*+2('+&2*$+&3*[&2*$+T="&+."*2"3&#)"20(
!$%+.&2*$+"!$'"42"78'*62"!$'"H663*8&2*$+)"S47HTA
7$"!&'="/("0&1("$+3#"%)(.")*,+&3)"&+.")3$2)"/*20"/*.,(2)A"K%2"20("<(80&+*)< *2)(3!"*)"*<63(<(+2(."*+
H33"$!"20*)"*)"0&+.3(."&%2$<&2*8&33#"@# qmake= moc="&+. QObject=")$"#$%"'&'(3#"+((."2$
QObject"&+."*)+D2"3*<*2(."2$";f "6'$,'&<<*+,A"B0("<(80&+*)<"8&+"@("%)(."@#"&+# QObject")%@83&))L
20*+Q"&@$%2"*2A"K%2"*!"#$%"&'("8%'*$%)="#$%"8&+"80(8Q"$%2"20( QMetaObject"83&))
.$8%<(+2&2*$+"&+."0&1("&"3$$Q"&2"20("FGG")$%'8("!*3()",(+('&2(."@# moc"2$")(("0$/"20(
class Employee : public QObject *<63(<(+2&2*$+"/$'Q)A
{
Q_OBJECT
public:
Employee() { mySalary = 0; } Rapid Dialog Design
int salary() const { return mySalary; }
public slots:
void setSalary(int newSalary); 42"*)".()*,+(."2$"@("63(&)&+2"&+."*+2%*2*1("2$"0&+.P8$.(="&+."*2"*)"+$2"%+%)%&3"!$'"6'$,'&<<(')"2$
signals: .(1(3$6"(+2*'("42"&663*8&2*$+)"6%'(3#"@#"/'*2*+,"FGG")$%'8("8$.(A"72*33="<&+#"6'$,'&<<(')"6'(!('"2$
void salaryChanged(int newSalary); %)("&"1*)%&3"&66'$&80"!$'".()*,+*+,"!$'<)="@(8&%)("20(#"!*+."*2"<$'("+&2%'&3"&+."!&)2('"20&+"0&+.P
private: 8$.*+,="&+."20(#"/&+2"2$"@("&@3("2$"(C6('*<(+2"/*20"&+."80&+,(".()*,+)"<$'("R%*8Q3#"&+."(&)*3#
int mySalary; 20&+"*)"6$))*@3("/*20"0&+.P8$.(."!$'<)A
};
void Employee::setSalary(int newSalary) 2'04, !"#,+"(C6&+.)"20("$62*$+)"&1&*3&@3("2$"6'$,'&<<(')"@#"6'$1*.*+,"&"1*)%&3".()*,+
{ 8&6&@*3*2#A2'04, !"#,+"8&+"@("%)(."2$".(1(3$6"&33"$'"I%)2")$<("$!"&+"&663*8&2*$+D)"!$'<)A"X$'<)"20&2
if (newSalary != mySalary) { &'("8'(&2(."%)*+, 2'04, !"#,+"(+."%6"&)"FGG"8$.(=")$ 2'04, !"#,+"8&+"@("%)(."/*20"&
mySalary = newSalary;
8$+1(+2*$+&3"2$$3"80&*+"&+."*<6$)()"+$")6(8*&3"'(R%*'(<(+2)"$+"20("8$<6*3('A
emit salaryChanged(mySalary);
}
} +"20*)")(82*$+="/("/*33"%)( 2'04, !"#,+"2$"8'(&2("20(";$P2$PF(33".*&3$,")0$/+"*+ X*,%'("`AbA"H+.
/0(20('"/(".$"*2"*+"8$.("$'"*+ 2'04, !"#,+="8'(&2*+,"&".*&3$,"&3/&#)"*+1$31()"20(")&<(
!%+.&<(+2&3")2(6)L
Z$2*8("0$/"20( setSalary()")3$2"*)"*<63(<(+2(.A"-("$+3#"(<*2"20( salary-Changed()")*,+&3"*!
• F'(&2("&+."*+*2*&3*[("20("80*3."/*.,(2)A
newSalary != mySalaryA"B0*)"(+)%'()"20&2"8#83*8"8$++(82*$+)".$+D2"3(&."2$"*+!*+*2("3$$6)A
• ?%2"20("80*3."/*.,(2)"*+"3&#$%2)A
• 7(2"20("2&@"$'.('A
• 9)2&@3*)0")*,+&3)3$2"8$++(82*$+)A
Qt's Meta-Object System • <63(<(+2"20(".*&3$,D)"8%)2$<")3$2)A
5+("$!"42D)"<&I$'"&80*(1(<(+2)"0&)"@((+"20("(C2(+)*$+"$!"FGG"/*20"&"<(80&+*)<"!$' !"#$%&)(>(&40%&Q8O/8O@%++&A!,+8"
8'(&2*+,"*+.(6(+.(+2")$!2/&'("8$<6$+(+2)"20&2"8&+"@("@$%+."2$,(20('"/*20$%2"&+#
8$<6$+(+2"Q+$/*+,"&+#20*+,"&@$%2"20("$20('"8$<6$+(+2)"*2"*)"8$++(82(."2$A
B$"3&%+80 2'04, !"#,+="83*8Q"42"@#"B'$332(80"1bACA#h>()*,+('"*+"20("72&'2"<(+%"$+"-*+.$/)="2#6(
designer"$+"20("8$<<&+."3*+("$+"f+*C="$'".$%@3(P83*8Q">()*,+('"*+"20(":&8"57"J"X*+.('A"-0(+ 2' 7(2"(&80"/*.,(2D)"6'$6('2*()"%)*+, 2'04, !"#,+D)"6'$6('2#"(.*2$'L
4, !"#,+")2&'2)="*2"/*33"6$6"%6"&"3*)2"$!"2(<63&2()A"F3*8Q"20("e-*.,(2e"2(<63&2(="20(+"83*8Q"5lA"SB0(
e>*&3$,"/*20"K%22$+)"K$22$<e"2(<63&2("<*,02"3$$Q"2(<62*+,="@%2"!$'"20*)"(C&<63("/("/*33"8'(&2("20( ^A F3*8Q"20("2(C2"3&@(3A":&Q(")%'("20&2"*2) objectName"6'$6('2#"*)"e3&@(3e"&+.")(2"20( text
5l"&+."F&+8(3"@%22$+)"@#"0&+."2$")0$/"0$/"*2"*)".$+(AT"g$%")0$%3."+$/"0&1("&"/*+.$/"8&33(. 6'$6('2#"2$"ejF(33"O$8&2*$+LeA
ef+2*23(.eA `A F3*8Q"20("3*+("(.*2$'A":&Q(")%'("20&2"20( objectName"6'$6('2#"*)"e3*+(9.*2eA
aA F3*8Q"20("!*')2"@%22$+A"7(2"20( objectName"6'$6('2#"2$"e$QK%22$+e="20( enabled"6'$6('2#"2$
K#".(!&%32=2'04, !"#,+D)"%)('"*+2('!&8("8$+)*)2)"$!")(1('&3"2$6P3(1(3"/*+.$/)A" !"#$%"6'(!('"&+":> P e!&3)(e="20( text"6'$6('2#"2$"e5le="&+."20( default"6'$6('2#"2$"e2'%(eA
)2#3("*+2('!&8(="/*20"$+("2$6P3(1(3"/*+.$/"&+.")(1('&3")%@P/*+.$/)="83*8Q"9.*2hf)('" +2('!&8( bA F3*8Q"20(")(8$+."@%22$+A"7(2"20( objectName"6'$6('2#"2$"e8&+8(3K%22$+e"&+."20( text"6'$6('2#
:$.(h>$8Q(."-*+.$/A 2$"eF&+8(3eA
dA F3*8Q"20("!$'<D)"@&8Q,'$%+."2$")(3(82"20("!$'<"*2)(3!A"7(2 objectName"2$"e;$B$F(33>*&3$,e"&+.
B0("!*')2")2(6"*)"2$"8'(&2("20("80*3."/*.,(2)"&+."63&8("20(<"$+"20("!$'<A"F'(&2("$+("3&@(3="$+("3*+( windowTitle"2$"e;$"2$"F(33eA
(.*2$'="$+("0$'*[$+2&3")6&8('="&+."2/$"6%)0"@%22$+)A"X$'"(&80"*2(<=".'&,"*2)"+&<("$'"*8$+"!'$< 2'
4, !"#,+D)"/*.,(2"@$C"&+.".'$6"20("*2(<"'$%,03#"/0('("*2")0$%3.",$"$+"20("!$'<A"B0(")6&8('"*2(<= H33"20("/*.,(2)"3$$Q"!*+("+$/="(C8(62"20("2(C2"3&@(3="/0*80")0$/)"jF(33"O$8&2*$+A"F3*8Q"9.*2h9.*2
/0*80"*)"*+1*)*@3("*+"20("!*+&3"!$'<="*)")0$/+"*+ 2'04, !"#,+"&)"&"@3%(")6'*+,A K%..*()"2$"(+2('"&")6(8*&3"<$.("20&2"&33$/)"#$%"2$")(2"@%..*()A"Z(C2="83*8Q"20("3&@(3"&+.".'&,"20(
'(."&''$/"3*+("2$"20("3*+("(.*2$'="20(+"'(3(&)(A"B0("3&@(3")0$%3."+$/")0$/ F(33"O$8&2*$+"&+."0&1("20(
!"#$%&)(?( !".1$%-'1;&!:&A82R%A&.!:A8.&98A%&8:&S!:A8.1 3*+("(.*2$'"&)"*2)"@%..#A"F3*8Q"9.*2h9.*2"-*.,(2)"2$"3(&1("@%..#"<$.(A
B0("+(C2")2(6"*)"2$"3&#"$%2"20("/*.,(2)"$+"20("!$'<L
'( F3*8Q"20("F(33"O$8&2*$+"3&@(3"&+."6'())"70*!2"&)"#$%"83*8Q"20("3*+("(.*2$'"+(C2"2$"*2")$"20&2"20(#
&'("@$20")(3(82(.A F3*8Q"X$'<hO&#"5%2"N$'*[$+2&33#A
)( F3*8Q"20(")6&8('="20(+"0$3."70*!2"&)"#$%"83*8Q"20("!$'<D)"5l"&+."F&+8(3"@%22$+)A F3*8Q"X$'<hO&#
5%2"N$'*[$+2&33#A
;( F3*8Q"20("@&8Q,'$%+."$!"20("!$'<"2$".()(3(82"&+#")(3(82(."*2(<)="20(+"83*8Q"X$'<hO&#"5%2
Z$/".'&,"20("@$22$<"$!"20("!$'<"%6"2$"<&Q("*2")0$'2('A"B0*)")0$%3."6'$.%8("&"!$'<"20&2"*)")*<*3&'"2$ E('2*8&33#A
X*,%'("`AkA">$+D2")6(+."2$$"<%80"2*<("6$)*2*$+*+,"20("*2(<)"$+"20("!$'<Y"42D)"3&#$%2"<&+&,(')"/*33
3&#"20(<"$%2"6'(8*)(3#"3&2('"$+A >( F3*8Q"X$'<hH.I%)2"7*[("2$"'()*[("20("!$'<"2$"*2)"6'(!(''(.")*[(A
!"#$%&)(D(&40%&78$9&.!/0&189%&.!A"%/1
B0("'(."3*+()"20&2"&66(&'"$+"20("!$'<")0$/"20("3&#$%2)"20&2"0&1("@((+"8'(&2(.A"B0(#".$+D2"&66(&'
/0(+"20( !$'<"*)"'%+A
!"#$%&)(I(&40%&78$9&.!/0&/0%&+,L8#/1 {
public:
QLabel *label;
QLineEdit *lineEdit;
QSpacerItem *spacerItem;
QPushButton *okButton;
QPushButton *cancelButton;
...
void setupUi(QWidget *widget) {
...
}
};
Z$/"83*8Q"9.*2h9.*2"B&@"5'.('A"H"+%<@('"*+"&"@3%("'(82&+,3("/*33"&66(&'"+(C2"2$"(1('#"/*.,(2"20&2
8&+"&88(62"!$8%)A"F3*8Q"(&80"/*.,(2"*+"2%'+"*+"20("$'.('"#$%"/&+2"20(<"2$"&88(62"!$8%)="20(+"83*8Q 56)#8)&)$*').#(-*77#.!)7&='#,&6)$,'#*&B#<'#(-*774#E6)&#")#%7)#'6)#+!$/#,& main.cpp;#")#($)*')#*
9.*2h9.*2"-*.,(2)"2$"3(&1("2&@"$'.('"<$.(A QDialog#*&.#9*77#,'#'! setupUi()4
!"#$%&)(K(&G%//!:"&/0%&78$9B1&/,-&8$A%$ F+#B!%#$%&#'6)#9$!8$*/#&!";#'6)#.,*-!8#",--#"!$0;#A%'#,'#.!)7&='#+%&(',!&#)G*('-B#*7#")#"*&'D
• 56)#HI#A%''!&#,7#*-"*B7#.,7*A-).4
• 56)#>*&()-#A%''!&#.!)7#&!'6,&84
• 56)#-,&)#).,'!$#*(()9'7#*&B#')G';#,&7')*.#!+#!&-B#*(()9',&8#:*-,.#()--#-!(*',!&74
E)#(*&#/*0)#'6)#.,*-!8#+%&(',!	$!9)$-B#AB#"$,',&8#7!/)#(!.)4#56)#(-)*&)7'#*99$!*(6#,7#'!#($)*')
*#&)"#(-*77#'6*'#,&6)$,'7#A!'6 QDialog#*&. Ui::GoToCell-Dialog#*&.#'6*'#,/9-)/)&'7#'6)#/,77,&8
+%&(',!&*-,'B#1'6%7#9$!:,&8#'6)#*.*8)#'6*'#*&B#7!+'"*$)#9$!A-)/#(*&#A)#7!-:).#7,/9-B#AB#*..,&8
*&!'6)$#-*B)$#!+#,&.,$)(',!&34#H%$#&*/,&8#(!&:)&',!&#,7#'!#8,:)#'6,7#&)"#(-*77#'6)#7*/)#&*/)#*7#'6)
uicJ8)&)$*').#(-*77#A%'#",'6!%'#'6) Ui::#9$)+,G4
L-7!#,&#'6)#(!&7'$%('!$;#")#7)'#%9#*#:*-,.*'!$#'!#$)7'$,('#'6)#$*&8)#!+#'6)#,&9%'4#<'#9$!:,.)7#'6$))
A%,-'J,&#:*-,.*'!$#(-*77)7D QIntValidator; QDoubleValidator;#*&. QRegExpValidator4#M)$)#")#%7)#*
QRegExpValidator#",'6#'6)#$)8%-*$#)G9$)77,!&#NOLJP*JCQORJSQOTJSQUT;VWN;#"6,(6#/)*&7D#L--!"#!&)
%99)$(*7)#!$#-!")$(*7)#-)'')$;#+!--!").#AB#!&)#.,8,'#,&#'6)#$*&8)#R#'!#S;#+!--!").#AB#C)$!;#!&);#!$
'"!#.,8,'7#)*(6#,&#'6)#$*&8)#T#'!#S4#1X!$#*&#,&'$!.%(',!&#'!#$)8%-*$#)G9$)77,!&7;#7))#'6) QRegExp#(-*77 Shape-Changing Dialogs
.!(%/)&'*',!&43
E)#6*:)#7))!"#'!#($)*')#.,*-!87#'6*'#*-"*B7#76!"#'6)#7*/)#",.8)'7#"6)&):)$#'6)B#*$)#%7).4#F&
YB#9*77,&8 this#'!#'6) QRegExpValidator#(!&7'$%('!$;#")#/*0)#,'#*#(6,-.#!+#'6) GoToCellDialog 7!/)#(*7)7;#,'#,7#.)7,$*A-)#'!#9$!:,.)#.,*-!87#'6*'#(*&#(6*&8)#76*9)4#56)#'"!#/!7'#(!//!�,&.7#!+
!AZ)('4#YB#.!,&8#7!;#")#.!&='#6*:)#'!#"!$$B#*A!%'#.)-)',&8#'6) QRegExpValidator#-*')$2#,'#",--#A) 76*9)J(6*&8,&8#.,*-!87#*$) $*!$(%&+(",&-.+'%#*&. /0.!&12-'$",&-.+'%4#Y!'6#'B9)7#!+#.,*-!8#(*&
.)-)').#*%'!/*',(*--B#"6)&#,'7#9*$)&'#,7#.)-)').4 A)#,/9-)/)&'). ,&#<';#),'6)$#9%$)-B#,&#(!.)#!$#%7,&8 !"#$%&'($)4
X!$#",.8)'7;#'6)#9*$)&'#6*7#*&#*..,',!&*-#/)*&,&8D#>6,-.#",.8)'7#*$)#76!"&#",'6,&#'6)#9*$)&'=7
*$)*4#E6)&#")#.)-)')#'6)#9*$)&'#",.8)';#&!'#!&-B#.!)7#'6)#(6,-.#:*&,76#+$!/#/)/!$B;#,'#*-7!
:*&,76)7#+$!/#'6)#7($))&4
56) on_lineEdit_textChanged()#7-!'#)&*A-)7#!$#.,7*A-)7#'6)#HI#A%''!&;#*((!$.,&8#'!#"6)'6)$#'6)#-,&)
).,'#(!&'*,&7#*#:*-,.#()--#-!(*',!&4 QLineEdit::hasAcceptableInput()#%7)7#'6)#:*-,.*'!$#")#7)'#,&#'6)
(!&7'$%('!$4
56,7#(!/9-)')7#'6)#.,*-!84#E)#(*&#&!"#$)"$,') main.cpp#'!#%7)#,'D
R4 >-,(0#X,-)a )"#X!$/#*&.#(6!!7)#'6)#Nb,*-!8#",'6#Y%''!&7#[,86'N#')/9-*')4
V4 >$)*')#'6)#]!$)#A%''!&#*&.#.$*8#,'#,&'!#'6)#:)$',(*-#-*B!%';#A)-!"#'6)#:)$',(*-#79*()$4#`)'#'6)
]!$)#A%''!&=7 text#9$!9)$'B#'!#Nc]!$)N;#*&.#,'7 checkable#9$!9)$'B#'!#N'$%)N4 `)'#'6)#HI
A%''!&=7 default#9$!9)$'B#'!#N'$%)N4
d4 >$)*')#*#8$!%9#A!G;#'"!#-*A)-7;#'"!#(!/A!A!G)7;#*&.#!&)#6!$,C!&'*-#79*()$;#*&.#9%'#'6)/
*&B"6)$)#!&#'6) +!$/4
e4 b$*8#'6)#A!''!/#$,86'#(!$&)$#!+#'6)#8$!%9#A!G#'!#/*0)#,'#-*$8)$4#56)&#/!:)#'6)#!'6)$
",.8)'7#,&'!#'6)#8$!%9#A!G#*&.#9!7,',!&#'6)/#*99$!G,/*')-B#*7#76!"&#,& X,8%$)#V4RR#1*34
!"#$%&'())(&:1;!7"&.#/&/,%&"$.#6&<.8=4&9,!20$%7&!7&1&"$!0
Of,)"#+%--#7,C)#,/*8)Q
h4 >-,(0#'6)#+!$/#'!#.)7)-)('#*&B#7)-)(').#",.8)'7;#'6)&#(-,(0#X!$/a^*B#H%'#,&#*#l$,.4 56)#+!$/
76!%-.#&!"#/*'(6 X,8%$)#V4RV#1A34
j4 `)'#'6)#'"!#:)$',(*-#79*()$#,')/7= sizeHint#9$!9)$'B#'!#OVT;#TQ4
56)#$)7%-',&8#8$,.#-*B!%'#6*7#'"!#(!-%/&7#*&.#+!%$#$!"7;#8,:,&8#*#'!'*-#!+#),86'#()--74#56)#i$,/*$B
I)B#8$!%9#A!G;#'6)#-)+'/!7'#:)$',(*-#79*()$#,')/;#'6)#`)(!&.*$B#I)B#8$!%9#A!G;#*&.#'6)#5)$',*$B
g4 b$*8#'6)#$,86'#).8)#!+#'6)#7)(!&.#(!/A!A!G#'!#/*0)#,'#*A!%'#'",()#*7#",.)#*7#'6)#+,$7' I)B#8$!%9#A!G#)*(6#!((%9B#*#7,&8-)#()--4#56)#:)$',(*-#-*B!%'#'6*'#(!&'*,&7#'6)#HI;#>*&()-;#*&.#]!$)
(!/A!A!G4 A%''!&7#!((%9,)7#'"!#()--74#56*'#-)*:)7#'"!#)/9'B#()--7#,&#'6)#A!''!/J$,86'#!+#'6)#.,*-!84#F+#'6,7#,7&='
"6*'#B!%#6*:);#%&.!#'6)#-*B!%';#$)9!7,',!&#'6)#",.8)'7;#*&.#'$B#*8*,&4
h4 `)'#'6)#8$!%9#A!G=7 title#9$!9)$'B#'!#Nci$,/*$B#I)BN;#'6)#+,$7'#-*A)-=7 text#9$!9)$'B#'!
N>!-%/&DN;#*&.#'6)#7)(!&.#-*A)-=7 text#9$!9)$'B#'!#NH$.)$DN4
j4 [,86'J(-,(0#'6)#+,$7'#(!/A!A!G#*&.#(6!!7)#_.,'#F')/7#+$!/#'6)#(!&')G'#/)&%#'!#9!9#%9 ! [)&*/)#'6)#+!$/#N`!$'b,*-!8N#*&.#(6*&8)#'6)#",&.!"#','-)#'!#N`!$'N4#`)'#'6)#&*/)7#!+#'6)#(6,-.
#$%&'($)=7#(!/A!A!G ).,'!$4 >$)*')#!&)#,')/#",'6#'6)#')G'#N !&)N4 ",.8)'7#'!#'6!7)#76!"&#,& X,8%$)#V4Rd4
k4 [,86'J(-,(0#'6)#7)(!&.#(!/A!A!G#*&.#(6!!7)#_.,'#F')/74#>$)*')#*&#NL7()&.,&8N#,')/#*&.#*
Nb)7()&.,&8N#,')/4 !"#$%&'()?(&@15!7"&/,%&>.$5=4&3!0"%/4
S4 >-,(0#'6)#8$!%9#A!G;#'6)&#(-,(0#X!$/a^*B#H%'#,&#*#l$,.4#>-,(0#'6)#8$!%9#A!G#*8*,&#*&.#(-,(0
X!$/aL.Z%7'#`,C)4 56,7#",--#9$!.%()#'6)#-*B!%'#76!"&#,& X,8%$)#V4RR#1A34 [View full size image]
F+#*#-*B!%'#.!)7&='#'%$&#!%'#@%,')#$,86'#!$#,+#B!%#/*0)#*#/,7'*0);#B!%#(*&#*-"*B7#(-,(0#_.,'aK&.!#!$
X!$/aY$)*0#^*B!%';#'6)&#$)9!7,',!&#'6)#",.8)'7#*&.#'$B#*8*,&4
E)#",--#&!"#*..#'6)#`)(!&.*$B#I)B#*&.#5)$',*$B#I)B#8$!%9#A!G)7D
R4 ]*0)#'6)#.,*-!8#",&.!"#'*--#)&!%86#+!$#'6)#)G'$*#9*$'74
V4 M!-.#.!"&#'6)#>'$-#0)B#1L-'#!&#'6)#]*(3#*&.#(-,(0#'6)#i$,/*$B#I)B#8$!%9#A!G#'!#($)*')#*#(!9B
!+#'6)#8$!%9#A!G#1*&.#,'7#(!&')&'73#!&#'!9#!+#'6)#!$,8,&*-4#b$*8#'6)#(!9B#A)-!"#'6)#!$,8,&*-
8$!%9#A!G;#"6,-)#7',--#9$)77,&8#>'$-#1!$#L-'34#[)9)*'#'6,7#9$!()77#'!#($)*')#*#'6,$.#8$!%9#A!G;
.$*88,&8#,'#A)-!"#'6)#7)(!&.#8$!%9#A!G4
d4 >6*&8)#'6),$ title#9$!9)$',)7#'!#Nc`)(!&.*$B#I)BN#*&.#Nc5)$',*$B#I)BN4
e4 >$)*')#!&)#:)$',(*-#79*()$#*&.#9-*()#,'#A)'"))&#'6)#9$,/*$B#0)B#8$!%9#A!G#*&.#'6)
7)(!&.*$B#0)B#8$!%9#A!G4
g4 L$$*&8)#'6)#",.8)'7#,&#'6)#8$,.J-,0)#9*'')$L!"&#,& X,8%$)#V4RV#1*34
!"#$%&'()'(&:1;!7"&.#/&/,%&>.$5=4&9,!20$%7 !7&1&"$!0
Of,)"#+%--#7,C)#,/*8)Q
>-,(0#_.,'a_.,'#5*A#H$.)$4#>-,(0#)*(6#(!/A!A!G#,&#'%$&#+$!/#'!9/!7'#'!#A!''!//!7';#'6)&#(-,(0#'6)
HI;#>*&()-;#*&.#]!$)#A%''!&7#!&#'6)#$,86'#7,.)4#>-,(0#_.,'a_.,'#E,.8)'7#'!#-)*:)#'*A#!$.)$#/!.)4
!"#'6*'#'6)#+!$/#6*7#A))&#.)7,8&).;#")#*$)#$)*.B#'!#/*0)#,'#+%&(',!&*-#AB#7)'',&8#%9#7!/)
7,8&*-7-!'#(!&&)(',!&74 !"#$%&'($)#*--!"7#%7#'!#)7'*A-,76#(!&&)(',!&7#A)'"))&#",.8)'7#'6*'#*$)#9*$'
!+#'6)#7*/)#+!$/4#E)#&)).#'!#)7'*A-,76#'"!#(!&&)(',!&74
>-,(0#_.,'a_.,'#`,8&*-7m`-!'7#'!#)&')$ !"#$%&'($)=7#(!&&)(',!&#/!.)4#>!&&)(',!&7#*$)#$)9$)7)&').
AB#A-%)#*$$!"7#A)'"))&#'6)#+!$/=7#",.8)'74#Y)(*%7)#") (6!7)#'6)#Nb,*-!8#",'6#Y%''!&7#[,86'N
')/9-*');#'6)#HI#*&.#>*&()-#A%''!&7#*$)#*-$)*.B#(!&&)(').#'! QDialog=7 accept()#*&. reject()
7-!'74#>!&&)(',!&7#*$)#*-7!#-,7').#,& !"#$%&'($)=7#7,8&*-m7-!'#).,'!$#",&.!"4
5!#)7'*A-,76#*#(!&&)(',!&#A)'"))&#'"!#",.8)'7;#(-,(0#'6)#7)&.)$#",.8)'#*&.#.$*8#'6)#$).#*$$!"#-,&)
'!#'6)#$)(),:)$#",.8)';#'6)&#$)-)*7)4#56,7#9!97#%9#*#.,*-!8#'6*'#*--!"7#B!%#'!#(6!!7)#'6)#7,8&*-#*&.
'6)#7-!'#'!#(!&&)('4
!"#$%&'()A(&B.77%9/!7"&/,%&>.$5=4&3!0"%/4
X,$7';#($)*')#* sortdialog.h#+,-)#",'6#'6)#+!--!",&8#(!&')&'7D
#ifndef SORTDIALOG_H
#define SORTDIALOG_H
#include <QDialog>
#include "ui_sortdialog.h"
class SortDialog : public QDialog, public Ui::SortDialog
{
Q_OBJECT
public:
SortDialog(QWidget *parent = 0);
void setColumnRange(QChar first, QChar last);
};
#endif
56)&#($)*') sortdialog.cppD
56)#(!&7'$%('!$#6,.)7#'6)#7)(!&.*$B#*&.#')$',*$B#9*$'7#!+#'6)#.,*-!84#F'#*-7!#7)'7#'6) sizeConstraint
9$!9)$'B#!+#'6)#+!$/=7#-*B!%'#'! QLayout::SetFixedSize;#/*0,&8#'6)#.,*-!8#&!&J$)7,C*A-)#AB#'6)#%7)$4 QUiLoader uiLoader;
56)#-*B!%'#'6)&#'*0)7#!:)$#'6)#$)79!&7,A,-,'B#+!$#$)7,C,&8;#*&.#$)7,C)7#'6)#.,*-!8#*%'!/*',(*--B#"6)& QFile file("sortdialog.ui");
(6,-.#",.8)'7#*$)#76!"&#!$#6,..)&;#)&7%$,&8#'6*'#'6)#.,*-!8#,7#*-"*B7#.,79-*B).#*'#,'7#!9',/*-#7,C)4 QWidget *sortDialog = uiLoader.load(&file);
if (sortDialog) {
...
56) setColumnRange()#7-!'#,&,',*-,C)7#'6)#(!&')&'7#!+#'6)#(!/A!A!G)7#A*7).#!&#'6)#7)-)(').#(!-%/&7 }
,&#'6)#79$)*.76))'4#E)#,&7)$'#*#N !&)N#,')/#,&#'6)#(!/A!A!G)7#+!$#'6)#1!9',!&*-3#7)(!&.*$B#*&.
')$',*$B#0)B74
E)#(*&#*(()77#'6)#+!$/=7#(6,-.#",.8)'7#%7,&8 QObject::findChild<T>()D
^,&)7#RS#*&.#VT#9$)7)&'#*#7%A'-)#-*B!%'#,.,!/4#56) QWidget::sizeHint()#+%&(',!&#$)'%$&7#*#",.8)'=7
N,.)*-N#7,C);#"6,(6#'6)#-*B!%'#7B7')/#'$,)7#'!#6!&!$4#56,7#)G9-*,&7#"6B#.,++)$)&'#0,&.7#!+#",.8)'7;#!$
7,/,-*$#",.8)'7#",'6#.,++)$)&'#(!&')&'7;#/*B#A)#*77,8&).#.,++)$)&'#7,C)7#AB#'6)#-*B!%'#7B7')/4#X!$
QComboBox *primaryColumnCombo =
(!/A!A!G)7;#'6,7#/)*&7#'6*'#'6)#7)(!&.*$B#*&.#')$',*$B#(!/A!A!G)7;#"6,(6#(!&'*,&#N !&)N;#)&.#%9 sortDialog->findChild<QComboBox *>("primaryColumnCombo");
-*$8)$#'6*&#'6)#9$,/*$B#(!/A!A!G;#"6,(6#(!&'*,&7#!&-B#7,&8-)J-)'')$#)&'$,)74#5!#*:!,.#'6,7 if (primaryColumnCombo) {
,&(!&7,7')&(B;#")#7)'#'6)#9$,/*$B#(!/A!A!G=7#/,&,/%/#7,C)#'!#'6) %$3+(,-)4#(!/A!A!G=7#,.)*- ...
7,C)4 }
!"#$%&'()F(&E/=4&4!7"2%G61"%&9.7/1!7%$&3!0"%/4
[View full size image]
56)#,')/#:,)"7#*$)#!9',/,C).#+!$#6*&.-,&8#-*$8)#*/!%&'7#!+#.*'*#*&.#!+')&#%7)#7($!--#A*$74#56)#7($!--
A*$#/)(6*&,7/#,7#,/9-)/)&').#,& QAbstractScrollArea;#*#A*7)#(-*77#+!$#,')/#:,)"7#*&.#!'6)$#0,&.7
!+#7($!--*A-)#",.8)'74
<'#9$!:,.)7#*#+)"#",.8)'7#'6*'#*$)#%7).#9%$)-B#+!$#.,79-*B,&8#,&+!$/*',!&4 QLabel#,7#'6)#/!7'
,/9!$'*&'#!+#'6)7);#*&.#,'#(*&#A)#%7).#+!$#76!",&8#$,(6#')G'#1%7,&8#*#7,/9-)#M5]^J-,0)#7B&'*G3#*&.
,/*8)74
!"#$%&'()H(&E/=4&5#2/!G61"%&9.7/1!7%$&3!0"%/4 !"#$%&'('*(&E/=4&0!4621;&3!0"%/4
[View full size image]
QTabWidget#*&. QToolBox#*$)#/%-',J9*8)#",.8)'74#_*(6#9*8)#,7#*#(6,-.#",.8)';#*&.#'6)#9*8)7#*$)
&%/A)$).#+$!/#T4
!"#$%&'()I(&E/=4&!/%5&J!%3&3!0"%/4
[View full size image]
!"#$%&'(')(&E/=4&!76#/&3!0"%/4
<'#9$!:,.)7#*#:)$7*',-)#/)77*8)#A!G#*&.#*&#)$$!$#.,*-!8#'6*'#$)/)/A)$7#"6,(6#/)77*8)7#,'#6*7
76!"&4#56)#9$!8$)77#!+#',/)J(!&7%/,&8#!9)$*',!&7#(*&#A)#,&.,(*').#%7,&8 QProgressDialog#!$#%7,&8
'6) QProgressBar#76!"&#)*$-,)$4 QInputDialog#,7#:)$B#(!&:)&,)&'#"6)&#*#7,&8-)#-,&)#!+#')G'#!$#*#7,&8-)
&%/A)$#,7#$)@%,$).#+$!/#'6)#%7)$4
L#-!'#!+#$)*.BJ'!J%7)#+%&(',!&*-,'B#,7#9$!:,.).#AB#'6)#A%,-'J,&#",.8)'7#*&.#(!//!&#.,*-!874#]!$)
79)(,*-,C).#$)@%,$)/)&'7#(*&#!+')&#A)#7*',7+,).#AB#7)'',&8#",.8)'#9$!9)$',)7;#!$#AB#(!&&)(',&8#7,8&*-7
'!#7-!'7#*&.#,/9-)/)&',&8#(%7'!/#A)6*:,!$#,&#'6)#7-!'74
!"#$%&'('A(&E/=4&>%%0<19K&0!12."4
[View full size image]
<'#9$!:,.)7#'6)#7'*&.*$.#7)'#!+#(!//!&#.,*-!87#'6*'#/*0)#,'#)*7B#'!#*70#'6)#%7)$#'!#7)-)('#*#(!-!$;
+!&';#!$#+,-);#!$#'!#9$,&'#*#.!(%/)&'4
!"#$%&'(''(&E/=4&9.2.$&0!12."&170&>.7/&0!12."
[View full size image]
F!/)#7,'%*',!&7;#,'#/*B#A)#.)7,$*A-)#'!#($)*')#*#(%7'!/#",.8)'#+$!/#7($*'(64#<'#/*0)7#'6,7
7'$*,86'+!$"*$.;#*&.#(%7'!/#",.8)'7#(*&#*(()77#*--#'6)#7*/)#9-*'+!$/J,&.)9)&.)&'#.$*",&8
+%&(',!&*-,'B#*7#<'=7#A%,-'J,&#",.8)'74#>%7'!/#",.8)'7#(*&#):)&#A)#,&')8$*').#",'6 !"#$%&'($)#7!
'6*'#'6)B#(*&#A)#%7).#,&#'6)#7*/)#"*B#*7#<'=7#A%,-'J,&#",.8)'74 >6*9')$#g#)G9-*,&7#6!"#'!#($)*')
(%7'!/#",.8)'74
H&#E,&.!"7#*&.#]*(#H`#\;#<'#%7)7#'6)#&*',:)#.,*-!87#$*'6)$#'6*&#,'7#!"&#(!//!&#.,*-!87#"6)&
9!77,A-)4
!"#$%&'('?(&E/=4&>!2%&170&6$!7/&0!12."4
Subclassing QMainWindow
Chapter 3. Creating Main Windows L&#*99-,(*',!&=7#/*,&#",&.!"#,7#($)*').#AB#7%A(-*77,&8 QMainWindow4#]*&B#!+#'6)#')(6&,@%)7#")#7*"
,& >6*9')$#V#+!$#($)*',&8#.,*-!87#*$)#*-7!#$)-):*&'#+!$#($)*',&8#/*,&#",&.!"7;#7,&()#A!'6 QDialog#*&.
QMainWindow#,&6)$,'#+$!/ QWidget4
• 6073.-%%&('" 8-&(9&(,+:
• ;)$-!&('"8$(0%"-(,"<++.7-)%
]*,&#",&.!"7#(*&#A)#($)*').#%7,&8 !"#$%&'($);#A%'#,&#'6,7#(6*9')$#") ",--#.!#):)$B'6,&8#,&#(!.)
• 6$!!&('"=2"!>$"6!-!0%"?-)
'!#.)/!&7'$*')#6!"#,'=7#.!&)4#F+#B!%#9$)+)$#'6)#/!$)#:,7%*-#*99$!*(6;#7))#'6)#N>$)*',&8#]*,&
• @/2.$/$(!&('"!>$"A&.$"8$(0
E,&.!"7#,& !"#$%&'($)N#(6*9')$#,& !"#$%&'($)=7#!&-,&)#/*&%*-4
• =%&('"#&-.+'%
• 6!+)&('"6$!!&('%
• 80.!&2.$"#+30/$(!% 56)#7!%$()#(!.)#+!$#'6)#`9$)*.76))'#*99-,(*',!&=7#/*,&#",&.!"#,7#79$)*. *($!77 mainwindow.h#*&.
• 62.-%>"63)$$(% mainwindow.cpp4#^)'=7#7'*$'#",'6#'6)#6)*.)$#+,-)D
56,7#(6*9')$#",--#')*(6#B!%#6!"#'!#($)*')#/*,&#",&.!"7#%7,&8#<'4#YB#'6)#)&.;#B!%#",--#A)#*A-)#'!
#ifndef MAINWINDOW_H
A%,-.#*&#*99-,(*',!&=7#)&',$)#%7)$#,&')$+*();#(!/9-)')#",'6#/)&%7;#'!!-A*$7;#7'*'%7#A*$;#*&.#*7#/*&B
#define MAINWINDOW_H
.,*-!87#*7#'6)#*99-,(*',!&#$)@%,$)74 #include <QMainWindow>
class QAction;
L&#*99-,(*',!&=7#/*,&#",&.!"#9$!:,.)7#'6)#+$*/)"!$0#%9!&#"6,(6#'6)#*99-,(*',!&=7#%7)$#,&')$+*()#,7 class QLabel;
A%,-'4#56)#/*,&#",&.!"#+!$#'6)#`9$)*.76))'#*99-,(*',!L!"&#,& X,8%$)#d4R#",--#+!$/#'6)#A*7,7#!+ class FindDialog;
'6,7#(6*9')$4#56)#`9$)*.76))'#*99-,(*',!&#/*0)7#%7)#!+#'6)#X,&.;#l!J'!J>)--;#*&.#`!$'#.,*-!87#'6*' class Spreadsheet;
")#($)*').#,& >6*9')$#V4 class MainWindow : public QMainWindow
{
Q_OBJECT
!"#$%&?()(&-6$%104,%%/&1662!91/!.7 public:
[View full size image]
MainWindow();
protected:
void closeEvent(QCloseEvent *event);
private slots:
void newFile();
void open();
bool save();
bool saveAs();
void find();
void goToCell();
void sort();
void about();
Y)6,&.#/!7'#lKF#*99-,(*',!&7#-,)7#*#A!.B#!+#(!.)#'6*'#9$!:,.)7#'6)#%&.)$-B,&8#+%&(',!&*-,'B+!$
)G*/9-);#(!.)#'!#$)*.#*&.#"$,')#+,-)7#!$#'!#9$!()77#'6)#.*'*#9$)7)&').#,&#'6)#%7)$#,&')$+*()4#F& void openRecentFile();
>6*9')$#e;#")#",--#7))#6!"#'!#,/9-)/)&'#7%(6#+%&(',!&*-,'B;#*8*,&#%7,&8#'6)#`9$)*.76))'#*99-,(*',!& void updateStatusBar();
*7#!%$#)G*/9-)4 void spreadsheetModified();
private:
void createActions();
void createMenus(); createActions();
void createContextMenu(); createMenus();
void createToolBars(); createContextMenu();
void createStatusBar(); createToolBars();
void readSettings(); createStatusBar();
void writeSettings(); readSettings();
bool okToContinue(); findDialog = 0;
bool loadFile(const QString &fileName); setWindowIcon(QIcon(":/images/icon.png"));
bool saveFile(const QString &fileName); setCurrentFile("");
void setCurrentFile(const QString &fileName); }
void updateRecentFileActions();
QString strippedName(const QString &fullFileName);
F&#'6)#(!&7'$%('!$;#")#A)8,&#AB#($)*',&8#* Spreadsheet#",.8)'#*&.#7)'',&8#,'#'!#A)#'6)#/*,&#",&.!"=7
()&'$*-#",.8)'4#56)#()&'$*-#",.8)'#!((%9,)7#'6)#/,..-)#!+#'6)#/*,&#",&.!"#17)) X,8%$)#d4V34#56)
56)#/*,&#",&.!"#&)).7#7!/)#/!$)#9$,:*')#7-!'7#*&.#7):)$*-#9$,:*')#+%&(',!&7#'!#7%99!$'#'6)#%7)$ Spreadsheet#(-*77#,7#* QTableWidget#7%A(-*77#",'6#7!/)#79$)*.76))'#(*9*A,-,',)7;#7%(6#*7#7%99!$'#+!$
,&')$+*()4 79$)*.76))'#+!$/%-*74 E)#",--#,/9-)/)&'#,'#,& >6*9')$#e4
Spreadsheet *spreadsheet;
!"#$%&?('( QMainWindow=4&1$%14
FindDialog *findDialog;
QLabel *locationLabel;
QLabel *formulaLabel;
QStringList recentFiles;
QString curFile;
enum { MaxRecentFiles = 5 };
QAction *recentFileActions[MaxRecentFiles];
QAction *separatorAction;
QMenu *fileMenu;
QMenu *editMenu;
...
QToolBar *fileToolBar;
QToolBar *editToolBar;
QAction *newAction;
QAction *openAction;
...
QAction *aboutQtAction;
};
#endif E)#(*--#'6)#9$,:*')#+%&(',!&7 createActions(); createMenus(); createContext-Menu();
createToolBars();#*&. createStatusBar()#'!#7)'#%9#'6)#$)7'#!+#'6)#/*,&#",&.!"4#E)#*-7!#(*--#'6)
9$,:*')#+%&(',!& readSettings()#'!#$)*.#'6)#*99-,(*',!&=7#7'!$).#7)'',&874
F&#*..,',!&#'!#,'7#9$,:*')#7-!'7#*&.#9$,:*')#+%&(',!&7; MainWindow#*-7!#6*7#-!'7#!+#9$,:*')#:*$,*A-)74#L--
!+#'6)7)#",--#A)#)G9-*,&).#*7#") %7)#'6)/4 E)#,&,',*-,C)#'6) findDialog#9!,&')$#'!#A)#*#&%--#9!,&')$2#'6)#+,$7'#',/) MainWindow::find()#,7#(*--).;
")#",--#($)*')#'6) FindDialog#!AZ)('4
E)#",--#&!"#$):,)"#'6)#,/9-)/)&'*',!&D
L'#'6)#)&.#!+#'6)#(!&7'$%('!$;#")#7)'#'6)#",&.!"=7#,(!&#'! icon.png;#*#i l#+,-)4#<' 7%99!$'7#/*&B
,/*8)#+!$/*'7;#,&(-%.,&8#Y]i;#lFX;OqQ#ri_l;#i l;#i ];#\Y];#*&.#\i]4#>*--,&8
#include <QtGui> QWidget::setWindowIcon()#7)'7#'6)#,(!L!"&#,&#'6)#'!9J-)+'#(!$&)$#!+#'6)#",&.!"4#K&+!$'%&*')-B;
#include "finddialog.h" '6)$)#,7#&!#9-*'+!$/J,&.)9)&.)&'#"*B#!+#7)'',&8#'6)#*99-,(*',!&#,(!&#'6*'#*99)*$7#!&#'6)#.)70'!94
#include "gotocelldialog.h" i-*'+!$/J79)(,+,(#9$!().%$)7#*$)#)G9-*,&).#*' 6''9Dmm.!(4'$!--')(64(!/me4Rm*99,(!&46'/-4
#include "mainwindow.h"
#include "sortdialog.h" [*]
GIF support is disabled in Qt by default because the decompression algorithm used by GIF files was patented in some countries
#include "spreadsheet.h" where software patents are recognized. We believe that this patent has now expired worldwide. To enable GIF support in Qt, pass
the -qt-gif command-line option to the configure script or set the appropriate option in the Qt installer.
56)#H9)&;#`*:);#*&.#`*:)#L7#*(',!&7#*$)#:)$B#7,/,-*$#'!#'6)# )"#*(',!&;#7!#")#",--#70,9#.,$)('-B#'!
<!DOCTYPE RCC><RCC version="1.0"> '6)#N$)()&'-B#!9)&).#+,-)7N 9*$'#!+#'6)#X,-)#/)&%D
<qresource>
<file>images/icon.png</file>
... ...
<file>images/gotocell.png</file> for (int i = 0; i < MaxRecentFiles; ++i) {
</qresource> recentFileActions[i] = new QAction(this);
</RCC> recentFileActions[i]->setVisible(false);
connect(recentFileActions[i], SIGNAL(triggered()),
this, SLOT(openRecentFile()));
}
[)7!%$()#+,-)7#*$)#(!/9,-).#,&'!#'6)#*99-,(*',!&=7#)G)(%'*A-);#7!#'6)B#(*&='#8)'#-!7'4#E6)&#")#$)+)$
'!#$)7!%$()7;#")#%7)#'6)#9*'6#9$)+,G :/#1(!-!-*763;#"6,(6#,7#"6B#'6)#,(!&#,7#79)(,+,).#*7
:/images/icon.png4#[)7!%$()7#(*&#A)#*&B#0,&.#!+#+,-)#1&!'#Z%7'#,/*8)73;#*&.#")#(*&#%7)#'6)/#,&
E)#9!9%-*')#'6) recentFileActions#*$$*B#",'6#*(',!&74#_*(6#*(',!&#,7#6,..)&#*&.#(!&&)(').#'!#'6)
/!7'#9-*()7#"6)$)#<'#)G9)('7#*#+,-)#&*/)4 56)B#*$)#(!:)$).#,&#/!$)#.)'*,-#,& >6*9')$#RV4
openRecentFile()#7-!'4#^*')$#!&;#")#",--#7))#6!"#'6)#$)()&'#+,-)#*(',!&7#*$)#/*.)#:,7,A-)#*&.#%7).4
]!7'#/!.)$&#lKF#*99-,(*',!&7#9$!:,.)#/)&%7;#(!&')G'#/)&%7;#*&.#'!!-A*$74#56)#/)&%7#)&*A-)
%7)$7#'!#)G9-!$)#'6)#*99-,(*',!&#*&.#-)*$!"#'!#.!#&)"#'6,&87;#"6,-)#'6)#(!&')G'#/)&%7#*&. ...
'!!-A*$7#9$!:,.)#@%,(0#*(()77#'!#+$)@%)&'-B#%7).#+%&(',!&*-,'B4 selectAllAction = new QAction(tr("&All"), this);
selectAllAction->setShortcut(tr("Ctrl+A"));
selectAllAction->setStatusTip(tr("Select all the cells in the "
!"#$%&?(?(&+,%&-6$%104,%%/&1662!91/!.7=4&5%7#4 "spreadsheet"));
connect(selectAllAction, SIGNAL(triggered()),
[View full size image]
spreadsheet, SLOT(selectAll()));
^)'=7#70,9#+%$'6)$#'!#'6)#`6!"#l$,.#*(',!&#,&#'6)#H9',!&7#/)&%D
...
<'#7,/9-,+,)7#'6)#9$!8$*//,&8#!+#/)&%7#*&.#'!!-A*$7#'6$!%86#,'7#*(',!&#(!&()9'4#L& -3!&+(#,7#*& showGridAction = new QAction(tr("&Show Grid"), this);
,')/#'6*'#(*&#A)#*..).#'!#*&B#&%/A)$#!+#/)&%7#*&.#'!!-A*$74 >$)*',&8#/)&%7#*&.#'!!-A*$7#,&#<' showGridAction->setCheckable(true);
,&:!-:)7#'6)7)#7')97D showGridAction->setChecked(spreadsheet->showGrid());
showGridAction->setStatusTip(tr("Show or hide the spreadsheet's "
"grid"));
• >$)*')#*&.#7)'#%9#'6)#*(',!&74 connect(showGridAction, SIGNAL(toggled(bool)),
• >$)*') /)&%7#*&.#9!9%-*')#'6)/#",'6#'6)#*(',!&74 spreadsheet, SLOT(setShowGrid(bool)));
• >$)*')#'!!-A*$7#*&.#9!9%-*')#'6)/#",'6#'6)#*(',!&74
!"#")#($)*')#'6)#_.,'#/)&%;#*..,&8#*(',!&7#",'6 QMenu::addAction()#*7#")#.,.#+!$#'6)#X,-)#/)&%;
*&.#*..,&8#'6)#7%A/)&%#",'6 QMenu::addMenu()#*'#'6)#9!7,',!&#"6)$)#")#"*&'#,'#'!#*99)*$4#56)
7%A/)&%;#-,0)#'6)#/)&%#,'#A)-!&87#'!;#,7#* QMenu4
toolsMenu = menuBar()->addMenu(tr("&Tools"));
toolsMenu->addAction(recalculateAction);
toolsMenu->addAction(sortAction);
optionsMenu = menuBar()->addMenu(tr("&Options"));
optionsMenu->addAction(showGridAction);
optionsMenu->addAction(autoRecalcAction);
menuBar()->addSeparator();
helpMenu = menuBar()->addMenu(tr("&Help"));
helpMenu->addAction(aboutAction);
helpMenu->addAction(aboutQtAction);
}
!"#'6*'#")#6*:)#($)*').#'6)#*(',!&7;#")#(*&#/!:)#!&#'!#A%,-.,&8#*#/)&%#7B7')/#(!&'*,&,&8#'6)/D
E)#($)*')#'6)#5!!-7;#H9',!&7;#*&.#M)-9#/)&%7#,&#*#7,/,-*$#+*76,!&4#E)#,&7)$'#*#7)9*$*'!$#A)'"))&
'6)#H9',!&7#*&.#M)-9#/)&%4#F&#]!',+#*&.#>b_#7'B-)7;#'6)#7)9*$*'!$#9%76)7#'6)#M)-9#/)&%#'!#'6)
$,86'2#,&#!'6)$#7'B-)7;#'6)#7)9*$*'!$#,7#,8&!$).4
void MainWindow::createMenus()
{
fileMenu = menuBar()->addMenu(tr("&File")); !"#$%&?(C(&M%7#&<1$&!7&M./!>&170&N!70.34&4/;2%4
fileMenu->addAction(newAction);
fileMenu->addAction(openAction);
fileMenu->addAction(saveAction);
fileMenu->addAction(saveAsAction);
separatorAction = fileMenu->addSeparator();
for (int i = 0; i < MaxRecentFiles; ++i)
fileMenu->addAction(recentFileActions[i]);
fileMenu->addSeparator();
fileMenu->addAction(exitAction);
void MainWindow::createContextMenu()
{
spreadsheet->addAction(cutAction);
F&#<';#/)&%7#*$)#,&7'*&()7#!+ QMenu4#56) addMenu()#+%&(',!&#($)*')7#* QMenu#",.8)'#",'6#'6) spreadsheet->addAction(copyAction);
79)(,+,).#')G'#*&.#*..7#,'#'!#'6)#/)&%#A*$4#56) QMainWindow::menuBar()#+%&(',!&#$)'%$&7#*#9!,&')$#'! spreadsheet->addAction(pasteAction);
* QMenuBar4#56)#/)&%#A*$#,7#($)*').#'6)#+,$7'#',/) menuBar()#,7#(*--).4 spreadsheet->setContextMenuPolicy(Qt::ActionsContextMenu);
}
void MainWindow::createStatusBar()
{
L&B#<'#",.8)'#(**:)#*#-,7'#!+ QAction7#*77!(,*').#",'6#,'4#5!#9$!:,.)#*#(!&')G'#/)&%#+!$#'6) locationLabel = new QLabel(" W999 ");
*99-,(*',!&;#")#*..#'6)#.)7,$).#*(',!&7#'!#'6) Spreadsheet#",.8)'#*&.#7)'#'6*'#",.8)'=7#(!&')G' locationLabel->setAlignment(Qt::AlignHCenter);
/)&%#9!-,(B#'!#76!"#*#(!&')G'#/)&%#",'6#'6)7)#*(',!&74#>!&')G'#/)&%7#*$)#,&:!0).#AB#$,86'J locationLabel->setMinimumSize(locationLabel->sizeHint());
(-,(0,&8#*#",.8)'#!$#AB#9$)77,&8#*#9-*'+!$/J79)(,+,(#0)B4 formulaLabel = new QLabel;
formulaLabel->setIndent(3);
!"#$%&?(D(&+,%&-6$%104,%%/&1662!91/!.7=4&9.7/%8/&5%7# statusBar()->addWidget(locationLabel);
statusBar()->addWidget(formulaLabel, 1);
connect(spreadsheet, SIGNAL(currentCellChanged(int, int, int, int)),
this, SLOT(updateStatusBar()));
connect(spreadsheet, SIGNAL(modified()),
this, SLOT(spreadsheetModified()));
updateStatusBar();
}
56) QMainWindow::statusBar()#+%&(',!&#$)'%$&7#*#9!,&')$#'!#'6)#7'*'%7#A*$4#156)#7'*'%7#A*$#,7#($)*').
L#/!$)#7!96,7',(*').#"*B#!+#9$!:,.,&8#(!&')G'#/)&%7#,7#'!#$),/9-)/)&'#'6) '6)#+,$7' ',/) statusBar()#,7#(*--).43#56)#7'*'%7#,&.,(*'!$7#*$)#7,/9-B QLabel7#"6!7)#')G'#")#(6*&8)
QWidget::contextMenuEvent()#+%&(',!&;#($)*')#* QMenu#",.8)';#9!9%-*')#,'#",'6#'6)#.)7,$).#*(',!&7; "6)&):)$#&)()77*$B4#E)#6*:)#*..).#*&#,&.)&'#'!#'6) formulaLabel#7!#'6*'#'6)#')G'#76!"&#,&#,'#,7
*&.#(*-- exec()#!&#,'4 !++7)'#7-,86'-B#+$!/#'6)#-)+'#).8)4#E6)&#'6) QLabel7#*$)#*..).#'!#'6)#7'*'%7#A*$;#'6)B#*$)
*%'!/*',(*--B#$)9*$)&').#'!#/*0)#'6)/#(6,-.$)&#!+#'6)#7'*'%7#A*$4
>$)*',&8#'!!-A*$7#,7#:)$B#7,/,-*$#'!#($)*',&8#/)&%74#E)#($)*')#*#X,-)#'!!-A*$#*&.#*&#_.,'#'!!-A*$4#r%7'
-,0)#*#/)&%;#*#'!!-A*$#(**:)#7)9*$*'!$74
tr("%1[*] - %2").arg(shownName)
.arg(tr("Spreadsheet"))
void MainWindow::updateRecentFileActions()
void MainWindow::openRecentFile()
{
{
QMutableStringListIterator i(recentFiles);
if (okToContinue()) {
while (i.hasNext()) {
QAction *action = qobject_cast<QAction *>(sender());
if (!QFile::exists(i.next()))
if (action)
i.remove();
loadFile(action->data().toString());
}
}
for (int j = 0; j < MaxRecentFiles; ++j) {
}
if (j < recentFiles.count()) {
QString text = tr("&%1 %2")
.arg(j + 1)
.arg(strippedName(recentFiles[j])); O1%&('1%(#*%/("1!!*%*(-(/%"%&'(0.3%,('1% openRecentFile()(*3!'(.*("-33% 4(51% okToContinue()(0#&"'.!&
recentFileActions[j]->setText(text); .*(#*% (.&("-*%('1%/%(-/%(-&<(#&*-8% ("1-&;%*,(-& (6/!8. .&;('1%(#*%/( . (&!'("-&"%3,(9%(0.& (!#'
recentFileActions[j]->setData(recentFiles[j]); 91."1(6-/'."#3-/(-"'.!&(.&8!>% ('1%(*3!'(#*.&; QObject::sender()4
recentFileActions[j]->setVisible(true);
} else {
recentFileActions[j]->setVisible(false); 51% qobject_cast<T>()(0#&"'.!&(6%/0!/$*(-( <&-$."("-*'(:-*% (!&('1%($%'-K.&0!/$-'.!&(;%&%/-'%
} :< moc,(U'7*($%'-K!:a%"'("!$6.3%/4(='(/%'#/&*(-(6!.&'%/(!0('1%(/%[#%*'% QObject(*#:"3-**,(!/(R(.0('1%
} !:a%"'("-&&!'(:%("-*'('!('1-'('<6%4(b&3.>%('1%(N'-& -/ (2^^ dynamic_cast<T>(),(U'7*
qobject_cast<T>()(9!/>*("!//%"'3<(-"/!**( <&-$."(3.:/-/<(:!#& -/.%*4(=&(!#/(%?-$63%,(9%(#*% -/%(6!**.:3%E
qobject_cast<T>()('!("-*'(- QObject(6!.&'%/('!(- QAction(6!.&'%/4(=0('1%("-*'(.*(*#""%**0#3(Q.'(*1!#3
:%+,(9%("-33 loadFile()(9.'1('1%(0#33(0.3%(&-$%('1-'(9%(%?'/-"'(0/!$('1%(-"'.!&7*( -'-4 • 51.*(.*('1%(0./*'('.$%('1%(#*%/(1-*(.&8!>% ('1%(@.& ( .-3!;4
• 51%(@.& ( .-3!;(9-*(.&8!>% (:%0!/%,(:#'('1%(#*%/("3!*% (.'4
=&". %&'-33<,(*.&"%(9%(>&!9('1-'('1%(*%& %/(.*(- QAction,('1%(6/!;/-$(9!#3 (*'.33(9!/>(.0(9%(#*% • 51%(@.& ( .-3!;(9-*(.&8!>% (:%0!/%(-& (.*(*'.33(8.*.:3%4
static_cast<T>()(!/(-('/- .'.!&-3(2K*'<3%("-*'(.&*'%- 4(c%0%/('!('1%(S5<6%(2!&8%/*.!&*S(*%"'.!&(!0
I66%& .?(T(0!/(-&(!8%/8.%9(!0('1%( .00%/%&'(2^^("-*'*4 =0('1%(@.& ( .-3!;( !%*&7'(-3/%- <(%?.*',(9%("/%-'%(.'(-& ("!&&%"'(.'* findNext()(-& findPrevious()
*.;&-3*('!('1%("!//%*6!& .&; Spreadsheet(*3!'*4(O%("!#3 (-3*!(1-8%("/%-'% ('1%( .-3!;(.&('1%
MainWindow("!&*'/#"'!/,(:#'( %3-<.&;(.'*("/%-'.!&($->%*(*'-/'#6(0-*'%/4(I3*!,(.0('1%( .-3!;(.*(&%8%/
#*% ,(.'(.*(&%8%/("/%-'% ,(*-8.&;(:!'1('.$%(-& ($%$!/<4
91."1(.*('1%(6/!;/-$$.&;(%[#.8-3%&'(!0(3!!>.&;(:!'1(9-<*(:%0!/%("/!**.&;(-(!&%K9-<(*'/%%'4
void MainWindow::find()
{
if (!findDialog) {
findDialog = new FindDialog(this);
connect(findDialog, SIGNAL (findNext(const QString &,
Qt::CaseSensitivity)), I( .-3!;(.*($! %3%**(.0(.'7*(.&8!>% (#*.&; show()(Q#&3%**(9%("-33 setModal()(:%0!/%1-& ('!($->%(.'
spreadsheet, SLOT (findNext(const QString &, $! -3+P(.'(.*($! -3(.0(.'7*(.&8!>% (#*.&; exec()4
Qt::CaseSensitivity)));
connect(findDialog, SIGNAL(findPrevious(const QString &,
Qt::CaseSensitivity)), void MainWindow::goToCell()
spreadsheet, SLOT(findPrevious(const QString &, {
Qt::CaseSensitivity))); GoToCellDialog dialog(this);
} if (dialog.exec()) {
findDialog->show(); QString str = dialog.lineEdit->text().toUpper();
findDialog->activateWindow(); spreadsheet->setCurrentCell(str.mid(1).toInt() - 1,
} str[0].unicode() - 'A');
}
}
51%(@.& ( .-3!;(.*(-(9.& !9('1-'(%&-:3%*('1%(#*%/('!(*%-/"1(0!/('%?'(.&('1%(*6/%- *1%%'4(51% find()
*3!'(.*("-33% (91%&('1%(#*%/("3.">*(D .'F@.& ('!(6!6(#6('1%(@.& ( .-3!;4 I'('1-'(6!.&',(*%8%/-3(*"%&-/.!*
51% QDialog::exec()(0#&"'.!&(/%'#/&*(-('/#%(8-3#%(QQDialog::Accepted+(.0('1%( .-3!;(.*(-""%6'% ,(-&
-(0-3*%(8-3#%(QQDialog::Rejected+ !'1%/9.*%4(c%"-33('1-'(91%&(9%("/%-'% ('1%(e!K'!K2%33( .-3!;(#*.&; SpreadsheetCompare compare;
()*+$&,- $.(.& 21-6'%/(M,(9%("!&&%"'% (Gf('! accept()(-& (2-&"%3('! reject()4(=0('1%(#*%/("1!!*%* compare.keys[0] =
Gf,(9%(*%'('1%("#//%&'("%33('!('1%(8-3#%(.&('1%(3.&%(% .'!/4 dialog.primaryColumnCombo->currentIndex();
compare.keys[1] =
dialog.secondaryColumnCombo->currentIndex() - 1;
51% QTableWidget::setCurrentCell()(0#&"'.!&(%?6%"'*('9!(-/;#$%&'*E(-(/!9(.& %?(-& (-("!3#$& compare.keys[2] =
.& %?4(=&('1%(N6/%- *1%%'(-663."-'.!&,("%33(IL(.*("%33(QR,(R+(-& ("%33(TMg(.*("%33(QMh,(L+4(5!(!:'-.&('1% dialog.tertiaryColumnCombo->currentIndex() - 1;
/!9(.& %?(0/!$('1% QString(/%'#/&% (:< QLineEdit::text(),(9%(%?'/-"'('1%(/!9(&#$:%/(#*.&; compare.ascending[0] =
QString::mid()(Q91."1(/%'#/&*(-(*#:*'/.&;(0/!$('1%(*'-/'(6!*.'.!&('!('1%(%& (!0('1%(*'/.&;+,("!&8%/'(.' (dialog.primaryOrderCombo->currentIndex() == 0);
'!(-& int(#*.&; QString::toInt(),(-& (*#:'/-"'(L4(@!/('1%("!3#$&(&#$:%/,(9%(*#:'/-"'('1%(&#$%/." compare.ascending[1] =
8-3#%(!0(7I7(0/!$('1%(&#$%/."(8-3#%(!0('1%(*'/.&;7*(#66%/"-*% (0./*'("1-/-"'%/4(O%(>&!9('1-'('1% (dialog.secondaryOrderCombo->currentIndex() == 0);
*'/.&;(9.33(1-8%('1%("!//%"'(0!/$-'(:%"-#*%('1% QRegExpValidator(9%("/%-'% (0!/('1%( .-3!;(!&3< compare.ascending[2] =
(dialog.tertiaryOrderCombo->currentIndex() == 0);
-33!9*('1%(Gf(:#''!&('!(:%(%&-:3% (.0(9%(1-8%(-(3%''%/(0!33!9% (:<(#6('!('1/%%( .;.'*4
spreadsheet->sort(compare);
}
51% goToCell()(0#&"'.!&( .00%/*(0/!$(-33('1%("! %(*%%&(*!(0-/(.&('1-'(.'("/%-'%*(-(9. ;%'(Q- }
GoToCellDialog+(-*(-(8-/.-:3%(!&('1%(*'-">4(I'('1%("!*'(!0(!&%(%?'/-(3.&%,(9%("!#3 (a#*'(-*(%-*.3<(1-8%
#*% new(-& deleteE
51%("! %(.& sort()(0!33!9*(-(*.$.3-/(6-''%/&('!('1-'(#*% (0!/ goToCell()E
void MainWindow::goToCell()
{ • O%("/%-'%('1%( .-3!;(!&('1%(*'-">(-& (.&.'.-3.d%(.'4
GoToCellDialog *dialog = new GoToCellDialog(this); • O%(6!6(#6('1%( .-3!;(#*.&; exec()4
if (dialog->exec()) { • =0('1%(#*%/("3.">*(Gf,(9%(%?'/-"'('1%(8-3#%*(%&'%/% (:<('1%(#*%/(0/!$('1%( .-3!;7*(9. ;%'*(-&
QString str = dialog->lineEdit->text().toUpper(); $->%(#*%(!0('1%$4
spreadsheet->setCurrentCell(str.mid(1).toInt() - 1,
str[0].unicode() - 'A'); 51% setColumnRange()("-33(*%'*('1%("!3#$&*(-8-.3-:3%(0!/(*!/'.&;('!('1%("!3#$&*('1-'(-/%(*%3%"'% 4
} @!/(%?-$63%,(#*.&;('1%(*%3%"'.!&(*1!9&(.& @.;#/%(A4L`, range.leftColumn()(9!#3 (<.%3 (R,(;.8.&;(7I7
delete dialog;
^(R(i(7I7,(-& range.rightColumn()(9!#3 (<.%3 (M,(;.8.&;(7I7(^(M(i(7274
}
I($!/%(/!:#*'(-66/!-"1(.*('!($->%('1% SortDialog("3-**(*$-/'%/(:<(1-8.&;(.'("/%-'%(-
SpreadsheetCompare(!:a%"'(.'*%30,(91."1("-&('1%&(:%(-""%**% (:<(.'*("-33%/4(51.*(*.$63.0.%*
MainWindow::sort()(*.;&.0."-&'3<E
void MainWindow::sort()
{
SortDialog dialog(this);
QTableWidgetSelectionRange range = spreadsheet->selectedRange();
dialog.setColumnRange('A' + range.leftColumn(),
'A' + range.rightColumn());
if (dialog.exec())
void MainWindow::sort() spreadsheet->performSort(dialog.comparisonObject());
{ }
SortDialog dialog(this);
QTableWidgetSelectionRange range = spreadsheet->selectedRange();
dialog.setColumnRange('A' + range.leftColumn(), 51.*(-66/!-"1(3%- *('!(3!!*%3<("!#63% ("!$6!&%&'*(-& (.*(-3$!*'(-39-<*('1%(/.;1'("1!."%(0!/( .-3!;*
'A' + range.rightColumn());
if (dialog.exec()) {
'1-'(9.33(:%("-33% (0/!$($!/%('1-&(!&%(63-"%4
void MainWindow::sort()
{
SortDialog dialog(this);
dialog.setSpreadsheet(spreadsheet);
dialog.exec();
}
settings.beginGroup("findDialog");
settings.setValue("matchCase", caseCheckBox->isChecked());
settings.setValue("searchBackward", backwardCheckBox->isChecked());
settings.endGroup();
51% 1'%2$("-&(:%(-& int,(- bool,(- double,(- QString,(- QStringList,(!/(-&<(!'1%/('<6%(*#66!/'% (:< 51.* main()(0#&"'.!&(.*(-(3.''3%(:.'( .00%/%&'(0/!$('1!*%(9%(1-8%(9/.''%&(*!(0-/E(O%(1-8%("/%-'% ('1%
QVariant,(.&"3# .&;(/%;.*'%/% ("#*'!$('<6%*4 MainWindow(.&*'-&"%(-*(-(8-/.-:3%(!&('1%(*'-">(.&*'%- (!0(#*.&; new4(51% MainWindow(.&*'-&"%(.*('1%&
-#'!$-'."-33<( %*'/!<% (91%&('1%(0#&"'.!&('%/$.&-'%*4
=&('1%(!/.;.&-3(8%/*.!&(!0('1%(@.3%($%&#,('1%/%(9-*(&!(23!*%(!6'.!&(:%"-#*%('1-'(9!#3 (1-8%(:%%&
'1%(*-$%(-*(D?.'4
51% readSettings()(0#&"'.!&(3!- *('1%(*%''.&;*('1-'(9%/%(*-8% (:< writeSettings()4(51%(*%"!&
-/;#$%&'('!('1% value()(0#&"'.!&(*6%".0.%*(-( %0-#3'(8-3#%,(.&("-*%('1%/%(-/%(&!(*%''.&;*(-8-.3-:3%4
51%( %0-#3'(8-3#%*(-/%(#*% ('1%(0./*'('.$%('1%(-663."-'.!&(.*(/#&4(N.&"%(&!(*%"!& (-/;#$%&'(.*(;.8%&
!"#$%&'(7K(&B5%&0%.& !<%&=%0#
0!/('1%(/%"%&'(0.3%*(3.*',(.'(9.33(:%(*%'('!(-&(%$6'<(3.*'(!&('1%(0./*'(/#&4
qApp, SLOT(closeAllWindows()));
...
}
L4 O2%&/&21/0?/$?&P1&.!?"%1(
M4 O2%&/&4#21,=&.!?"%1(
`4 O2%&/&2><!11%$(
j4 O2%&/0&9+M&.,$R2>/4%(
private:
enum { MagicNumber = 0x7F51C883, RowCount = 999, ColumnCount = 26 };
Cell *cell(int row, int column) const;
QString text(int row, int column) const;
QString formula(int row, int column) const;
void setFormula(int row, int column, const QString &formula);
bool autoRecalc;
};
51%(-''/.:#'%*(!0(- QTableWidget("%33,(*#"1(-*(.'*('%?'(-& (.'*(-3.;&$%&',(-/%(*'!/% (.&(-
QTableWidgetItem4(b&3.>% QTableWidget, QTableWidgetItem(.*&7'(-(9. ;%'("3-**P(.'(.*(-(6#/%( -'-("3-**4
51% Cell("3-**(.&1%/.'* QTableWidgetItem(-& (.*(%?63-.&% (91%&(.'*(.$63%$%&'-'.!&(.*(*1!9&(.&('1.*
=&('1%("3-**7*(6/.8-'%(*%"'.!&,(9%( %"3-/%('1/%%("!&*'-&'*,(0!#/(0#&"'.!&*,(-& (!&%(8-/.-:3%4
"1-6'%/7*(3-*'(*%"'.!&4
class SpreadsheetCompare
class Spreadsheet : public QTableWidget
{
{
public:
Q_OBJECT
bool operator()(const QStringList &row1,
public:
const QStringList &row2) const;
Spreadsheet(QWidget *parent = 0);
enum { KeyCount = 3 };
bool autoRecalculate() const { return autoRecalc; }
int keys[KeyCount];
QString currentLocation() const;
bool ascending[KeyCount];
QString currentFormula() const;
};
QTableWidgetSelectionRange selectedRange() const;
#endif
void clear();
bool readFile(const QString &fileName);
bool writeFile(const QString &fileName);
void sort(const SpreadsheetCompare &compare); !"#!"$%"&#'()"#"*%+#,(-!#-!" SpreadsheetCompare#.)$++#%"'(*(-(/*0#1"#,())#"23)$(*#-!(+#,!"*#,"
&"4(", Spreadsheet::sort()0
8/&6$))9:#,!"*#-!"#;+"&#"*-"&+#+/6"#-"2-#/*#$*#"63-9#.")):#-!" QTableWidget#,())#$;-/6$-(.$))9
.&"$-"#$ QTableWidgetItem#-/#!/)%#-!"#-"2-0#<*#/;&#+3&"$%+!""-:#,"#,$*- Cell#(-"6+#-/#="#.&"$-"%
(*+-"$%0# !(+#(+#$.!("4"%#=9#-!" setItemPrototype()#.$))#(*#-!"#./*+-&;.-/&0#<*-"&*$))9: QTableWidget 2/-$!."&34/4&4+&5/%6+
.)/*"+#-!"#(-"6#3$++"%#$+#$#3&/-/-93"#"4"&9#-(6"#$#*",#(-"6#(+#&">;(&"%0
<*#-!"#R3&"$%+!""-#$33)(.$-(/*:#"4"&9#*/*S"63-9#."))#(+#+-/&"%#(*#6"6/&9#$+#$*
?)+/#(*#-!"#./*+-&;.-/&:#,"#+"-#-!"#+")".-(/*#6/%"#-/ QAbstractItemView::ContiguousSelection#-/ (*%(4(%;$) QTableWidgetItem#/=T".-0#R-/&(*@#%$-$#$+#(-"6+#(+#$*#$33&/$.!#-!$-#(+#$)+/
$))/,#$#+(*@)"#&".-$*@;)$&#+")".-(/*0#1"#./**".-#-!"#-$=)"#,(%@"-A+ itemChanged()#+(@*$)#-/#-!" ;+"%#=9 QListWidget#$*% QTReeWidget:#,!(.!#/3"&$-"#/* QListWidgetItem+#$*%
3&(4$-" somethingChanged()#+)/-B#-!(+#"*+;&"+#-!$-#,!"*#-!"#;+"&#"%(-+#$#.")):#-!" somethingChanged() QTReeWidgetItem+0
+)/-#(+#.$))"%0#C(*$))9:#,"#.$)) clear()#-/#&"+(D"#-!"#-$=)"#$*%#-/#+"-#-!"#./);6*#!"$%(*@+0
U-A+#(-"6#.)$++"+#.$*#="#;+"%#/;-#/'#-!"#=/2#$+#%$-$#!/)%"&+0#C/&#"2$63)":#$
QTableWidgetItem#$)&"$%9#+-/&"+#$#'",#$--&(=;-"+:#(*.);%(*@#$#+-&(*@:#'/*-:#./)/&:#$*%
void Spreadsheet::clear() (./*:#$*%#$#3/(*-"&#=$.5#-/#-!" QTableWidget0# !"#(-"6+#.$*#$)+/#!/)%#%$-$#FQVariant+J:
{ (*.);%(*@#&"@(+-"&"%#.;+-/6#-93"+:#$*%#=9#+;=.)$++(*@#-!"#(-"6 .)$++#,"#.$*#3&/4(%"
setRowCount(0); $%%(-(/*$)#';*.-(/*$)(-90
setColumnCount(0);
setRowCount(RowCount); V-!"&#-//)5(-+#3&/4(%"#$ void#3/(*-"&#(*#-!"(&#(-"6#.)$++"+#-/#+-/&"#.;+-/6#%$-$0#<*#U-:
setColumnCount(ColumnCount);
-!"#6/&"#*$-;&$)#$33&/$.!#(+#-/#;+" setData()#,(-!#$ QVariant:#=;-#('#$ void#3/(*-"&#(+
for (int i = 0; i < ColumnCount; ++i) {
QTableWidgetItem *item = new QTableWidgetItem; &">;(&"%:#(-#.$*#="#-&(4($))9#$.!("4"%#=9#+;=.)$++(*@#$*#(-"6#.)$++#$*%#$%%(*@#$ void
item->setText(QString(QChar('A' + i))); 3/(*-""6="$&($=)"0
setHorizontalHeaderItem(i, item);
} C//&"#.!$))"*@(*@#%$-$#!$*%)(*@#&">;(&"6"*-+:#+;.!#$+#)$&@"#%$-$#+"-+:#./63)"2#%$-$
setCurrentCell(0, 0); (-"6+:#%$-$=$+"#(*-"@&$-(/*:#$*%#6;)-(3)"#%$-$#4(",+:#U-#3&/4(%"+#$#+"-#/'#6/%")W4(",
} .)$++"+#-!$-#+"3$&$-"#-!"#%$-$#'&/6#-!"((+;$)#&"3&"+"*-$-(/*0# !"+"#$&"#./4"&"%#(*
Q!$3-"&#OE0
void Spreadsheet::somethingChanged()
!" formula()#';*.-(/*#&"-;&*+#-!"#."))A+#'/&6;)$0#<*#6$*9#.$+"+:#-!"#'/&6;)$#$*%#-!"#-"2-#$&"#-!" {
+$6"B#'/&#"2$63)":#-!"#'/&6;)$#KX"))/K#"4$);$-"+#-/#-!"#+-&(*@#KX"))/K:#+/#('#-!"#;+"&#-93"+#KX"))/K if (autoRecalc)
(*-/#$#."))#$*%#3&"++"+#Y*-"&:#-!$-#."))#,())#+!/,#-!"#-"2-#KX"))/K0 L;-#-!"&"#$&"#$#'",#"2."3-(/*+7 recalculate();
emit modified();
• <'#-!"#'/&6;)$#(+#$#*;6="&:#(-#(+#(*-"&3&"-"%#$+#+;.!0#C/&#"2$63)":#-!"#'/&6;)$#KO0ZEK }
"4$);$-"+#-/#-!" double#4$);"#O0Z:#,!(.!#(+#&"*%"&"%#$+#$#&(@!-S$)(@*"%#KO0ZK#(*#-!"
+3&"$%+!""-0
• <'#-!"#'/&6;)$#+-$&-+#,(-!#$#+(*@)"#>;/-":#-!"#&"+-#/'#-!"#'/&6;)$#(+#(*-"&3&"-"%#$+#-"2-0 C/& !" somethingChanged()#3&(4$-"#+)/-#&".$).;)$-"+#-!"#,!/)"#+3&"$%+!""-#('#K$;-/S&".$).;)$-"K#(+
"2$63)":#-!"#'/&6;)$ K#AOG[PZK#"4$);$-"+#-/#-!"#+-&(*@#KOG[PZK0 "*$=)"%0 <-#$)+/#"6(-+#-!" modified()#+(@*$)0
• <'#-!"#'/&6;)$#+-$&-+#,(-!#$*#">;$)+#+(@*#FA\AJ:#-!"#'/&6;)$#(+#(*-"&3&"-"%#$+#$*#$&(-!6"-(.
'/&6;)$0#C/&#"2$63)":#('#."))#?O#./*-$(*+#KOGK#$*%#."))#?G#./*-$(*+#KHK:#-!"#'/&6;)$#K\?O]?GK
"4$);$-"+#-/#O^0 Loading and Saving
!"#-$+5 /'#./*4"&-(*@#$#'/&6;)$#(*-/#$#4$);"#(+#3"&'/&6"%#=9#-!" Cell#.)$++0#C/&#-!"#6/6"*-:#-!" 1"#,())#*/,#(63)"6"*-#-!"#)/$%(*@#$*%#+$4(*@#/'#R3&"$%+!""-#'()"+#;+(*@#$#.;+-/6#=(*$&9#'/&6$-0
-!(*@#-/#="$&#(*#6(*%#(+#-!$-#-!"#-"2-#+!/,*#(*#-!"#."))#(+#-!"#&"+;)-#/'#"4$);$-(*@#-!"#'/&6;)$:#*/-#-!" 1"#,())#%/#-!(+#;+(*@ QFile#$*% QDataStream:#,!(.!#-/@"-!"&/4(%"#3)$-'/&6S(*%"3"*%"*-#=(*$&9
'/&6;)$#(-+")'0 <WV0
1"#,())#+-$&-#,(-!#,&(-(*@#$#R3&"$%+!""-#'()"7
void Spreadsheet::setFormula(int row, int column,
const QString &formula)
{ bool Spreadsheet::writeFile(const QString &fileName)
Cell *c = cell(row, column); {
if (!c) { QFile file(fileName);
c = new Cell; if (!file.open(QIODevice::WriteOnly)) {
setItem(row, column, c); QMessageBox::warning(this, tr("Spreadsheet"),
} tr("Cannot write file %1:\n%2.")
c->setFormula(formula); .arg(file.fileName())
} .arg(file.errorString()));
return false;
}
!" setFormula()#3&(4$-"#';*.-(/*#+"-+#-!"#'/&6;)$#'/&#$#@(4"*#."))0#<'#-!"#."))#$)&"$%9#!$+#$ Cell QDataStream out(&file);
/=T".-:#,"#&";+"#(-0#V-!"&,(+":#,"#.&"$-"#$#*", Cell#/=T".-#$*%#.$)) QTableWidget::setItem()#-/ out.setVersion(QDataStream::Qt_4_1);
out << quint32(MagicNumber);
(*+"&-#(-#(*-/#-!"#-$=)"0#?-#-!"#"*%:#,"#.$))#-!"#."))A+#/,* setFormula()#';*.-(/*:#,!(.!#,())#.$;+"#-!"
QApplication::setOverrideCursor(Qt::WaitCursor);
."))#-/#=" &"3$(*-"%#('#(-A+#+!/,*#/*#+.&""*0#1"#%/*A-#*""%#-/#,/&&9#$=/;-#%")"-(*@#-!" Cell#/=T".- for (int row = 0; row < RowCount; ++row) {
)$-"&#/*B QTableWidget#-$5"+#/,*"&+!(3#/'#-!"#."))#$*%#,())#%")"-"#(-#$;-/6$-(.$))9#$-#-!"#&(@!-#-(6"0 for (int column = 0; column < ColumnCount; ++column) {
QString str = formula(row, column);
if (!str.isEmpty())
QString Spreadsheet::currentLocation() const out << quint16(row) << quint16(column) << str;
{ }
return QChar('A' + currentColumn()) }
+ QString::number(currentRow() + 1); QApplication::restoreOverrideCursor();
} return true;
}
!" writeFile()#';*.-(/*#(+#.$))"%#'&/6 MainWindow::saveFile()#-/#,&(-"#-!"#'()"#-/#%(+50#<-#&"-;&*+ bool Spreadsheet::readFile(const QString &fileName)
{
true#/*#+;.."++: false#/*#"&&/&0
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly)) {
1"#.&"$-"#$ QFile#/=T".-#,(-!#-!"#@(4"*#'()"#*$6"#$*%#.$)) open()#-/#/3"*#-!"#'()"#'/&#,&(-(*@0#1"#$)+/ QMessageBox::warning(this, tr("Spreadsheet"),
.&"$-"#$ QDataStream#/=T".-#-!$-#/3"&$-"+#/*#-!" QFile#$*%#;+"#(-#-/#,&(-"#/;-#-!"#%$-$0 tr("Cannot read file %1:\n%2.")
.arg(file.fileName())
_;+-#="'/&"#,"#,&(-"#-!"#%$-$:#,"#.!$*@"#-!"#$33)(.$-(/*A+#.;&+/&#-/#-!"#+-$*%$&%#,$(-#.;&+/& .arg(file.errorString()));
F;+;$))9#$*#!/;&@)$++J#$*%#&"+-/&"#-!"#*/&6$)#.;&+/&#/*."#$))#-!"#%$-$#(+#,&(--"*0#?-#-!"#"*%#/'#-!" return false;
}
';*.-(/*:#-!"#'()"#(+#$;-/6$-(.$))9#.)/+"%#=9 QFileA+#%"+-&;.-/&0
QDataStream in(&file);
in.setVersion(QDataStream::Qt_4_1);
QDataStream#+;33/&-+#=$+(.#Q]]#-93"+#$+#,"))#$+#6$*9#/'#U-A+#-93"+0# !"#+9*-$2#(+#6/%")"%#$'-"& quint32 magic;
-!"#R-$*%$&%#Q]] <iostream>#.)$++"+0#C/&#"2$63)": in >> magic;
if (magic != MagicNumber) {
QMessageBox::warning(this, tr("Spreadsheet"),
out << x << y << z; tr("The file is not a Spreadsheet file."));
return false;
}
clear();
,&(-"+#-!"#4$&($=)"+ x: y:#$*% z#-/#$#+-&"$6:#$*% quint16 row;
quint16 column;
QString str;
in >> x >> y >> z; QApplication::setOverrideCursor(Qt::WaitCursor);
while (!in.atEnd()) {
in >> row >> column >> str;
setFormula(row, column, str);
&"$%+#-!"6#'&/6#$#+-&"$60#L".$;+"#-!"#Q]]#=$+(.#-93"+ char: short: int: long:#$*% long long#6$9 }
!$4"#%(''"&"*-#+(D"+#/*#%(''"&"*-#3)$-'/&6+:#(-#(+#+$'"+-#-/#.$+-#-!"+"#4$);"+#-/#/*"#/' qint8: quint8: QApplication::restoreOverrideCursor();
qint16: quint16: qint32: quint32: qint64:#$*% quint64:#,!(.!#$&"#@;$&$*-""%#-/#="#/'#-!"#+(D"#-!"9 return true;
$%4"&-(+"#F(*#=(-+J0 }
!"#R3&"$%+!""-#$33)(.$-(/*A+#'()"#'/&6$-#(+#'$(&)9#+(63)"0#?#R3&"$%+!""-#'()"#+-$&-+#,(-!#$#[GS=(-
*;6="&#-!$-#(%"*-('("+#-!"#'()"#'/&6$-#FMagicNumber:#%"'(*"%#$+ 0x7F51C883#(* spreadsheet.h:#$* !" readFile()#';*.-(/*#(+#4"&9#+(6()$&#-/ writeFile()0#1"#;+" QFile#-/#&"$%#(*#-!"#'()":#=;-#-!(+#-(6"
$&=(-&$&9#&$*%/6#*;6="&0J# !"*#./6"+#$#+"&("+#/'#=)/.5+:#"$.!#/'#,!(.!#./*-$(*+#$#+(*@)"#."))A+#&/,: ;+(*@#-!" QIODevice::ReadOnly#')$@#&$-!"&#-!$* QIODevice:: WriteOnly0# !"*#,"#+"-#-!" QDataStream
./);6*:#$*%#'/&6;)$0# /#+$4"#+3$.":#,"#%/*A-#,&(-"#/;-#"63-9#."))+0 4"&+(/*#-/#a0# !"#'/&6$-#'/&#&"$%(*@#6;+-#$),$9+#="#-!"#+$6"#$+#'/&#,&(-(*@0
<'#-!"&"#(+#$#+")".-(/*#$-#$)):#,"#+(63)9#&"-;&*#-!"#'(&+-#F$*%#/*)9J#/*"0# !"#.$+"#,!"&"#-!"&"#(+#*/
+")".-(/*#+!/;)%#*"4"&#!$33"*#+(*."#-!" ContiguousSelection#6/%"#-&"$-+#-!"#.;&&"*-#."))#$+#="(*@
+")".-"%0#L;-#-/#3&/-".-#$@$(*+-#-!"#3/++(=()(-9#/'#$#=;@#(*#/;&/@&$6#-!$-#6$5"+#*/#."))#.;&&"*-:
,"#!$*%)"#-!(+#.$+"0
void Spreadsheet::paste()
void Spreadsheet::copy()
{
{
QTableWidgetSelectionRange range = selectedRange();
QTableWidgetSelectionRange range = selectedRange();
QString str = QApplication::clipboard()->text();
QString str;
QStringList rows = str.split('\n');
for (int i = 0; i < range.rowCount(); ++i) {
int numRows = rows.count();
if (i > 0)
int numColumns = rows.first().count('\t') + 1;
str += "\n";
if (range.rowCount() * range.columnCount() != 1
for (int j = 0; j < range.columnCount(); ++j) {
&& (range.rowCount() != numRows
if (j > 0)
|| range.columnCount() != numColumns)) {
str += "\t";
QMessageBox::information(this, tr("Spreadsheet"),
str += formula(range.topRow() + i, range.leftColumn() + j);
tr("The information cannot be pasted because the copy "
}
"and paste areas aren't the same size."));
}
return;
QApplication::clipboard()->setText(str);
}
}
for (int i = 0; i < numRows; ++i) {
QStringList columns = rows[i].split('\t');
for (int j = 0; j < numColumns; ++j) {
!" copy()#+)/-#./&&"+3/*%+#-/#Y%(-bQ/390#<-#(-"&$-"+#/4"&#-!"#.;&&"*-#+")".-(/*#F,!(.!#(+#+(63)9#-!" int row = range.topRow() + i;
.;&&"*-#."))#('#-!"&"#(+#*/#"23)(.(-#+")".-(/*J0#Y$.!#+")".-"%#."))A+#'/&6;)$#(+#$%%"%#-/#$ QString:#,(-! int column = range.leftColumn() + j;
&/,+#+"3$&$-"%#=9#*",)(*"#.!$&$.-"&+#$*%#./);6*+#+"3$&$-"%#=9#-$=#.!$&$.-"&+0 if (row < RowCount && column < ColumnCount)
setFormula(row, column, columns[j]);
}
!"#+9+-"6#.)(3=/$&%#(+#$4$()$=)"#(*#U-#-!&/;@!#-!" QApplication::clipboard()#+-$-(.#';*.-(/*0#L9 }
.$))(*@ QClipboard::setText():#,"#6$5"#-!"#-"2-#$4$()$=)"#/*#-!"#.)(3=/$&%:#=/-!#-/#-!(+#$33)(.$-(/* somethingChanged();
$*%#-/#/-!"&#$33)(.$-(/*+#-!$-#+;33/&-#3)$(*#-"2-0#V;&#'/&6$-#,(-!#-$=#$*%#*",)(*"#.!$&$.-"&+#$+ }
+"3$&$-/&+#(+#;*%"&+-//%#=9#$#4$&("-9#/'#$33)(.$-(/*+:#(*.);%(*@#d(.&/+/'-#Y2.")0
8"2-:#,"#%"-"&6(*"#-!"#%(6"*+(/*#/'#-!"#./39#$&"$0# !"#*;6="&#/'#&/,+#(+#-!"#*;6="&#/'#+-&(*@+#(*
-!" QStringListB#-!"#*;6="&#/'#./);6*+#(+#-!"#*;6="&#/'#-$=#.!$&$.-"&+#(*#-!"#'(&+-#&/,:#3);+#O0#<'
/*)9#/*"#."))#(+#+")".-"%:#,"#;+"#-!$-#."))#$+#-!"#-/3S)"'-#./&*"&#/'#-!"#3$+-"#$&"$B#/-!"&,(+":#,"#;+"
-!"#.;&&"*-#+")".-(/*#$+#-!"#3$+-"#$&"$0
/#3"&'/&6#-!"#3$+-":#,"#(-"&$-"#/4"&#-!"#&/,+#$*%#+3)(-#"$.!#/'#-!"6#(*-/#."))+#=9#;+(*@
QString::split()#$@$(*:#=;-#-!(+#-(6"#;+(*@#-$=#$+#-!"#+"3$&$-/&0 C(@;&"#P0H#());+-&$-"+#-!"#+-"3+0
!"#$%&'(B(&C4+/!."&,<!:A-4$1&/%D/&!./-&/9%&+:$%41+9%%/
!" QTableWidget::selectedRanges()#';*.-(/*#&"-;&*+#$#)(+-#/'#+")".-(/*#&$*@"+0#1"#5*/,#-!"&"
.$**/-#="#6/&"#-!$*#/*"#=".$;+"#,"#+"-#-!"#+")".-(/*#6/%"#-/
QAbstractItemView::ContiguousSelection#(*#-!"#./*+-&;.-/&0#C/&#/;&#./*4"*("*.":#,"#%"'(*"#$
selectedRange()#';*.-(/*#-!$-#&"-;&*+#-!"#+")".-(/*#&$*@"7
}
QApplication::beep();
}
!" findNext()#+)/-#(-"&$-"+#-!&/;@!#-!"#."))+#+-$&-(*@#'&/6#-!"#."))#-/#-!"#&(@!-#/'#-!"#.;&+/&#$*%
6/4(*@#&(@!-#;*-()#-!"#)$+-#./);6*#(+#&"$.!"%:#-!"*#./*-(*;"+#'&/6#-!"#'(&+-#./);6*#(*#-!"#&/,#=")/,:
$*%#+/#/*#;*-()#-!"#-"2-#(+#'/;*%#/&#;*-()#-!"#4"&9 )$+-#."))#(+#&"$.!"%0#C/&#"2$63)":#('#-!"#.;&&"*-#."))
(+#."))#QGP:#,"#+"$&.!#cGP:#YGP:#M:#NGP:#-!"*#?GZ:#LGZ:#QGZ:#M:#NGZ:#$*%#+/#/*#;*-()#NIII0#<'#,"
'(*%#$#6$-.!:#,"#.)"$&#-!"#.;&&"*-#+")".-(/*:#6/4"#-!"#."))#.;&+/&#-/#-!"#."))#-!$-#6$-.!"%:#$*%#6$5"
-!"#,(*%/,#-!$-#./*-$(*+#-!" Spreadsheet#$.-(4"0#<'#*/#6$-.!#(+#'/;*%:#,"#6$5"#-!"#$33)(.$-(/*#=""3
-/#(*%(.$-"#-!$-#-!"#+"$&.!#'(*(+!"%#;*+;.."++';))90
!"#$%&'(G(&2/-$!."&/9%&+%<%,/!-.&4+&4&<!+/&-;&$-0+
!" recalculate()#+)/-#./&&"+3/*%+#-/# //)+bf".$).;)$-"0#<-#(+#$)+/#.$))"%#$;-/6$-(.$))9#=9
Spreadsheet#,!"*#*"."++$&90 [View full size image]
1"#(-"&$-"#/4"&#$))#-!"#."))+#$*%#.$)) setDirty()#/*#"4"&9#."))#-/#6$&5#"$.!#/*"#$+#&">;(&(*@
&".$).;)$-(/*0# !"#*"2-#-(6" QTableWidget#.$))+ text()#/*#$ Cell#-/#/=-$(*#-!"#4$);"#-/#+!/,#(*#-!"
+3&"$%+!""-:#-!"#4$);"#,())#="#&".$).;)$-"%0
!" setAutoRecalculate()#+)/-#./&&"+3/*%+#-/#V3-(/*+b?;-/Sf".$).;)$-"0#<'#-!"#'"$-;&"#(+#="(*@
-;&*"%#/*:#,"#&".$).;)$-" -!"#,!/)"#+3&"$%+!""-#(66"%($-")9#-/#6$5"#+;&"#-!$-#(-A+#;3#-/#%$-"B
$'-"&,$&%: recalculate()#(+#.$))"%#$;-/6$-(.$))9#'&/6 somethingChanged()0
1"#%/*A-#*""%#-/#(63)"6"*-#$*9-!(*@#'/&#V3-(/*+bR!/,#g&(%#=".$;+" QTableWidget#$)&"$%9#!$+#$
?'-""&'/&6(*@#-!" qStableSort():#,"#6/4"#-!"#%$-$#=$.5#(*-/#-!"#-$=)":#.)"$&#-!"#+")".-(/*:#$*%
setShowGrid()#+)/-: ,!(.!#(-#(*!"&(-+#'&/6#(-+#=$+"#.)$++ QTable-View0#?))#-!$-#&"6$(*+#(+
.$)) somethingChanged()0
Spreadsheet::sort():#,!(.!#(+#.$))"%#'&/6 MainWindow::sort()7
8/,#)"-A+#+""#$*#"2$63)"#(*4/)4(*@ SpreadsheetCompare7
Subclassing QTableWidgetItem
QStringList row1, row2;
QSpreadsheetCompare compare; !" Cell#.)$++#(*!"&(-+#'&/6 QTableWidgetItem0# !"#.)$++#(+#%"+(@*"%#-/#,/&5#,"))#,(-! Spreadsheet:
...
=;-#(-#!$+#*/#+3".('(.#%"3"*%"*.("+#/*#-!$-#.)$++#$*%#./;)%#(*#-!"/&9#="#;+"%#(*#$*9 QTableWidget0
if (compare(row1, row2)) {
// row1 is less than row2 X"&"A+#-!"#!"$%"&#'()"7
}
#ifndef CELL_H
#define CELL_H
!" compare#/=T".-#.$*#="#;+"%#T;+-#$+#('#(-#!$%#=""*#$#3)$(* compare()#';*.-(/*0#?%%(-(/*$))9:#(-+ #include <QTableWidgetItem>
(63)"6"*-$-(/*#.$*#$.."++#$))#-!"#+/&-#5"9+#$*%#+/&-#/&%"&+:#,!(.!#$&"#+-/&"%#$+#6"6="$&($=)"+0 class Cell : public QTableWidgetItem
{
?*#$)-"&*$-(4"#-/#-!(+#+.!"6"#,/;)%#!$4"#=""*#-/#+-/&"#-!"#+/&-#5"9+#$*%#+/&-#/&%"&+#(*#@)/=$) public:
4$&($=)"+#$*%#;+"#$#3)$(* compare()#';*.-(/*0#X/,"4"&:#./66;*(.$-(*@#-!&/;@!#@)/=$)#4$&($=)"+#(+ Cell();
(*")"@$*-#$*%#.$*#)"$%#-/#+;=-)"#=;@+0#C;*.-/&+#$&"#$#6/&"#3/,"&';)#(%(/6#'/&#(*-"&'$.(*@#,(-! QTableWidgetItem *clone() const;
void setData(int role, const QVariant &value);
-"63)$-"#';*.-(/*+#+;.!#$+ qStableSort()0
QVariant data(int role) const;
void setFormula(const QString &formula);
X"&"#(+#-!"#(63)"6"*-$-(/*#/'#-!"#';*.-(/*#-!$-#(+#;+"%#-/#./63$&"#-,/#+3&"$%+!""-#&/,+7 QString formula() const;
void setDirty();
private:
bool SpreadsheetCompare::operator()(const QStringList &row1, QVariant value() const;
const QStringList &row2) const QVariant evalExpression(const QString &str, int &pos) const;
{ QVariant evalTerm(const QString &str, int &pos) const;
for (int i = 0; i < KeyCount; ++i) { QVariant evalFactor(const QString &str, int &pos) const;
int column = keys[i]; mutable QVariant cachedValue;
if (column != -1) { mutable bool cacheIsDirty;
if (row1[column] != row2[column]) { };
if (ascending[i]) { #endif
return row1[column] < row2[column];
} else {
return row1[column] > row2[column];
} !" Cell#.)$++#"2-"*%+ QTableWidgetItem#=9#$%%(*@#-,/#3&(4$-"#4$&($=)"+7
}
} • cachedValue#.$.!"+#-!"#."))A+#4$);"#$+#$ QVariant0
} • cacheIsDirty#(+ true#('#-!"#.$.!"%#4$);"#(+*A-#;3#-/#%$-"0
return false;
} 1"#;+" QVariant#=".$;+"#+/6"#."))+#!$4"#$ double#4$);":#,!()"#/-!"&+#!$4"#$ QString#4$);"0
<'#-!"#'/&6;)$#+-$&-+#,(-!#$#+(*@)"#>;/-"#F'/&#"2$63)":#K#AOG[PZKJ:#-!"#+(*@)"#>;/-"#/..;3("+#3/+(-(/*
E#$*%#-!"#4$);"#(+#-!"#+-&(*@#'&/6#3/+(-(/*#O#-/#-!"#"*%0 h"-A+#+-$&-#,(-! evalExpression():#-!"#';*.-(/*#-!$-#3$&+"+#$* ()$&"**!%+7
<'#-!"#'/&6;)$#+-$&-+#,(-!#$*#">;$)+#+(@*#FA\AJ:#,"#-$5"#-!"#+-&(*@#'&/6#3/+(-(/*#O#$*%#&"6/4"#$*9
+3$."+#(-#6$9#./*-$(*0# !"*#,"#.$)) evalExpression()#-/#./63;-"#-!"#4$);"#/'#-!"#"23&"++(/*0# !" QVariant Cell::evalExpression(const QString &str, int &pos) const
pos#$&@;6"*-#(+#3$++"%#=9#&"'"&"*."B#(-#(*%(.$-"+#-!"#3/+(-(/*#/'#-!"#.!$&$.-"&#,!"&"#3$&+(*@#+!/;)% {
="@(*0#?'-"&#-!"#.$))#-/ evalExpression():#-!"#.!$&$.-"&#$-#3/+(-(/* pos#+!/;)%#="#-!" QChar::Null QVariant result = evalTerm(str, pos);
.!$&$.-"&#,"#$33"*%"%:#('#(-#,$+#+;.."++';))9#3$&+"%0#<'#-!"#3$&+"#'$()"%#="'/&"#-!"#"*%:#,"#+"- while (str[pos] != QChar::Null) {
QChar op = str[pos];
cachedValue#-/#=" Invalid0
if (op != '+' && op != '-')
return result;
<'#-!"#'/&6;)$#%/"+*A-#="@(*#,(-!#$#+(*@)"#>;/-"#/&#$*#">;$)+#+(@*:#,"#$--"63-#-/#./*4"&-#(-#-/#$ ++pos;
')/$-(*@S3/(*-#4$);"#;+(*@ toDouble()0#<'#-!"#./*4"&+(/*#,/&5+:#,"#+"- cachedValue#-/#="#-!" QVariant term = evalTerm(str, pos);
&"+;)-(*@#*;6="&B#/-!"&,(+":#,"#+"- cachedValue#-/#="#-!"#'/&6;)$#+-&(*@0#C/&#"2$63)":#$#'/&6;)$#/' if (result.type() == QVariant::Double
KO0ZEK#.$;+"+ toDouble()#-/#+"- ok#-/ true#$*%#&"-;&*#O0Z:#,!()"#$#'/&6;)$#/'#K1/&)%#e/3;)$-(/*K && term.type() == QVariant::Double) {
.$;+"+ toDouble()#-/#+"- ok#-/ false#$*%#&"-;&*#E0E0 if (op == '+') {
result = result.toDouble() + term.toDouble();
} else {
L9#@(4(*@ toDouble()#$#3/(*-"&#-/#$ bool:#,"#$&"#$=)"#-/#%(+-(*@;(+!#="-,""*#-!"#./*4"&+(/*#/'#$ result = result.toDouble() - term.toDouble();
+-&(*@#-!$-#&"3&"+"*-+#-!"#*;6"&(.#4$);"#E0E#$*%#$#./*4"&+(/*#"&&/&#F,!"&"#E0E#(+#$)+/#&"-;&*"%#=;- }
-!" bool (+#+"-#-/ falseJ0#R/6"-(6"+#-!"#&"-;&*(*@#/'#$#D"&/#4$);"#/*#./*4"&+(/*#'$();&"#(+#"2$.-)9 } else {
,!$-#,"#*""%:#(*#,!(.!#.$+"#,"#%/#*/-#=/-!"$++(*@#$#3/(*-"&#-/#$ bool0#C/"&'/&6$*."#$*% result = Invalid;
3/&-$=()(-9#&"$+/*+:#U-#*"4"&#;+"+#Q]]#"2."3-(/*+#-/#&"3/&-#'$();&"0# !(+#%/"+*A-#3&"4"*-#9/;#'&/6 }
;+(*@#-!"6#(*#U-#3&/@&$6+:#3&/4(%(*@#9/;&#./63()"&#+;33/&-+#-!"60 }
return result;
}
!" value()#';*.-(/*#(+#%".)$&"%#./*+-0#1"#!$%#-/#%".)$&" cachedValue#$*% cacheIsValid#$+#6;-$=)"
4$&($=)"+#+/#-!$-#-!"#./63()"&#,())#$))/,#;+#-/#6/%('9#-!"6#(*#./*+-#';*.-(/*+0#<-#6(@!-#="#-"63-(*@
-/#6$5" value()#*/*S./*+-#$*%#&"6/4"#-!" mutable#5"9,/&%+:#=;-#-!$-#,/;)%#*/-#./63()"#=".$;+"
,"#.$)) value()#'&/6 data():#$#./*+-#';*.-(/*0 C(&+-:#,"#.$)) evalTerm()#-/#@"-#-!"#4$);"#/'#-!"#'(&+-#-"&60#<'#-!"#'/))/,(*@#.!$&$.-"&#(+#A]A#/&#A]SSA:
,"#./*-(*;"#=9#.$))(*@ evalTerm()#$#+"./*%#-(6"B#/-!"&,(+":#-!"#"23&"++(/*#./*+(+-+#/'#$#+(*@)"
1"#!$4"#*/,#./63)"-"%#-!"#R3&"$%+!""-#$33)(.$-(/*:#$3$&-#'&/6#3$&+(*@#'/&6;)$+0# !"#&"+-#/'#-!(+ -"&6:#$*%#,"#&"-;&*#(-+#4$);"#$+#-!"#4$);"#/'#-!"#,!/)"#"23&"++(/*0#?'-"&#,"#!$4"#-!"#4$);"#/'#-!"
+".-(/*#./4"&+ evalExpression()#$*%#-!"#-,/#!")3"&#';*.-(/*+ evalTerm()#$*% evalFactor()0# !"#./%" '(&+-#-,/#-"&6+:#,"#./63;-"#-!"#&"+;)-#/'#-!"#/3"&$-(/*:#%"3"*%(*@#/*#-!"#/3"&$-/&0#<'#=/-!#-"&6+
(+#$#=(-#./63)(.$-"%:#=;-#(-#(+#(*.);%"%#!"&"#-/#6$5"#-!"#$33)(.$-(/*#./63)"-"0#R(*."#-!"#./%"#(+#*/- "4$);$-"%#-/#$ double:#,"#./63;-"#-!"#&"+;)-#$+#$ doubleB#/-!"&,(+":#,"#+"-#-!"#&"+;)-#-/#="
&")$-"%#-/#g`<#3&/@&$66(*@:#9/;#.$* +$'")9#+5(3#(-#$*%#./*-(*;"#&"$%(*@#'&/6 Q!$3-"&#Z0 Invalid0
• !"#$%&'&()*+#*,&-).#"
• /!0123""&() +,&-).#
1"#+"-#-!"#%"'$;)-#&$*@"#-/#="#E#-/#GZZ#F0x00#-/ 0xFFJ:#,!(.!#(+#6/&"#$33&/3&($-"#'/&#$#!"2$%".(6$)
• 4(#.)53#&()* !"#$%*,&-).#"*6*+#*8."&)(.5
+3(*#=/2#-!$* QSpinBoxA+#%"'$;)-#/'#E#-/#II0
• 8$!02.*9!::.5&()
!"#;+"&#.$*#6/%('9#$#+3(*#=/2A+#.;&&"*-#4$);"#"(-!"&#=9#.)(.5(*@#(-+#;3#$*%#%/,*#$&&/,+#/&#=9
!(+#.!$3-"&#"23)$(*+#!/,#-/#%"4")/3#.;+-/6#,(%@"-+#;+(*@#U-0#Q;+-/6#,(%@"-+#.$*#="#.&"$-"%#=9
-93(*@#$#4$);"#(*-/#-!"#+3(*#=/2A+#)(*"#"%(-/&0#<*#-!"#)$--"&#.$+":#,"#,$*-#-/#&"+-&(.-#-!"#;+"&A+#(*3;-
+;=.)$++(*@#$*#"2(+-(*@#U-#,(%@"-#/&#=9#+;=.)$++(*@ QWidget#%(&".-)90#1"#,())#%"6/*+-&$-"#=/-!
-/#)"@(-(6$-"#!"2$%".(6$)#*;6="&+0# /#$.!("4"#-!(+:#,"#;+"#$ QRegExpValidator#-!$-#$.."3-+
$33&/$.!"+:#$*%#,"#,())#$)+/#+""#!/,#-/#(*-"@&$-"#$#.;+-/6#,(%@"-#,(-! 3'-4"*!5+"&#+/#-!$-#(-#.$*
="-,""*#/*"#$*%#"(@!-#.!$&$.-"&+:#"$.!#/'#,!(.!#6;+-#="#(*#/*"#/'#-!"#+"-+:#AEA#-/#AIA:#A?A#-/#ACA:#$*%
="#;+"%#T;+-#)(5"#$#=;()-S(*#U-#,(%@"-0#1"#,())#&/;*%#/''#-!"#.!$3-"&#=9#3&"+"*-(*@#$#.;+-/6#,(%@"-
A$A#-/#A'A0
-!$-#;+"+#%/;=)"#=;''"&(*@:#$#3/,"&';)#-".!*(>;"#'/&#!(@!S+3""%#%&$,(*@0
#ifndef HEXSPINBOX_H
#define HEXSPINBOX_H !" textFromValue()#';*.-(/*#./*4"&-+#$*#(*-"@"$);"#-/#$#+-&(*@0 QSpinBox#.$))+#(-#-/#;3%$-"#-!"
#include <QSpinBox> "%(-/$&-#/'#-!"#+3(*#=/2#,!"*#-!"#;+"&"++"+#-!"#+3(*#=/2A+#;3#/&#%/,*#$&&/,+0#1"#;+"#-!"
class QRegExpValidator; +-$-(.#';*.-(/* QString::number()#,(-!#$#+"./*%#$&@;6"*-#/'#OH#-/#./*4"&-#-!"#4$);"#-/#)/,"&.$+"
class HexSpinBox : public QSpinBox !"2$%".(6$):#$*%#.$)) QString::toUpper()#/*#-!"#&"+;)-#-/#6$5"#(-#;33"&.$+"0
{
Q_OBJECT
public: int HexSpinBox::valueFromText(const QString &text) const
HexSpinBox(QWidget *parent = 0); {
protected: bool ok;
QValidator::State validate(QString &text, int &pos) const; return text.toInt(&ok, 16);
int valueFromText(const QString &text) const; }
QString textFromValue(int value) const;
private:
QRegExpValidator *validator;
}; !" valueFromText()#';*.-(/*#3"&'/&6+#-!" &"4"&+"#./*4"&+(/*:#'&/6#$#+-&(*@#-/#$*#(*-"@"$);"0#<-
#endif (+#.$))"%#=9 QSpinBox#,!"*#-!"#;+"&#-93"+#$#4$);"#(*-/#-!"#"%(-/$&-#/'#-!"#+3(*#=/2#$*%#3&"++"+
Y*-"&0#1"#;+"#-!" QString::toInt()#';*.-(/*#-/#$--"63-#-/#./*4"&-#-!"#.;&&"*-#-"2-#-/#$*#(*-"@"&
4$);":#$@$(*#;+(*@#=$+"#OH0#<'#-!"#+-&(*@#(+#*/-#4$)(%#!"2$%".(6$): ok#(+#+"-#-/ false#$*% toInt()
!" HexSpinBox#(*!"&(-+#6/+-#/'#(-+#';*.-(/*$)(-9#'&/6 QSpinBox0#<-#3&/4(%"+#$#-93(.$)#./*+-&;.-/&#$*% &"-;&*+#E0#X"&":#,"#%/*A-#!$4"#-/#./*+(%"&#-!(+#3/++(=()(-9#=".$;+"#-!"#4$)(%$-/&#/*)9#3"&6(-+#4$)(%
&"(63)"6"*-+#-!&""#4(&-;$)#';*.-(/*+#'&/6 QSpinBox0 !"2$%".(6$)#+-&(*@+#-/#="#"*-"&"%0#<*+-"$%#/'#3$++(*@#-!" $%%&"++#/'#$#%;669#4$&($=)"#FokJ:#,"
./;)%#(*+-"$%#3$++#$#*;))#3/(*-"&#$+#-!"#'(&+-#$&@;6"*-#-/ toInt()0
/#%"6/*+-&$-"#!/,#-/#,&(-"#$#.;+-/6#,(%@"-#;+(*@#-!(+#$33&/$.!:#,"#,())#.&"$-"#-!" IconEditor
,(%@"-#+!/,*#(* C(@;&"#Z0G0# !" IconEditor#(+#$#,(%@"-#-!$-#./;)%#="#;+"%#(*#$*#(./*#"%(-(*@ protected:
3&/@&$60 void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void paintEvent(QPaintEvent *event);
!"#$%&>()(&89% IconEditor&0!1"%/ private:
void setImagePixel(const QPoint &pos, bool opaque);
QRect pixelRect(int i, int j) const;
QColor curColor;
QImage image;
int zoom;
};
#endif
IconEditor#&"(63)"6"*-+#-!&""#3&/-".-"%#';*.-(/*+#'&/6 QWidget#$*%#!$+#$#'",#3&(4$-"#';*.-(/*+#$*%
4$&($=)"+0# !"#-!&""#3&(4$-"#4$&($=)"+#!/)%#-!"#4$);"+#/'#-!"#-!&""#3&/3"&-("+0
!"#(63)"6"*-$-(/*#'()"#="@(*+#,(-!#-!" IconEditorA+#./*+-&;.-/&7
#include <QtGui>
#include "iconeditor.h"
IconEditor::IconEditor(QWidget *parent)
: QWidget(parent)
{
setAttribute(Qt::WA_StaticContents);
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); }
curColor = Qt::black;
zoom = 8;
image = QImage(16, 16, QImage::Format_ARGB32);
image.fill(qRgba(0, 0, 0, 0)); !" sizeHint()#';*.-(/*#(+#&"(63)"6"*-"%#'&/6 QWidget#$*%#&"-;&*+#-!"#(%"$)#+(D"#/'#$#,(%@"-0#X"&":
} ,"#-$5"#-!"#(6$@"#+(D"#6;)-(3)("%#=9#-!"#D//6#'$.-/&:#,(-!#/*"#"2-&$#3(2")#(*#"$.!#%(&".-(/*#-/
$../66/%$-"#$#@&(%#('#-!"#D//6#'$.-/&#(+#[#//&"0#F1"#%/*A-#+!/,#$#@&(%#('#-!"#D//6#'$.-/&#(+#G#/&
O:#=".$;+"#-!"#@&(%#,/;)%#-!"*#!$&%)9#)"$4"#$*9#&//6#'/&#-!"#(./*A+#3(2")+0J
!"#./*+-&;.-/&#!$+#+/6"#+;=-)"#$+3".-+#+;.!#$+#-!" Qt::WA_StaticContents#$--&(=;-"#$*%#-!"
?#,(%@"-A+#+(D"#!(*-#(+#6/+-)9#;+"';)#(*#./*T;*.-(/*#,(-!#)$9/;-+0#U-A+#)$9/;-#6$*$@"&+#-&9#$+#6;.!
setSizePolicy()#.$))0#1"#,())#%(+.;++#-!"6#+!/&-)90
$+#3/++(=)"#-/#&"+3".-#$#,(%@"-A+#+(D"#!(*-#,!"*#-!"9#)$9#/;-#$#'/&6A+#.!()%#,(%@"-+0#C/& IconEditor
-/#="#$#@//%#)$9/;-#.(-(D"*:#(-#6;+-#&"3/&-#$#.&"%(=)"#+(D"#!(*-0
!"#3"*#./)/&#(+#+"-#-/#=)$.50# !"#D//6#'$.-/&#(+#+"-#-/#^:#6"$*(*@ -!$-#"$.!#3(2")#(*#-!"#(./*#,())#="
&"*%"&"%#$+#$*#^#2#^#+>;$&"0
<*#$%%(-(/*#-/#-!"#+(D"#!(*-:#,(%@"-+#!$4"#$#+(D"#3/)(.9#-!$-#-"))+#-!"#)$9/;-#+9+-"6#,!"-!"&#-!"9#)(5"
-/#="#+-&"-.!"%#$*%#+!&;*50#L9#.$))(*@ setSizePolicy()#(*#-!"#./*+-&;.-/& ,(-! QSizePolicy::Minimum
!"#(./*#%$-$#(+#+-/&"%#(*#-!" image#6"6="$&($=)"#$*%#.$*#="#$.."++"%#-!&/;@!#-!" $+#!/&(D/*-$)#$*%#4"&-(.$)#3/)(.("+:#,"#-"))#$*9#)$9/;-#6$*$@"&#-!$-#(+#&"+3/*+(=)"#'/&#-!(+#,(%@"-#-!$-
setIconImage()#$*% iconImage()#';*.-(/*+0#?*#(./*#"%(-/&/@&$6#,/;)%#-93(.$))9#.$)) -!"#,(%@"-A+#+(D"#!(*-#(+#&"$))9#(-+#6(*(6;6#+(D"0#<*#/-!"&#,/&%+:#-!"#,(%@"-#.$*#="#+-&"-.!"%#('
setIconImage()#,!"* -!"#;+"&#/3"*+#$*#(./*#'()"#$*% icon-Image()#-/#&"-&("4"#-!"#(./*#,!"*#-!"#;+"& &">;(&"%:#=;-#(-#+!/;)%#*"4"&#+!&(*5#=")/,#-!"#+(D"#!(*-0# !(+#.$*#="#/4"&&(%%"*#(* 3'-4"*!5+"&#=9
,$*-+#-/#+$4"#(-0# !" image#4$&($=)"#(+#/'#-93" QImage0#1"#(*(-($)(D"#(-#-/#OH#2#OH#3(2")+#$*%#[GS=(- +"--(*@#-!"#,(%@"-A+ sizePolicy#3&/3"&-90# !"#6"$*(*@#/'#-!"#4$&(/;+#+(D"#3/)(.("+#(+#"23)$(*"%#(*
?fgL#'/&6$-:#$#'/&6$-#-!$-#+;33/&-+#+"6(S-&$*+3$&"*.90#1"#.)"$&#-!"#(6$@" %$-$#=9#'())(*@#(-#,(-!#$ Q!$3-"&#H#Fh$9/;-#d$*$@"6"*-J0
-&$*+3$&"*-#./)/&0
!"&"#$&"#6$*9#+(-;$-(/*+#,!"*#$#3$(*-#"4"*-#(+#@"*"&$-"%#$*% paintEvent()#(+#.$))"%7
• 1!"*#$#,(%@"-#(+#+!/,*#'/&#-!"#'(&+-#-(6":#-!"#+9+-"6#$;-/6$-(.$))9#@"*"&$-"+#$#3$(*-#"4"*-
-/#'/&."#-!"#,(%@"-#-/#3$(*-#(-+")'0
• 1!"*#$#,(%@"-#(+#&"+(D"%:#-!"#+9+-"6#@"*"&$-"+#$#3$(*-#"4"*-0
• <'#-!"#,(%@"-#(+#/=+.;&"%#=9#$*/-!"&#,(*%/,#$*%#-!"*#&"4"$)"%#$@$(*:#$#3$(*-#"4"*-#(+
@"*"&$-"%#'/&#-!"#$&"$#-!$-#,$+#!(%%"*#F;*)"++#-!"#,(*%/,#+9+-"6#+-/&"%#-!"#$&"$J0
X"&"A+#-!"#./%"7
L"'/&"#,"#.$)) drawLine()#/*#-!" QPainter:#,"#+"-#-!"#)(*"A+#./)/&#;+(*@ setPen()0#1"#./;)%#!$&%S
./%"#$#./)/&:#)(5"#=)$.5#/&#@&$9:#=;-#$#="--"&#$33&/$.!#(+#-/#;+"#-!"#,(%@"-A+#3$)"--"0
void IconEditor::paintEvent(QPaintEvent *event)
{ Y4"&9#,(%@"-#(+#">;(33"%#,(-!#$#3$)"--"#-!$-#+3".('("+#,!(.!#./)/&+#+!/;)%#="#;+"%#'/&#,!$-0#C/&
QPainter painter(this); "2$63)":#-!"&"#(+#$#3$)"--"#"*-&9#'/&#-!"#=$.5@&/;*%#./)/&#/'#,(%@"-+#F;+;$))9#)(@!-#@&$9J#$*%#/*"#'/&
if (zoom >= 3) { -!"#./)/&#/'#-"2-#/*#-!$-#=$.5@&/;*%#F;+;$))9#=)$.5J0#L9#%"'$;)-:#$#,(%@"-A+#3$)"--"#$%/3-+#-!"
painter.setPen(palette().foreground().color()); ,(*%/,#+9+-"6A+#./)/&#+.!"6"0#L9#;+(*@#./)/&+#'&/6#-!"#3$)"--":#,"#"*+;&"#-!$- IconEditor#&"+3".-+
for (int i = 0; i <= image.width(); ++i) -!"#;+"&A+#3&"'"&"*."+0
painter.drawLine(zoom * i, 0,
zoom * i, zoom * image.height());
for (int j = 0; j <= image.height(); ++j) ?#,(%@"-A+#3$)"--"#./*+(+-+#/'#-!&""#./)/&#@&/;3+7#$.-(4":#(*$.-(4":#$*%#%(+$=)"%0#1!(.!#./)/&#@&/;3
painter.drawLine(0, zoom * j, +!/;)%#="#;+"%#%"3"*%+#/*#-!"#,(%@"-A+#.;&&"*-#+-$-"7
zoom * image.width(), zoom * j);
} • !" Active#@&/;3#(+#;+"%#'/&#,(%@"-+#(*#-!"#.;&&"*-)9 $.-(4"#,(*%/,0
for (int i = 0; i < image.width(); ++i) { • !" Inactive#@&/;3#(+#;+"%#'/&#,(%@"-+#(*#-!"#/-!"&#,(*%/,+0
for (int j = 0; j < image.height(); ++j) { • !" Disabled#@&/;3#(+#;+"%#'/&#%(+$=)"%#,(%@"-+#(*#$*9#,(*%/,0
QRect rect = pixelRect(i, j);
if (!event->region().intersect(rect).isEmpty()) {
QColor color = QColor::fromRgba(image.pixel(i, j)); !" QWidget::palette()#';*.-(/*#&"-;&*+#-!"#,(%@"-A+#3$)"--"#$+#$ QPalette#/=T".-0#Q/)/&#@&/;3+#$&"
painter.fillRect(rect, color); +3".('("%#$+#"*;6+#/'#-93" QPalette::ColorGroup0
}
} 1!"*#,"#,$*-#-/#@"-#$*#$33&/3&($-"#=&;+!#/&#./)/&#'/&#%&$,(*@:#-!"#./&&".-#$33&/$.!#(+#-/#;+"#-!"
} .;&&"*-#3$)"--":#/=-$(*"%#'&/6 QWidget::palette():#$*%#-!"#&">;(&"%#&/)":#'/&#"2$63)":
} QPalette::foreground()0#Y$.!#&/)"#';*.-(/*#&"-;&*+#$#=&;+!:#,!(.!#(+#*/&6$))9#,!$-#,"#,$*-:#=;-#('
,"#T;+-#*""%#-!"#./)/&#,"#.$*#"2-&$.-#(-#'&/6#-!"#=&;+!:#$+#,"#%(%#(*#-!" paintEvent()0#L9#%"'$;)-:
-!"#=&;+!"+#&"-;&*"%#$&"#-!/+"#$33&/3&($-"#-/#-!"#,(%@"-A+#+-$-":#+/#,"#%/#*/-#*""%#-/#+3".('9#$
1"#+-$&-#=9#./*+-&;.-(*@#$ QPainter#/=T".-#/*#-!"#,(%@"-0#<'#-!"#D//6#'$.-/&#(+#[#//&":#,"#%&$, ./)/&#@&/;30
-!"#!/&(D/*-$)#$*%#4"&-(.$)#)(*"+#-!$-#'/&6#-!"#@&(%#;+(*@#-!" QPainter::drawLine()#';*.-(/*0
!" paintEvent()#';*.-(/*#'(*(+!"+#=9#%&$,(*@#-!"#(6$@"#(-+")'0# !"#.$))#-/ IconEditor::pixelRect()
&"-;&*+#$ QRect#-!$-#%"'(*"+#-!"#&"@(/*#-/#&"3$(*-0#?+#$*#"$+9#/3-(6(D$-(/*:#,"#%/*A-#&"%&$,#3(2")+
-!$-#'$))#/;-+(%"#-!(+#&"@(/*0 6/;+"#=;--/*:#,"#$)+/#.$)) setImagePixel():#=;-#3$++ false#-/#.)"$&#-!"#3(2")0
!"#$%&>('(&3$40!."&4&<!.%&#+!." QPainter
void IconEditor::mouseMoveEvent(QMouseEvent *event)
{
if (event->buttons() & Qt::LeftButton) {
setImagePixel(event->pos(), true);
} else if (event->buttons() & Qt::RightButton) {
setImagePixel(event->pos(), false);
}
}
!" mouseMoveEvent()#!$*%)"+#K6/;+"#6/4"K#"4"*-+0#L9#%"'$;)-:#-!"+"#"4"*-+#$&"#/*)9#@"*"&$-"%
,!"*#-!"#;+"&#(+#!/)%(*@#%/,*#$#=;--/*0#<-#(+#3/++(=)"#-/#.!$*@"#-!(+#="!$4(/&#=9#.$))(*@
QWidget::setMouseTracking():#=;-#,"#%/*A-#*""%#-/#%/#+/#'/&#-!(+#"2$63)"0
_;+-#$+#3&"++(*@#-!"#)"'-#/&#&(@!-#6/;+"#=;--/*#+"-+#/&#.)"$&+#$#3(2"):#5""3(*@#(-#3&"++"%#$*%#!/4"&(*@
/4"&#$#3(2")#(+#$)+/#"*/;@!#-/#+"-#/&#.)"$&#$#3(2")0#R(*."#(-A+#3/++(=)"#-/#!/)%#6/&"#-!$*#/*"#=;--/*
3&"++"%#%/,*#$-#$#-(6":#-!" 4$);"#&"-;&*"%#=9 QMouseEvent::buttons()#(+#$#=(-,(+"#Vf#/'#-!"#6/;+"
1"#.$)) QPainter::fillRect()#-/#%&$,#$#D//6"%#3(2")0 QPainter::fillRect()#-$5"+#$ QRect#$*%#$ =;--/*+0#1"#-"+-#,!"-!"&#$#."&-$(*#=;--/*#(+#3&"++"%#%/,*#;+(*@#-!" &#/3"&$-/&:#$*%#('#-!(+#(+#-!"
QBrush0#L9#3$++(*@#$ QColor#$+#-!"#=&;+!:#,"#/=-$(*#$#+/)(%#'())#3$--"&*0
.$+"#,"#.$)) setImagePixel()0
QRect IconEditor::pixelRect(int i, int j) const void IconEditor::setImagePixel(const QPoint &pos, bool opaque)
{ {
if (zoom >= 3) { int i = pos.x() / zoom;
return QRect(zoom * i + 1, zoom * j + 1, zoom - 1, zoom - 1); int j = pos.y() / zoom;
} else { if (image.rect().contains(i, j)) {
return QRect(zoom * i, zoom * j, zoom, zoom); if (opaque) {
} image.setPixel(i, j, penColor().rgba());
} } else {
image.setPixel(i, j, qRgba(0, 0, 0, 0));
}
!" pixelRect()#';*.-(/*#&"-;&*+#$ QRect#+;(-$=)"#'/& QPainter::fillRect()0# !" i#$*% j#3$&$6"-"&+ update(pixelRect(i, j));
$&"#3(2")#.//&%(*$-"+#(*#-!" QImage*/-#(*#-!"#,(%@"-0#<'#-!"#D//6#'$.-/&#(+#O:#-!"#-,/#.//&%(*$-" }
+9+-"6+#./(*.(%"#"2$.-)90 }
!"#&34$D4,@)#+2#(!"#.3+-+(%+*#4..3+4,!#43"#(!4(#.3+."3(%")#(!4(#43"#).",%2%,#(+#(!"#,7)(+-#$%&'"(
!" IconEditor#$%&'"(#%)#*+$#,+-./"("0#1)%*'#(!"#%*2+3-4(%+*#4*&#"54-./")#23+-#"43/%"3#,!4.("3)6
43"*K(#4,,"))%D/"#%* !"#$%&'($)#4*&#(!4(#(!"#$%&'"(#%)*K(#3"*&"3")#%()"/20#?+(!#(!")"#.3+D/"-)
$"#,+7/&#$3%("#,+&"#(!4(#7)")#(!" IconEditor#4)#4#$%*&+$#%*#%()#+$*#3%'!(6#4)#4#,"*(34/#$%&'"(#%*#4 ,4*#D"#)+/I"&#D8#7)%*'#(!"#./7'%*#4..3+4,!0
QMainWindow6#4)#4#,!%/&#$%&'"(#%*)%&"#4#/48+7(6#+3#4)#4#,!%/&#$%&'"(#%*)%&"#4 QScrollArea#9.0#:;<=0#>*
(!"#*"5(#)",(%+*6#$"#$%//#)""#!+$#(+#%*("'34("#%(#$%(! !"#$%&'($)0
!"#./7'%*#4..3+4,!#3"A7%3")#(!"#,3"4(%+*#+2#4#./7'%*#/%D3438#(!4( !"#$%&'($)#,4*#/+4(#37*E(%-"
4*)"#(+#,3"4("#%*)(4*,")#+2#(!"#$%&'"(0# !"#3"4/#$%&'"(#%)#(!"*#7)"&#D8 !"#$%&'($)#$!"*
"&%(%*'#(!"#2+3-#4*+3#.3"I%"$%*'6#4*&#(!4*@)#(+#F(K)#-"(4E+DV",(#)8)("-6 !"#$%&'($)#,4*
&8*4-%,4//8#+D(4%*#(!"#/%)(#+2#%()#.3+."3(%")0# +#)!+$#!+$#(!%)#$+3@)6#$"#$%//#%*("'34("#(!"
IconEditor#23+-#(!"#.3"I%+7)#)",(%+*#4)#4#./7'%*0
IconEditorPlugin::IconEditorPlugin(QObject *parent)
: QObject(parent)
{
}
!"#,+*)(37,(+3#%)#(3%I%4/0 !" whatsThis()#27*,(%+*#3"(73*)#(!"#CO!4(K)# !%)WC#("5(#2+3 !"#$%&'($)#(+#&%)./480
G(#(!"#"*&#+2#(!"#)+73,"#2%/"#(!4(#%-./"-"*()#(!"#./7'%*#,/4))6#$"#-7)(#7)"#(!" Q_EXPORT_PLUGIN2()
!" group()#27*,(%+*#3"(73*)#(!"#*4-"#+2#(!"#$%&'"(#D+5#'3+7.#(!%)#,7)(+-#$%&'"(#)!+7/&#D"/+*'#(+0 -4,3+#(+#-4@"#(!"#./7'%*#4I4%/4D/"#(+ !"#$%&'($)0# !"#2%3)(#43'7-"*(#%)#(!"#*4-"#$"#$4*(#(+#'%I"
>2#(!"#*4-"#%)*K(#4/3"4&8 %*#7)"6 !"#$%&'($)#$%//#,3"4("#4#*"$#'3+7.#2+3#(!"#$%&'"(0 (!"#./7'%*X#(!"#)",+*+'7-"*(#%)#(!"#*4-"#+2#(!"#,/4))#(!4(#%-./"-"*()#%(0
!" .pro#2%/"#2+3#D7%/&%*'#(!"#./7'%*#/++@)#/%@"#(!%)B
QIcon IconEditorPlugin::icon() const
{
return QIcon(":/images/iconeditor.png");
} TEMPLATE = lib
CONFIG += designer plugin release
HEADERS = ../iconeditor/iconeditor.h \
iconeditorplugin.h
!" icon()#27*,(%+*#3"(73*)#(!"#%,+*#(+#7)"#(+#3".3")"*(#(!"#,7)(+-#$%&'"(#%* !"#$%&'($)K)#$%&'"( SOURCES = ../iconeditor/iconeditor.cpp \
D+50#J"3"6#$"#4))7-"#(!4(#(!" IconEditorPlugin#!4)#4*#4))+,%4("&#F(#3")+73,"#2%/"#$%(!#4#)7%(4D/" iconeditorplugin.cpp
"*(38#2+3#(!"#%,+*#"&%(+3#%-4'"0 RESOURCES = iconeditorplugin.qrc
DESTDIR = $(QTDIR)/plugins/designer
>*#(!"#.3+(",("&#)",(%+*#+2#(!"#,/4))6#$"#&",/43"#4//#(!" QWidget#"I"*(#!4*&/"3)#(!4(#$"#$4*(#(+
3"%-./"-"*(0
private:
void updateRubberBandRegion();
void refreshPixmap();
void drawGrid(QPainter *painter);
void drawCurves(QPainter *painter);
enum { Margin = 50 };
QToolButton *zoomInButton;
!"#7)"3#,4*#\++-#%*#3"."4("&/8#D8#&34$%*'#4#37DD"3#D4*&#-7/(%./"#(%-")6#\++-%*'#+7(#7)%*'#(!" QToolButton *zoomOutButton;
]++-#Y7(#D7((+*6#4*&#(!"*#\++-%*'#D4,@#%*#7)%*'#(!"#]++-#>*#D7((+*0# !"#]++-#>*#4*&#]++-#Y7( QMap<int, QVector<QPointF> > curveMap;
D7((+*)#4.."43#(!"#2%3)(#(%-"#(!"8#D",+-"#4I4%/4D/"6#)+#(!4(#(!"8#&+*K(#,/7(("3#(!"#&%)./48#%2#(!"#7)"3 QVector<PlotSettings> zoomStack;
&+")*K(#\++-#(!"#'34.!0 int curZoom;
bool rubberBandIsShown;
!" Plotter#$%&'"(#,4*#!+/&#(!"#&4(4#2+3#4*8#*7-D"3#+2#,73I")0#>(#4/)+#-4%*(4%*)#4#)(4,@#+2 QRect rubberBandRect;
QPixmap pixmap;
PlotSettings#+DV",()6#"4,!#+2#$!%,!#,+33").+*&)#(+#4#.43(%,7/43#\++-#/"I"/0
};
^"(K)#3"I%"$#(!"#,/4))6#)(43(%*'#$%(! plotter.hB
>*#(!"#.3%I4("#)",(%+*#+2#(!"#,/4))6#$"#&",/43"#4#2"$#27*,(%+*)#2+3#.4%*(%*'#(!"#$%&'"(6#4#,+*)(4*(6
4*&#)"I"34/#-"-D"3#I43%4D/")0# !" Margin#,+*)(4*(#%)#7)"&#(+#.3+I%&"#)+-"#).4,%*'#43+7*&#(!"
#ifndef PLOTTER_H
#define PLOTTER_H '34.!0
#include <QMap>
#include <QPixmap> G-+*'#(!"#-"-D"3#I43%4D/")#%) pixmap#+2#(8." QPixmap0# !%)#I43%4D/"#!+/&)#4#,+.8#+2#(!"#$!+/"
#include <QVector> $%&'"(K)#3"*&"3%*'6#%&"*(%,4/#(+#$!4(#%)#)!+$*#+*#),3""*0# !"#./+(#%)#4/$48)#&34$*#+*(+#(!%)#+22E
#include <QWidget> ),3""*#.%5-4.#2%3)(X#(!"*#(!"#.%5-4.#%)#,+.%"&#+*(+#(!"#$%&'"(0
class QToolButton;
class PlotSettings;
(!"-#$%(! std::#92+3#"54-./"6 floor()#%*)("4&#+2 std::floor()=0
class PlotSettings
{
public: Plotter::Plotter(QWidget *parent)
PlotSettings(); : QWidget(parent)
{
void scroll(int dx, int dy); setBackgroundRole(QPalette::Dark);
void adjust(); setAutoFillBackground(true);
double spanX() const { return maxX - minX; } setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
double spanY() const { return maxY - minY; } setFocusPolicy(Qt::StrongFocus);
rubberBandIsShown = false;
double minX;
double maxX; zoomInButton = new QToolButton(this);
int numXTicks; zoomInButton->setIcon(QIcon(":/images/zoomin.png"));
double minY; zoomInButton->adjustSize();
double maxY; connect(zoomInButton, SIGNAL(clicked()), this, SLOT(zoomIn()));
int numYTicks;
zoomOutButton = new QToolButton(this);
private: zoomOutButton->setIcon(QIcon(":/images/zoomout.png"));
static void adjustAxis(double &min, double &max, int &numTicks); zoomOutButton->adjustSize();
}; connect(zoomOutButton, SIGNAL(clicked()), this, SLOT(zoomOut()));
#endif
setPlotSettings(PlotSettings());
}
!" PlotSettings#,/4))#).",%2%")#(!"#34*'"#+2#(!" *#4*& +#45")#4*&#(!"#*7-D"3#+2#(%,@)#2+3#(!")"
45")0 Q%'73"#_0<#)!+$)#(!"#,+33").+*&"*,"#D"($""*#4 PlotSettings#+DV",(#4* Plotter#$%&'"(0
!" setBackgroundRole()#,4//#("//) QWidget#(+#7)"#(!"#C&43@C#,+-.+*"*(#+2#(!"#.4/"(("#4)#(!"#,+/+3#2+3
'"$()% *+8+ PlotSettings-. 1%19%) :2)"293%. "34)%*'#(!"#$%&'"(6#%*)("4&#+2#(!"#C$%*&+$C#,+-.+*"*(0# !%)#'%I")#F(#4#&"247/(#,+/+3#(!4(#%(#,4*#7)"
(+#2%//#4*8#*"$/8#3"I"4/"&#.%5"/)#$!"*#(!"#$%&'"(#%)#3")%\"&#(+#4#/43'"3#)%\"6#D"2+3" paintEvent()#"I"*
!4)#(!"#,!4*,"#(+#.4%*(#(!"#*"$#.%5"/)0#O"#4/)+#*""&#(+#,4// setAutoFillBackground(true)#(+#"*4D/"
(!%)#-",!4*%)-0#9?8#&"247/(6#,!%/&#$%&'"()#%*!"3%(#(!"#D4,@'3+7*+-#(!"%3#.43"*(#$%&'"(0=
!" setFocusPolicy(Qt::StrongFocus)#,4//#-4@")#(!"#$%&'"(#4,,".(#2+,7)#D8#,/%,@%*'#+3#D8#.3"))%*'
4D0#O!"*#(!" Plotter#!4)#2+,7)6#%(#$%//#3","%I"#"I"*()#2+3#@"8#.3"))")0# !" Plotter#$%&'"(
7*&"3)(4*&)#4#2"$#@"8)B#b#(+#\++-#%*X E#(+#\++-#+7(X#4*&#(!"#433+$#@"8)#(+#),3+//#7.6#&+$*6#/"2(6
4*%'!(0
a+$#/"(K)#3"I%"$#(!"#%-./"-"*(4(%+*#2%/"B
#include <QtGui>
#include <cmath>
#include "plotter.h"
O"#%*,/7&"#(!"#"5.",("&#!"4&"3#2%/")#4*&#%-.+3(#4//#(!" std#*4-").4,"K)#)8-D+/)#%*(+#(!"#'/+D4/
R(%//#%*#(!"#,+*)(37,(+36#$"#,3"4("#($+ QToolButton)6#"4,!#$%(!#4*#%,+*0# !")"#D7((+*)#4//+$#(!"#7)"3
*4-").4,"0# !%)#4//+$)#7)#(+#4,,"))#(!"#27*,(%+*)#(!4(#43"#&",/43"&#%* <cmath>#$%(!+7(#.3"2%5%*'
(+#\++-#%*#4*&#+7(0# !"#D7((+*K)#%,+*)#43"#)(+3"&#%*#4#3")+73,"#2%/"6#)+#4*8#4../%,4(%+*#(!4(#7)")#(!"
Plotter#$%&'"(#$%//#*""&#(!%)#"*(38#%*#%() .pro#2%/"B zoomInButton->show();
refreshPixmap();
}
RESOURCES = plotter.qrc }
O!"*#(!"#7)"3 -+I")#(!"#-+7)"#,73)+3#$!%/"#!+/&%*'#(!"#/"2(#D7((+*6#$"#2%3)(#,4//
updateRubberBandRegion()#(+#),!"&7/"#4#.4%*(#"I"*(#(+#3".4%*(#(!"#43"4#$!"3"#(!"#37DD"3#D4*&#$4)6
(!"*#$"#3",+-.7(" rubberBandRect#(+#4,,+7*(#2+3#(!"#-+7)"#-+I"6#4*%*4//8#$"#,4//
updateRubberBandRegion()#4#)",+*&#(%-"#(+#3".4%*(#(!"#43"4#$!"3"#(!"#37DD"3#D4*&#!4)#-+I"&#(+0
!%)#"22",(%I"/8#"34)")#(!"#37DD"3#D4**"&34$)#%(#4(#(!"#*"$#,++3&%*4(")0 '"$()% *+==+ B#C(.&"6$ A30&&%) /00)#"62&%. 26# D001"6$ "6 06 &7% )(99%)
926#
>2#(!"#7)"3#-+I")#(!"#-+7)"#7.$43&#+3#/"2($43&6#%(K)#/%@"/8#(!4( rubberBandRectK)#*+-%*4/#D+((+-E
3%'!(#,+3*"3#$%//#"*.#4D+I"#+3#(+#(!"#/"2(#+2#%()#(+.E/"2(#,+3*"30#>2#(!%)#+,,73)6#(!" QRect#$%//#!4I"#4 [View full size image]
O!""/#"I"*()#+,,73#$!"*#4#-+7)"#$!""/#%)#(73*"&0#e+)(#-%,"#+*/8#.3+I%&"#4#I"3(%,4/#$!""/6#D7(
)+-"#4/)+#!4I"#4#!+3%\+*(4/#$!""/0#F(#)7..+3()#D+(!#@%*&)#+2#$!""/0#O!""/#"I"*()#'+#(+#(!"#$%&'"(
(!4(#!4)#(!"#2+,7)0# !" delta()#27*,(%+*#3"(73*)#(!"#&%)(4*,"#(!"#$!""/#$4)#3+(4("&#%*#"%'!(!)#+2#4
&"'3""0#e%,"#(8.%,4//8#$+3@#%*#)(".)#+2#:_#&"'3"")0#J"3"6#$"#),3+//#D8#(!"#3"A7")("&#*7-D"3#+2#(%,@)
D8#-+&%28%*'#(!"#(+.-+)(#%("-#+*#(!"#\++-#)(4,@#4*.&4("#(!"#&%)./48#7)%*' refreshPixmap()0
!"#-+)(#,+--+*#7)"#+2#(!"#$!""/#-+7)"#%)#(+#),3+//#4#),3+//#D430#O!"*#$"#7)" QScrollArea
9,+I"3"&#%* L!4.("3#`=#(+#.3+I%&"#),3+//#D43)6 QScrollArea#!4*&/")#(!"#$!""/#-+7)"#"I"*()
47(+-4(%,4//86#)+#$"#&+*K(#*""&#(+#3"%-./"-"*( wheelEvent()#+73)"/I")0
!"*#$"#."32+3-#(!"#\++-0# !"#\++-#%)#4,!%"I"&#D8#.7)!%*'#(!"#*"$ PlotSettings#(!4(#$"#!4I"
V7)(#,4/,7/4("&#+*#(+.#+2#(!"#\++-#)(4,@#4*&#,4//%*' zoomIn()#(+#&+#(!"#V+D0 !%)#2%*%)!")#(!"#%-./"-"*(4(%+*#+2#(!"#"I"*(#!4*&/"3)0#a+$#/"(K)#3"I%"$#(!"#.3%I4("#27*,(%+*)0
!" refreshPixmap()#27*,(%+*#3"&34$)#(!"#./+(#+*(+#(!"#+22E),3""*#.%5-4.#4*.&4(")#(!"#&%)./480
O!"*#(!"#7)"3#.3"))")#4#@"8#4*&#(!" Plotter#$%&'"(#!4)#2+,7)6#(!" keyPress-Event()#27*,(%+*#%) O"#3")%\"#(!"#.%5-4.#(+#!4I"#(!"#)4-"#)%\"#4)#(!"#$%&'"(#4*%//#%(#$%(!#(!"#$%&'"(K)#"34)"#,+/+30
,4//"&0#O"#3"%-./"-"*(#%(#!"3"#(+#3").+*&#(+#)%5#@"8)B#b6 E6#1.6#Z+$*6#^"2(6#4*&#N%'!(0#>2#(!"#7)"3 !%)#,+/+3#%)#(!"#C&43@C#,+-.+*"*(#+2#(!"#.4/"(("6#D",47)"#+2#(!"#,4//#(+ setBackgroundRole()#%*#(!"
.3"))"#@"8#(!4(#$"#43"#*+(#!4*&/%*'6#$"#,4//#(!"#D4)" ,/4))#%-./"-"*(4(%+*0#Q+3#)%-./%,%(86#$" Plotter#,+*)(37,(+30#>2#(!"#D4,@'3+7*&#%)#4#*+*E)+/%&#D37)!6 QPixmap::fill()#*""&)#(+#@*+$#(!"
%'*+3"#(!"#R!%2(6#L(3/6#4*&#G/(#-+&%2%"3#@"8)6#$!%,!#43"#4I4%/4D/"#(!3+7'! QKeyEvent::modifiers()0 +22)"(#%*#(!"#$%&'"(#$!"3"#(!"#.%5-4.#$%//#"*.#(+#4/%'*#(!"#D37)!#.4(("3*#,+33",(/80#J"3"6#(!"
.%5-4.#,+33").+*&)#(+#(!"#"*(%3"#$%&'"(6#)+#$"#).",%28#.+)%(%+*#9d6#d=0
void Plotter::wheelEvent(QWheelEvent *event)
{ !"*#$"#,3"4("#4 QPainter#(+#&34$#+*#(!"#.%5-4.0# !" initFrom()#,4//#)"()#(!"#.4%*("3K)#."*6
int numDegrees = event->delta() / 8; D4,@'3+7*&6#4*+*(#(+#(!"#)4-"#+*")#4)#(!" Plotter#$%&'"(0#a"5(#$"#,4// drawGrid()#4*&
int numTicks = numDegrees / 15; drawCurves()#(+#."32+3-#(!"#&34$%*'0#G( (!"#"*&6#$"#,4// update()#(+#),!"&7/"#4#.4%*(#"I"*(#2+3#(!"
if (event->orientation() == Qt::Horizontal) { $!+/"#$%&'"(0# !"#.%5-4.#%)#,+.%"&#(+#(!"#$%&'"(#%*#(!" paintEvent()#27*,(%+*#9.0#:MP=0
zoomStack[curZoom].scroll(numTicks, 0);
} else {
zoomStack[curZoom].scroll(0, numTicks); void Plotter::drawGrid(QPainter *painter)
} {
QRect rect(Margin, Margin, width() - 2 * Margin, height() - 2 * Margin);
width() - 2 * Margin, height() - 2 * Margin); if (!rect.isValid())
if (!rect.isValid()) return;
return; painter->setClipRect(rect.adjusted(+1, +1, -1, -1));
PlotSettings settings = zoomStack[curZoom]; QMapIterator<int, QVector<QPointF> > i(curveMap);
QPen quiteDark = palette().dark().color().light(); while (i.hasNext()) {
QPen light = palette().light().color(); i.next();
for (int i = 0; i <= settings.numXTicks; ++i) { int id = i.key();
int x = rect.left() + (i * (rect.width() - 1) const QVector<QPointF> &data = i.value();
/ settings.numXTicks); QPolygonF polyline(data.count());
double label = settings.minX + (i * settings.spanX() for (int j = 0; j < data.count(); ++j) {
/ settings.numXTicks); double dx = data[j].x() - settings.minX;
painter->setPen(quiteDark); double dy = data[j].y() - settings.minY;
painter->drawLine(x, rect.top(), x, rect.bottom()); double x = rect.left() + (dx * (rect.width() - 1)
painter->setPen(light); / settings.spanX());
painter->drawLine(x, rect.bottom(), x, rect.bottom() + 5); double y = rect.bottom() - (dy * (rect.height() - 1)
painter->drawText(x - 50, rect.bottom() + 5, 100, 15, / settings.spanY());
Qt::AlignHCenter | Qt::AlignTop, polyline[j] = QPointF(x, y);
QString::number(label)); }
} painter->setPen(colorForIds[uint(id) % 6]);
for (int j = 0; j <= settings.numYTicks; ++j) { painter->drawPolyline(polyline);
int y = rect.bottom() - (j * (rect.height() - 1) }
/ settings.numYTicks); }
double label = settings.minY + (j * settings.spanY()
/ settings.numYTicks);
painter->setPen(quiteDark);
painter->drawLine(rect.left(), y, rect.right(), y); !" drawCurves()#27*,(%+*#&34$)#(!"#,73I")#+*#(+.#+2#(!"#'3%&0#O"#)(43(#D8#,4//%*' setClipRect()#(+
painter->setPen(light); )"(#(!" QPainterK)#,/%.#3"'%+*#(+#(!"#3",(4*'/"#(!4(#,+*(4%*)#(!"#,73I")#9"5,/7&%*'#(!"#-43'%*)#4*&
painter->drawLine(rect.left() - 5, y, rect.left(), y); (!"#234-"#43+7*&#(!"#'34.!=0 QPainter#$%//#(!"*#%'*+3"#&34$%*'#+."34(%+*)#+*#.%5"/)#+7()%&"#(!"
painter->drawText(rect.left() - Margin, y - 10, Margin - 5, 20, 43"40
Qt::AlignRight | Qt::AlignVCenter,
QString::number(label)); a"5(6#$"#%("34("#+I"3#4//#(!"#,73I")#7)%*'#4#f4I4E)(8/"#%("34(+36#4*+3#"4,!#,73I"6#$"#%("34("#+I"3
} %()#,+*)(%(7"*( QPointF)0# !" key()#27*,(%+*#'%I")#(!"#,73I"K)#>Z6#4*&#(!" value()#27*,(%+*#'%I")#(!"
painter->drawRect(rect.adjusted(0, 0, -1, -1));
,+33").+*&%*'#,73I"#&4(4#4) 4 QVector<QPointF>0# !"#%**"3 for#/++.#,+*I"3()#"4,! QPointF#23+-
}
./+(("3#,++3&%*4(")#(+#$%&'"(#,++3&%*4(")#4*&#)(+3")#(!"-#%*#(!" polyline#I43%4D/"0
Y*,"#$"#!4I"#,+*I"3("//#(!"#.+%*()#+2#4#,73I"#(+#$%&'"(#,++3&%*4(")6#$"#)"(#(!"#."*#,+/+3#2+3#(!"
!" drawGrid()#27*,(%+*#&34$)#(!"#'3%&#D"!%*&#(!"#,73I")#4*&#(!"#45")0# !"#43"4#+*#$!%,!#$"#&34$
,73I"#97)%*'#+*"#+2#4#)"(#+2#.3"&"2%*"&#,+/+3)=#4*&#,4// drawPolyline()#(+#&34$#4#/%*"#(!4(#'+")
(!"#'3%&#%)#).",%2%"&#D8 rect0#>2#(!"#$%&'"(#%)*K(#/43'"#"*+7'!#(+#4,,+--+&4("#(!"#'34.!6#$"#3"(73* (!3+7'!#4//#(!"#,73I"K)#.+%*()0
%--"&%4("/80
!%)#%)#(!"#,+-./"(" Plotter#,/4))0#G//#(!4(#3"-4%*)#43"#4#2"$#27*,(%+*)#%* PlotSettings0
!"#2%3)( for#/++.#&34$)#(!"#'3%&K)#I"3(%,4/#/%*")#4*&#(!"#(%,@)#4/+*'#(!" *#45%)0# !"#)",+*& for#/++.
&34$)#(!"#'3%&K)#!+3%\+*(4/#/%*")#4*&#(!"#(%,@)#4/+*'#(!" +#45%)0#G(#(!"#"*&6#$"#&34$#4#3",(4*'/"
4/+*'#(!"#-43'%*)0# !" drawText()#27*,(%+*#%)#7)"&#(+#&34$#(!"#*7-D"3)#,+33").+*&%*'#(+#(!"#(%,@ PlotSettings::PlotSettings()
-43@)#+*#D+(!#45")0 {
minX = 0.0;
!"#,4//)#(+ drawText()#!4I"#(!"#2+//+$%*'#)8*(45B maxX = 10.0;
numXTicks = 5;
minY = 0.0;
painter->drawText(x, y, width, height, alignment, text); maxY = 10.0;
numYTicks = 5;
}
!%)#4/'+3%(!-#$%//#'%I"#)7D+.(%-4/#3")7/()%*#)+-"#,4)")0#G#-+3"#)+.!%)(%,4("/'+3%(!-#%)
void PlotSettings::adjust() &"),3%D"&#%*#H47/#R0#J",@D"3(K)#43(%,/"#Ca%,"#a7-D"3)#2+3#[34.!#^4D"/)C#.7D/%)!"&#%* 0)12/&3%
{ 0$4%#9>R?a#dE:MEM<`:``EP=0
adjustAxis(minX, maxX, numXTicks);
adjustAxis(minY, maxY, numYTicks);
} !%)#,!4.("3#!4)#D3+7'!(#7)#(+#(!"#"*&#+2 H43(#>0#>(#!4)#"5./4%*"&#!+$#(+#,7)(+-%\"#4*#"5%)(%*'#F(
$%&'"(#4*&#!+$#(+#D7%/#$%&'"(#23+-#(!"#'3+7*.#7)%*' QWidget#4)#(!"#D4)"#,/4))0#O"#!4I"
4/3"4&8#)""*#!+$#(+#,+-.+)"#4#$%&'"(#23+-#"5%)(%*' $%&'"()#%* L!4.("3#M6#4*&#$"#$%//#"5./+3"#(!"
(!"-"#273(!"3#%* L!4.("3#`0
!" adjust()#27*,(%+*#%)#,4//"+- mouseReleaseEvent()#(+#3+7*&#(!" minX6 maxX6 minY6#4*& maxY
I4/7")#(+#C*%,"C#I4/7")#4*&#(+#&"("3-%*"#(!"#*7-D"3#+2#(%,@)#4..3+.3%4("#2+3#"4,!#45%)0# !"#.3%I4("
G(#(!%)#.+%*(6#$"#@*+$#"*+7'!#(+#$3%("#,+-./"("#[1>#4../%,4(%+*)#7)%*'#F(0#>* H43()#>>#4*& >>>6#$"
27*,(%+* adjustAxis()#&+")#%()#$+3@#+*"#45%)#4(#4#(%-"0
$%//#"5./+3"#F(#%*#'3"4("3#&".(!#)+#(!4(#$"#,4*#-4@"#27//#7)"#+2#F(K)#.+$"30
e+)(#+2#(!"#,+&"#%* adjustAxis()#)%-./8#4(("-.()#(+#&"("3-%*"#4*#4..3+.3%4("#I4/7"#2+3#(!"#%*("3I4/
D"($""*#($+#(%,@)#9(!"#C)(".C=0# +#+D(4%*#*%,"#*7-D"3)#4/+*'#(!"#45%)6#$"#-7)(#)"/",(#(!"#)(".#$%(!
,43"0#Q+3#"54-./"6#4#)(".#I4/7"#+2#P0<#$+7/&#/"4&#(+#4*#45%)#$%(!#-7/(%./")#+2#P0<6#$!%,!#%)#&%22%,7/(
2+3#."+./"#(+#3"/4("#(+0#Q+3#45")#/4D"/"&#%*#&",%-4/#*+(4(%+*6#C*%,"C#)(".#I4/7")#43"#*7-D"3)#+2#(!"
2+3-#:d(6#Mi:d(6#+3#_i:d(0
O"#)(43(#D8#,+-.7(%*'#(!"#C'3+))#)(".C6#4#@%*&#+2#-45%-7-#2+3#(!"#)(".#I4/7"0# !"*#$"#2%*&#(!"
,+33").+*&%*'#*7-D"3#+2#(!"#2+3-#:d (#(!4(#%)#)-4//"3#(!4*#+3#"A74/#(+#(!"#'3+))#)(".0#O"#&+#(!%)#D8
(4@%*'#(!"#&",%-4/#/+'43%(!-#+2#(!"#'3+))#)(".6#3+7*&%*'#(!4( I4/7"#&+$*#(+#4#$!+/"#*7-D"36#(!"*
34%)%*'#:d#(+#(!"#.+$"3#+2#(!%)#3+7*&"&#*7-D"30#Q+3#"54-./"6#%2#(!"#'3+))#)(".#%)#MP`6#$"#,+-.7("
/+'#MP`#j#M0PkMl:mX#(!"*#$"#3+7*&#%(#&+$*#(+#M#4*&#+D(4%*#:d M#j#:dd#4)#(!"#,4*&%&4("#)(".#I4/7"
+2#(!"#2+3-#:d(0
Y*,"#$"#!4I"#(!"#2%3)(#,4*&%&4("#)(".#I4/7"6#$"#,4*#7)"#%(#(+#,4/,7/4("#(!"#+(!"3#($+#,4*&%&4(")B
Mi:d(#4*&#_i:d(0#Q+3#(!"#"54-./"#4D+I"6#(!"#($+#+(!"3#,4*&%&4(")#43"#Mdd#4*&#_dd0# !"#_dd
,4*&%&4("#%)#/43'"3#(!4*#(!"#'3+))#)(".6#)+#$"#,4*K(#7)"#%(0#?7(#Mdd#%)#)-4//"3#(!4*#MP`6#)+#$"#7)"
Part II: Intermediate Qt Chapter 6. Layout Management
L!4.("3#`0 #^48+7(#e4*4'"-"*( • *+,&('"-.!"/&0'$!%"1("+"21)3
• 4!+56$0"*+,1.!%
• 478&!!$)%
L!4.("3#k0 #cI"*(#H3+,"))%*'
• 45)188&('"9)$+%
• #156"/&0'$!%"+(0":118;+)%
L!4.("3#<0 #MZ#4*&#PZ#[34.!%,) • <.8!&78$"#15.3$(!"=(!$)>+5$
>*#(!" FindFileDialog#,+*)(37,(+36#$"#)"(#(!"#2+3-K)#-%*%-7-#)%\"#(+#M`_#5#:ld#4*&#(!"#%*%(%4/#)%\"
FindFileDialog::FindFileDialog(QWidget *parent) (+#P`_#5#M;d0#>*#(!" resizeEvent()#!4*&/"36#$"#'%I"#4*8#"5(34#).4,"#(+#(!"#$%&'"()#(!4(#$"#$4*( (+
: QDialog(parent) '3+$0# !%)#"*)73")#(!4(#(!"#2+3-#),4/")#)-++(!/8#$!"*#(!"#7)"3#3")%\")#%(0
{
...
namedLabel->setGeometry(9, 9, 50, 25); '"$()% ,+F+ G%."D"6$ 2 )%."D293% #"230$
namedLineEdit->setGeometry(65, 9, 200, 25); [View full size image]
lookInLabel->setGeometry(9, 40, 50, 25);
lookInLineEdit->setGeometry(65, 40, 200, 25);
subfoldersCheckBox->setGeometry(9, 71, 256, 23);
tableWidget->setGeometry(9, 100, 256, 100);
messageLabel->setGeometry(9, 206, 256, 25);
findButton->setGeometry(271, 9, 85, 32);
stopButton->setGeometry(271, 47, 85, 32);
closeButton->setGeometry(271, 84, 85, 32);
helpButton->setGeometry(271, 199, 85, 32);
setWindowTitle(tr("Find Files or Folders"));
setFixedSize(365, 240);
}
f7)(#/%@"#4D)+/7("#.+)%(%+*%*'6#-4*74/#/48+7(#3"A7%3")#4#/+(#+2#!43&E,+&"&#,+*)(4*()#(+#D"#,4/,7/4("&
GD)+/7("#.+)%(%+*%*'#!4)#-4*8#&%)4&I4*(4'")B D8#(!"#.3+'34--"30#O3%(%*'#,+&"#/%@"#(!%)#%)#(%3")+-"6#").",%4//8#%2#(!"#&")%'*#,!4*'")0#G*&#(!"3"#%)
)(%//#(!"#3%)@#+2#("5(#(37*,4(%+*0#O"#,4*#4I+%&#(!%)#3%)@#D8#(4@%*'#4,,+7*(#+2#(!"#,!%/&#$%&'"()K#)%\"
• !"#7)"3#,4**+(#3")%\"#(!"#$%*&+$0 !%*()6#D7(#(!4(#$+7/&#,+-./%,4("#(!"#,+&"#"I"*#273(!"30
• R+-"#("5(#-48#D"#(37*,4("&#%2#(!"#7)"3#,!++)")#4*#7*7)74//8#/43'"#2+*(#+3#%2#(!"#4../%,4(%+*
%)#(34*)/4("&#%*(+#4*+(!"3#/4*'74'"0 !"#-+)(#,+*I"*%"*(#)+/7(%+*#2+3#/48%*'#+7(#$%&'"()#+*#4#2+3-#%)#(+#7)"#F(K)#/48+7(#-4*4'"3)0# !"
• !"#$%&'"()#-%'!(#!4I"#%*4..3+.3%4("#)%\")#2+3#)+-"#)(8/")0 /48+7(#-4*4'"3)#.3+I%&"#)"*)%D/"#&"247/()#2+3#"I"38#(8."#+2#$%&'"(#4*&#(4@"#%*(+#4,,+7*(#"4,!
• !"#.+)%(%+*)#4*&#)%\")#-7)(#D"#,4/,7/4("&#-4*74//80# !%)#%)#("&%+7)#4*&#"33+3E.3+*"6#4*& $%&'"(K)#)%\"#!%*(6#$!%,!#%*#(73*#(8.%,4//8#&"."*&)#+*#(!"#$%&'"(K)#2+*(6#)(8/"6#4*&#,+*("*()0#^48+7(
-4@")#-4%*("*4*,"#.4%*27/0 -4*4'"3)#4/)+#3").",(#-%*%-7-#4*&#-45%-7-#)%\")6#4*/(+-4(%,4//8#4&V7)(#(!"#/48+7(#%*
3").+*)"#(+#2+*(#,!4*'")6#,+*("*(#,!4*'")6#4*&#$%*&+$#3")%\%*'0
G*#4/("3*4(%I"#(+#4D)+/7("#.+)%(%+*%*'#%)#-4*74/#/48+7(0#O%(! -4*74/#/48+7(6#(!"#$%&'"()#43"#)(%//
'%I"*#4D)+/7("#.+)%(%+*)6#D7(#(!"%3#)%\")#43"#-4&"#.3+.+3(%+*4/#(+#(!"#)%\"#+2#(!"#$%*&+$#34(!"3#(!4* !"#(!3""#-+)(#%-.+3(4*(#/48+7(#-4*4'"3)#43" QHBoxLayout6 QVBoxLayout6#4*& QGridLayout0# !")"
D"%*'#"*(%3"/8#!43&E,+&"&0# !%)#,4*#D"#4,!%"I"&#D8#3"%-./"-"*(%*'#(!"#2+3-K) resizeEvent() ,/4))")#%*!"3%( QLayout6#$!%,!#.3+I%&")#(!"#D4)%,#234-"$+3@#2+3#/48+7()0#G//#(!3""#,/4))")#43"#27//8
27*,(%+*#(+#)"(#%()#,!%/& $%&'"()K#'"+-"(3%")B )7..+3("&#D8 !"#$%&'($)#4*&#,4*#4/)+#D"#7)"&#&%3",(/8#%*#,+&"0
J"3"K)#(!" FindFileDialog#,+&"#7)%*'#/48+7(#-4*4'"3)B
FindFileDialog::FindFileDialog(QWidget *parent)
: QDialog(parent)
{
... FindFileDialog::FindFileDialog(QWidget *parent)
setMinimumSize(265, 190); : QDialog(parent)
resize(365, 240); {
} ...
void FindFileDialog::resizeEvent(QResizeEvent * /* event */) QGridLayout *leftLayout = new QGridLayout;
{ leftLayout->addWidget(namedLabel, 0, 0);
int extraWidth = width() - minimumWidth(); leftLayout->addWidget(namedLineEdit, 0, 1);
int extraHeight = height() - minimumHeight(); leftLayout->addWidget(lookInLabel, 1, 0);
namedLabel->setGeometry(9, 9, 50, 25); leftLayout->addWidget(lookInLineEdit, 1, 1);
namedLineEdit->setGeometry(65, 9, 100 + extraWidth, 25); leftLayout->addWidget(subfoldersCheckBox, 2, 0, 1, 2);
lookInLabel->setGeometry(9, 40, 50, 25); leftLayout->addWidget(tableWidget, 3, 0, 1, 2);
lookInLineEdit->setGeometry(65, 40, 100 + extraWidth, 25); leftLayout->addWidget(messageLabel, 4, 0, 1, 2);
subfoldersCheckBox->setGeometry(9, 71, 156 + extraWidth, 23); QVBoxLayout *rightLayout = new QVBoxLayout;
tableWidget->setGeometry(9, 100, 156 + extraWidth, rightLayout->addWidget(findButton);
50 + extraHeight); rightLayout->addWidget(stopButton);
messageLabel->setGeometry(9, 156 + extraHeight, 156 + extraWidth, rightLayout->addWidget(closeButton);
25); rightLayout->addStretch();
findButton->setGeometry(171 + extraWidth, 9, 85, 32); rightLayout->addWidget(helpButton);
stopButton->setGeometry(171 + extraWidth, 47, 85, 32); QHBoxLayout *mainLayout = new QHBoxLayout;
closeButton->setGeometry(171 + extraWidth, 84, 85, 32); mainLayout->addLayout(leftLayout);
mainLayout->addLayout(rightLayout); )%(74(%+*0# !"#)4-"#4../%")#%2#$"#,4// hide()#+3 show()#+*#4#,!%/&#$%&'"(0#>2#4#,!%/&#$%&'"(K)#)%\"#!%*(
setLayout(mainLayout); ,!4*'")6#(!"#/48+7(#$%//#D"#47(+-4(%,4//8#3"&+*"6#(4@%*'#%*(+#4,,+7*(#(!"#*"$#)%\"#!%*(0#G/)+6#/48+7(
setWindowTitle(tr("Find Files or Folders")); -4*4'"3)#47(+-4(%,4//8#)"(#4#-%*%-7-#)%\"#2+3#(!"#2+3-#4)#4#$!+/"6#D4)"&#+*#(!"#2+3-K)#,!%/&
} $%&'"()K#-%*%-7-#)%\")#4*&#)%\"#!%*()0
>*#(!"#"54-./")#.3")"*("&#)+#2436#$"#!4I"#)%-./8#.7(#$%&'"()#%*(+#/48+7()#4*)"&#).4,"3#%("-)
!"#/48+7(#%)#!4*&/"&#D8#+*" QHBoxLayout6#+*" QGridLayout6#4*&#+*" QVBoxLayout0# !" QGridLayout 9)(3"(,!")=#(+#,+*)7-"#4*8#"5,"))#).4,"0#>*#)+-"#,4)")6#(!%)#%)*K(#)722%,%"*(#(+#-4@"#(!"#/48+7(#/++@
+*#(!"#/"2(#4*&#(!" QVBoxLayout#+*#(!"#3%'!(#43"#./4,"&#)%&"#D8#)%&"#D8#(!"#+7("3 QHBoxLayout0# !" "54,(/8#(!"#$48#$"#$4*(0#>*#(!")"#)%(74(%+*)6#$"#,4*#4&V7)(#(!"#/48+7(#D8#,!4*'%*'#(!"#)%\"#.+/%,%")
-43'%*#43+7*&#(!"#&%4/+'#4*&#(!"#).4,%*'#D"($""*#(!"#,!%/&#$%&'"()#43"#)"(#(+#&"247/(#I4/7")#D4)"& 4*&#)%\"#!%*()#+2#(!"#$%&'"()#D"%*'#/4%&#+7(0
+*#(!"#,733"*(#$%&'"(#)(8/"X#(!"8#,4*#D"#,!4*'")%*' QLayout::setMargin()#4*&
QLayout::setSpacing()0 G#$%&'"(K)#)%\"#.+/%,8#("//)#(!"#/48+7(#)8)("-#!+$#%(#)!+7/&#)(3"(,!#+3#)!3%*@0#F(#.3+I%&")#)"*)%D/"
&"247/(#)%\"#.+/%,%")#2+3#4//#%()#D7%/(E%*#$%&'"()6#D7(#)%*,"#*+#)%*'/"#&"247/(#,4*#4,,+7*(#2+3#"I"38
!"#)4-"#&%4/+'#,+7/&#D"#,3"4("&#I%)74//8#%* !"#$%&'($)#D8#./4,%*'#(!"#,!%/&#$%&'"()#%*#(!"%3 .+))%D/"#/48+7(6#%(#%)#)(%//#,+--+*#2+3#&"I"/+."3)#(+#,!4*'"#(!"#)%\"#.+/%,%")#2+3#+*"#+3#($+#$%&'"()
4..3+5%-4("#.+)%(%+*)X#)"/",(%*'#(!+)"#(!4(#*""&#(+#D"#/4%&#+7(#(+'"(!"3X#4*&#,/%,@%*'#Q+3-p^48#Y7( +*#4#2+3-0#G QSizePolicy#!4)#D+(!#4#!+3%\+*(4/#4*#I"3(%,4/#,+-.+*"*(0 J"3"#43"#(!"#-+)(#7)"27/
J+3%\+*(4//86#Q+3-p^48#Y7(#S"3(%,4//86#+3#Q+3-p^48#Y7(#%*#4#[3%&0#O"#7)"&#(!%)#4..3+4,!#%* L!4.("3 I4/7")B
M#2+3 ,3"4(%*'#(!"#R.3"4&)!""(#4../%,4(%+*K)#[+E(+EL"//#4*&#R+3(#&%4/+')0
• Fixed#-"4*)#(!4(#(!"#$%&'"(#,4**+(#'3+$#+3#)!3%*@0# !"#$%&'"(#4/$48)#)(48)#4(#(!"#)%\"#+2#%()
'"$()% ,+H+ E7% '"6# '"3% #"230$-. 32I0(& )%\"#!%*(0
• Minimum#-"4*)#(!4(#(!"#$%&'"(K)#)%\"#!%*(#%)#%()#-%*%-7-#)%\"0# !"#$%&'"(#,4**+(#)!3%*@
[View full size image]
D"/+$#(!"#)%\"#!%*(6#D7(#%(#,4*#'3+$#(+#2%//#4I4%/4D/"#).4,"#%2#*","))4380
• Maximum#-"4*)#(!4(#(!"#$%&'"(K)#)%\"#!%*(#%)#%()#-45%-7-#)%\"0# !"#$%&'"(#,4*#D"#)!37*@
&+$*#(+#%()#-%*%-7-#)%\"#!%*(0
• Preferred#-"4*)#(!4(#(!"#$%&'"(K)#)%\"#!%*(#%)#%()#.3"2"33"&#)%\"6#D7(#(!4(#(!"#$%&'"(#,4*#)(%//
)!3%*@#+3#'3+$#%2#*","))4380
• Expanding#-"4*)#(!4(#(!"#$%&'"(#,4*#)!3%*@#+3#'3+$#4*&#(!4(#%(#%)#").",%4//8#$%//%*'#(+#'3+$0
Q%'73"#`0;#)7--43%\")#(!"#-"4*%*'#+2#(!"#&%22"3"*(#)%\"#.+/%,%")6#7)%*'#4 QLabel#)!+$%*'#(!"#("5(
CR+-"# "5(C#4)#4*#"54-./"0
G*&#%2#(!%)#%)*K(#)722%,%"*(6#$"#,4*#4/$48)#&"3%I"#23+-#(!"#,!%/&#$%&'"(K)#,/4))#4*"%-./"-"*(
sizeHint()#(+#+D(4%*#(!"#)%\"#!%*(#$"#*""&0
Stacked Layouts
!" QStackedLayout#,/4))#/48)#+7(#4 )"(#+2#,!%/&#$%&'"()6#+3#C.4'")C6#4*&#)!+$)#+*/8#+*"#4(#4#(%-"6
!%&%*'#(!"#+(!"3)#23+-#(!"#7)"30# !" QStackedLayout#%()"/2#%)#%*I%)%D/"#4*&#.3+I%&")#*+#%*(3%*)%,#-"4*)
2+3#(!"#7)"3#(+#,!4*'"#.4'"0# !"#)-4//#433+$)#4*&#(!"#&43@#'348#234-"#%* Q%'73"#`0_#43"#.3+I%&"&#D8
!"#$%&'($)#(+#-4@"#(!"#/48+7(#"4)%"3#(+#&")%'*#$%(!0#Q+3#,+*I"*%"*,"6#F(#4/)+#%*,/7&")
QStackedWidget6#$!%,!#.3+I%&")#4 QWidget#$%(!#4#D7%/(E%* QStackedLayout0
;/(+'#542"#7!4'#%("#%5'/#8"(C#"%'C#7/#3("%7"#*'4)& !"#$%&'($)A
D1 E("%7"#%#)"6#./(+#,%'"-#/)#7!"#FG4%5/&F#/(#7!"#FB4-&"7F#7"+$5%7"1
H1 I--#% QListWidget#%)-#% QStackedWidget#7/#7!"#./(+1
J1 ;455#"%3!#$%&"#647!#3!45-#64-&"7'#%)-#5%C/*7'1
K /#3("%7"#%#)"6#$%&"9#(4&!7L35432#%)-#3!//'"#M)'"(7#:%&"N#7/#'6473!#$%&"'9#35432#7!"#74)C#5".7
!"#$%&"'#%("#)*+,"("-#.(/+#01# /#+%2"#%#'$"34.43#3!45-#64-&"7#84'4,5"9#6"#3%)#3%55 /(#(4&!7#%((/6#5/3%7"-#%7#7!"#7/$L(4&!7#/.#7!" QStackedWidget1O
setCurrentIndex()#647!#%#$%&"#)*+,"(1# !"#$%&"#)*+,"(#./(#%#3!45-#64-&"7#4'#%8%45%,5"#*'4)&
indexOf()1 P1 Q%C#7!"#64-&"7'#/*7#'4-"#,C#'4-"#*'4)&#%#!/(4R/)7%5#5%C/*71
S1 E/))"37#7!"#54'7#64-&"7@' currentRowChanged(int)#'4&)%5#7/#7!"#'7%32"-#64-&"7@'
!"#:("."(")3"'#-4%5/&#'!/6)#4) ;4&*("#<1<#4'#%)#"=%+$5"#7!%7#*'"' QStacked-Layout1# !"#-4%5/& setCurrentIndex(int)#'5/71
3/)'4'7'#/.#% QListWidget#/)#7!"#5".7#%)-#% QStackedLayout#/)#7!"#(4&!71#>%3!#47"+#4)#7!" QListWidget <1 T"7#7!"#8%5*"#/.#7!"#54'7#64-&"7@' currentRow#$(/$"(7C#7/#01
3/(("'$/)-'#7/#%#-4.."(")7#$%&"#4)#7!" QStackedLayout1#?"("@'#7!"#("5"8%)7#3/-"#.(/+#7!"#-4%5/&@'
3/)'7(*37/(A T4)3"#6"#!%8"#4+$5"+")7"-#$%&"#'6473!4)&#*'4)&#$("-".4)"-#'4&)%5'#%)-#'5/7'9#7!"#-4%5/ᤷ#"=!4,47
7!"#3/(("37#,"!%84/( 6!")#$("84"6"-#4) !"#$%&'($)1
PreferenceDialog::PreferenceDialog(QWidget *parent)
: QDialog(parent) Splitters
{
... I QSplitter#4'#%#64-&"7#7!%7#3/)7%4)'#/7!"(#64-&"7'1# !"#64-&"7'#4)#%#'$5477"(#%("#'"$%(%7"-#,C
listWidget = new QListWidget;
'$5477"(#!%)-5"'1#U'"('#3%)#3!%)&"#7!"#'4R"'#/.#%#'$5477"(@'#3!45-#64-&"7'#,C#-(%&&4)!"#!%)-5"'1
listWidget->addItem(tr("Appearance"));
listWidget->addItem(tr("Web Browser")); T$5477"('#3%)#/.7")#,"#*'"-#%'#%)#%57"()%748"#7/#5%C/*7#+%)%&"('9#7/#&48"#+/("#3/)7(/5#7/#7!"#*'"(1
listWidget->addItem(tr("Mail & News"));
listWidget->addItem(tr("Advanced")); !"#3!45-#64-&"7'#/.#% QSplitter#%("#%*7/+%743%55C#$5%3"-#'4-"#,C#'4-"#K/(#/)"#,"5/6#7!"#/7!"(O#4)
stackedLayout = new QStackedLayout; 7!"#/(-"(#4)#6!43!#7!"C#%("#3("%7"-9#647!#'$5477"(#,%('#,"76"")#%-V%3")7#64-&"7'1#?"("@'#7!"#3/-"#./(
stackedLayout->addWidget(appearancePage); 3("%74)!"#64)-/6#-"$437"-#4) ;4&*("#<1WA
stackedLayout->addWidget(webBrowserPage);
stackedLayout->addWidget(mailAndNewsPage);
stackedLayout->addWidget(advancedPage); int main(int argc, char *argv[])
connect(listWidget, SIGNAL(currentRowChanged(int)), {
stackedLayout, SLOT(setCurrentIndex(int))); QApplication app(argc, argv);
... QTextEdit *editor1 = new QTextEdit;
listWidget->setCurrentRow(0); QTextEdit *editor2 = new QTextEdit;
} QTextEdit *editor3 = new QTextEdit;
QSplitter splitter(Qt::Horizontal);
splitter.addWidget(editor1);
splitter.addWidget(editor2);
splitter.addWidget(editor3);
...
splitter.show();
return app.exec();
}
!"#$%&'(7(&)1%&8,6!00%$&-,,6!4-0!+3
[View full size image]
!"#$%&'(;(&)1%&<-!6&=6!%30&-,,6!4-0!+3&+3&<-4&>8&?
I.7"(#3("%74)!"#7!(""#64-&"7'#7!%7#6"#6%)7#7/#-4'$5%C9#6"#3("%7"#%#8"(743%5#'$5477"(9 rightSplitter9
[View full size image] %)-#%--#7!"#76/#64-&"7'#6"#6%)7#/)#7!"#(4&!71# !")#6"#3("%7"#%#!/(4R/)7%5#'$5477"(9 mainSplitter9
%)-#%--#7!"#64-&"7#6"#6%)7#47#7/#-4'$5%C#/)#7!"#5".7#%)- rightSplitter#6!/'"#64-&"7'#6"#6%)7
'!/6)#/)#7!"#(4&!71#B"#+%2" mainSplitter#7!" QMainWindow@'#3")7(%5#64-&"71
B!")#7!"#*'"(#("'4R"'#%#64)-/69 QSplitter#)/(+%55C#-4'7(4,*7"'#7!"#'$%3"#'/#7!%7#7!"#("5%748"#'4R"'
/.#7!"#3!45-#64-&"7'#'7%C#7!"#'%+"1#M)#7!"#X%45#E54")7#"=%+$5"9#6"#-/)@7#6%)7#7!4'#,"!%84/(N#4)'7"%-9
6"#6%)7#7!" QtreeWidget#%)-#7!" QTableWidget#7/#2""$#7!"4(#'4R"'#%)-#6"#6%)7#7/#&48"#%)C#"=7(%
'$%3"#7/#7!" QTextEdit1# !4'#4'#%3!4"8"-#,C#7!"#76/ setStretchFactor()#3%55'1# !"#.4('7#%(&*+")7#4'
7!"#0L,%'"-#4)-"=#/.#7!"#'$5477"(@'#3!45-#64-&"79#%)-#7!"#'"3/)-#%(&*+")7#4'#7!"#'7("73!#.%37/(#6"
6%)7#7/#'"7N#7!"#-".%*57#4'#01
!"#$%&'(@A(&)1%&<-!6&=6!%30:.&.,6!00%$&!35%B!3"
Scrolling Areas
!" QScrollArea#35%''#$(/84-"'#%#'3(/55%,5"#84"6$/(7#%)-#76/#'3(/55#,%('1#M.#6"#6%)7#7/#%--#'3(/55
,%(' 7/#%#64-&"79#47#4'#+*3!#'4+$5"(#7/#*'"#% QScrollArea#7!%)#7/#4)'7%)74%7"#/*(#/6) QScrollBar'
%)-#4+$5"+")7#7!"#'3(/554)&#.*)374/)%547C#/*('"58"'1
!"#$%&'(@@( QScrollArea:.&4+3.0!0#%30&*!5"%0.
B!")#7!"#%$$543%74/)#4'#'7%(7"-9 QSplitter#&48"'#7!"#3!45-#64-&"7'#%$$(/$(4%7"#'4R"'#,%'"-#/)#7!"4(
4)474%5#'4R"'#K/(#,%'"-#/)#7!"4(#'4R"#!4)7#4.#)/#4)474%5#'4R"#4'#'$"34.4"-O1#B"#3%)#+/8"#7!"#'$5477"(
!%)-5"'#$(/&(%++%743%55C#,C#3%554)& QSplitter::setSizes()1# !" QSplitter#35%''#%5'/#$(/84-"'#%
+"%)'#/.#'%84)&#%)-#("'7/(4)/'#'7%7"#7!"#)"=7#74+"#7!"#%$$543%74/)#4'#(*)1#?"("@'#7!"
writeSettings()#.*)374/)#7!%7#'%8"'#7!"#X%45#E54")7@'#'"774)&'A !"#6%C#7/#*'" QScrollArea#4'#7/#3%55 setWidget()#647!#7!"#64-&"7#6"#6%)7#7/#%--#'3(/55#,%('#7/1
QScrollArea#%*7/+%743%55C#("$%(")7'#7!"#64-&"7#7/#+%2"#47#%#3!45-#/.#7!"#84"6$/(7#K%33"''4,5"
7!(/*&! QScrollArea::viewport()O#4.#47#4')@7#%5("%-C1#;/(#"=%+$5"9#4.#6"#6%)7#'3(/55#,%('#%(/*)-#7!"
void MailClient::writeSettings() IconEditor#64-&"7#6"#-"8"5/$"-#4) E!%$7"(#S9#6"#3%)#6(47"#7!4'A
{
QSettings settings("Software Inc.", "Mail Client");
settings.beginGroup("mainWindow"); int main(int argc, char *argv[])
settings.setValue("size", size()); {
settings.setValue("mainSplitter", mainSplitter->saveState()); QApplication app(argc, argv);
settings.setValue("rightSplitter", rightSplitter->saveState()); IconEditor *iconEditor = new IconEditor;
settings.endGroup(); iconEditor->setIconImage(QImage(":/images/mouse.png"));
} QScrollArea scrollArea;
scrollArea.setWidget(iconEditor);
scrollArea.viewport()->setBackgroundRole(QPalette::Dark);
?"("@'#7!"#3/(("'$/)-4)& readSettings()#.*)374/)A scrollArea.viewport()->setAutoFillBackground(true);
scrollArea.setWindowTitle(QObject::tr("Icon Editor"));
scrollArea.show();
return app.exec();
void MailClient::readSettings() }
{
QSettings settings("Software Inc.", "Mail Client");
settings.beginGroup("mainWindow");
resize(settings.value("size", QSize(480, 360)).toSize()); !" QScrollArea#$("'")7'#7!"#64-&"7#%7#47'#3*((")7#'4R"#/(#*'"'#7!"#'4R"#!4)7#4.#7!"#64-&"7#!%')@7#,"")
mainSplitter->restoreState( ("'4R"-#C"71#]C#3%554)& setWidgetResizable(true)9#6"#3%)#7"55 QScrollArea#7/#%*7/+%743%55C#("'4R"#7!"
settings.value("mainSplitter").toByteArray()); 64-&"7#7/#7%2"#%-8%)7%&"#/.#%)C#"=7(%#'$%3"#,"C/)-#47'#'4R"#!4)71
rightSplitter->restoreState(
settings.value("rightSplitter").toByteArray());
]C#-".%*579#7!"#'3(/55#,%('#%("#/)5C#-4'$5%C"-#6!")#7!"#84"6$/(7#4'#'+%55"(#7!%)#7!"#3!45-#64-&"71#B"
settings.endGroup();
} 3%)#./(3"#7!"#'3(/55#,%('#7/ %56%C'#,"#'!/6)#,C#'"774)&#'3(/55#,%(#$/5434"'A
scrollArea.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
QSplitter#4'#.*55C#'*$$/(7"-#,C !"#$%&'($)1# /#$*7#64-&"7'#4)7/#%#'$5477"(9#$5%3"#7!"#3!45-#64-&"7' scrollArea.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
%$$(/=4+%7"5C#4)#7!"4(#-"'4("-#$/'474/)'9#'"5"37#7!"+9#%)-#35432#;/(+ZQ%C#[*7#?/(4R/)7%55C#4)#T$5477"(
/(#;/(+ZQ%C#[*7#\"(743%55C#4)#T$5477"(1
!"#$%&'(@C(&D%.!E!3"&- QScrollArea
>8"(C#-/32#64-&"7#!%'#47'#/6)#7475"#,%(9#"8")#6!")#47#4'#-/32"-1#U'"('#3%)#+/8"#-/32#64)-/6'#.(/+
/)"#-/32#%("%#7/#%)/7!"(#,C#-(%&&4)!"#7475"#,%(1# !"C#3%)#%5'/#-"7%3!#%#-/32#64)-/6#.(/+#%)
%("%#%)-#5"7#7!"#-/32#64)-/6#.5/%7#%'#%)#4)-"$")-")7#64)-/6#,C#-(%&&4)!"#-/32#64)-/6#/*7'4-"
/.#%)C#-/32#%("%1#;(""L.5/%74)&#-/32#64)-/6'#%("#%56%C'#F/)#7/$F#/.#7!"4(#+%4)#64)-/61#U'"('#3%)
35/'"#% QDockWidget#,C#354324)!"#35/'"#,*77/)#4)#7!"#64-&"7@'#7475"#,%(1#I)C#3/+,4)%74/)#/.#7!"'"
."%7*("'#3%)#,"#-4'%,5"-#,C#3%554)& QDockWidget::setFeatures()1
M)#"%(54"(#8"('4/)'#/.#^79#7//5,%('#6"("#7("%7"-#542"#-/32#64-&"7'#%)-#'!%("-#7!"#'%+"#-/32#%("%'1
T7%(74)ʇ!#^7#P9#7//5,%('#/33*$C#7!"4(#/6)#%("%'#%(/*)-#7!"#3")7(%5#64-&"7#K%'#'!/6)#4) ;4&*("
<1DPO#%)-#3%)@7#,"#*)-/32"-1#M.#%#.5/%74)//5,%(#4'#("_*4("-9#6"#3%)#'4+$5C#$*7#47#4)'4-"#%
QDockWindow1
!"#$%&'(@I( QMainWindow:.&5+4H&-35&0++6J-$&-$%-.
!"#$%&'(@F(&G QMainWindow&*!01&-&5+4H&*!5"%0
[View full size image]
!"#3/()"('#4)-43%7"-#647!#-/77"-#54)"'#3%)#,"5/)/#"47!"(#/.#7!"4(#76/#%-V/4)4)&#-/32#%("%'1#;/(
"=%+$5"9#6"#3/*5-#+%2"#7!"#7/$L5".7#3/()"(#,"5/)/#7!"#5".7#-/32#%("%#,C#3%554)&
QMainWindow::setCorner(Qt::TopLeftCorner, Qt:: LeftDockWidgetArea)1
!"#./55/64)/-"#')4$$"7#'!/6'#!/6#7/#6(%$#%)#"=4'74)@-&"7#K4)#7!4'#3%'"9#% QtreeWidgetO#4)#%
QDockWidget#%)-#4)'"(7#47#4)7/#7!"#(4&!7#-/32#%("%A
| Qt::BottomToolBarArea);
addToolBar(fontToolBar);
M.#6"#6%)7#7/#'%8"#7!"#$/'474/)#/.#%55#7!"#-/32#64-&"7'#%)-#7//5,%('#'/#7!%7#6"#3%)#("'7/("#7!"+#7!"
)"=7#74+"#7!"#%$$543%74/)#4'#(*)9#6"#3%)#6(47"#3/-"#7!%7#4'#'4+45%(#7/#7!"#3/-"#6"#*'"-#7/#'%8"#%
QSplitter@'#'7%7"9#*'4)& QMainWindow@' saveState()#%)- restoreState()#.*)374/)'A
void MainWindow::writeSettings()
{
QSettings settings("Software Inc.", "Icon Editor");
settings.beginGroup("mainWindow");
settings.setValue("size", size());
settings.setValue("state", saveState());
settings.endGroup();
}
void MainWindow::readSettings()
{
QSettings settings("Software Inc.", "Icon Editor");
settings.beginGroup("mainWindow");
resize(settings.value("size").toSize());
restoreState(settings.value("state").toByteArray());
settings.endGroup();
}
MainWindow::MainWindow()
{ void MainWindow::open()
workspace = new QWorkspace; {
setCentralWidget(workspace); Editor *editor = createEditor();
connect(workspace, SIGNAL(windowActivated(QWidget *)), if (editor->open()) {
this, SLOT(updateMenus())); editor->show();
createActions(); } else {
createMenus(); editor->close();
createToolBars(); }
createStatusBar(); }
setWindowTitle(tr("MDI Editor"));
setWindowIcon(QPixmap(":/images/icon.png"));
} !" open()#.*)374/)#3/(("'$/)-'#7/#;45"Z[$")1#M7#3("%7"'#%) Editor#./(#7!"#)"6#-/3*+")7#%)-#3%55'
open()#/)#7!" Editor1#M7#+%2"'#+/("#'")'"#7/#4+$5"+")7#7!"#.45"#/$"(%74/)'#4)#7!" Editor#35%''#7!%)
4)#7!" MainWindow#35%''9#,"3%*'"#"%3! Editor#)""-'#7/#+%4)7%4)#47'#/6)#4)-"$")-")7#'7%7"1
M)#7!" MainWindow#3/)'7(*37/(9#6"#3("%7"#% QWorkspace#64-&"7#%)-#+%2"#47#7!"#3")7(%5#64-&"71#B"
3/))"37#7!" QWorkspace@' windowActivated()#'4&)%5#7/#7!"#'5/7#6"#6455#*'"#7/#2""$#7!"#64)-/6#+")* M.#7!" open()#.%45'9#6"#'4+$5C#35/'"#7!"#"-47/(#'4)3"#7!"#*'"(#6455#!%8"#%5("%-C#,"")#)/74.4"-#/.#7!"
*$#7/#-%7"1 "((/(1#B"#-/)@7#)""-#7/#"=$543475C#-"5"7"#7!" Editor#/,V"37#/*('"58"'N#7!4'#4'#-/)"#%*7/+%743%55C#,C
Editor#7!(/*&!#7!" Qt::WA_DeleteOn-Close#64-&"7#%77(4,*7"9#6!43!#4'#'"7#4)#7!" Editor#3/)'7(*37/(1
void MainWindow::newFile()
{ void MainWindow::save()
Editor *editor = createEditor(); {
editor->newFile(); if (activeEditor())
editor->show(); activeEditor()->save();
} }
;4('79#6"#3("%7"#% QAction#("$("'")74)!"#"-47/(#4)#7!"#%$$543%74/)@'#B4)-/6#+")*#%)-#3/))"37#7!%7
%374/)#7/#7!" show()#%)- setFocus()#'5/7'1
!" save()#.*)374/)#*'"'#7!" isUntitled#8%(4%,5"#7/#-"7"(+4)"#6!"7!"(#47#'!/*5-#3%55 saveFile()#/(
saveAs()1
T4)3"#6"#%55/6#*'"('#7/#3("%7"#%)C#)*+,"(#/.#"-47/(#64)-/6'9#6"#+*'7#+%2"#'/+"#$(/84'4/)#./(
)%+4)!"+#'/#7!%7#7!"C#3%)#,"#-4'74)&*4'!"-#,"./("#7!"C#!%8"#,"")#'%8"-#./(#7!"#.4('7#74+"1#[)"
3/++/)#6%C#/.#!%)-54)!4'#4'#7/#%55/3%7"#)%+"'#7!%7#4)35*-"#%#)*+,"(#K./(#"=%+$5"9 void Editor::closeEvent(QCloseEvent *event)
document1.txtO1#B"#*'"#7!" isUntitled#8%(4%,5"#7/#-4'74)&*4'!#,"76"")#)%+"'#'*$$54"-#,C#7!"#*'"( {
%)-#)%+"'#6"#!%8"#3("%7"-#$(/&(%++%743%55C1 if (okToContinue()) {
event->accept();
B"#3/))"37#7!"#7"=7#-/3*+")7@' contentsChanged()#'4&)%5#7/#7!"#$(48%7" documentWasModified()#'5/71 } else {
!4'#'5/7#'4+$5C#3%55' setWindowModified(true)1 event->ignore();
}
}
;4)%55C9#6"#'"7#7!" Qt::WA_DeleteOnClose#%77(4,*7"#7/#$("8")7#+"+/(C#5"%2'#6!")#7!"#*'"(#35/'"'#%)
Editor#64)-/61
M.#7!"#74+"(#"8")7#4')@7#./(#7!"#74+"(#6"#%("#4)7"("'7"-#4)9#6"#$%''#47#/)#7/#/*(#,%'"#35%''1
!" sizeHint()#.*)374/)#("7*()'#7!"#'$%3"#)""-"-#,C#7!"#7"=7#%'#7!"#64-&"7@'#4-"%5#'4R"1
QWidget::fontMetrics()#("7*()'#% QFontMetrics#/,V"37#7!%7#3%)#,"#_*"(4"-#7/#/,7%4)#4)./(+%74/)
("5%74)/#7!"#64-&"7@'#./)71#M)#7!4'#3%'"9#6"#%'2#./(#7!"#'4R"#("_*4("-#,C#7!"#&48")#7"=71#K !"#.4('7 void Ticker::hideEvent(QHideEvent * /* event */)
%(&*+")7#7/ QFontMetrics::size()#4'#%#.5%!%7#4')@7#)""-"-#./(#'4+$5"#'7(4)&'9#'/#6"#V*'7#$%''#01O {
killTimer(myTimerId);
}
void Ticker::paintEvent(QPaintEvent * /* event */)
{
QPainter painter(this); !" hideEvent()#.*)374/)#3%55' QObject::killTimer()#7/#'7/$#7!"#74+"(1
int textWidth = fontMetrics().width(text());
if (textWidth < 1)
return; 4+"(#"8")7'#%("#5/6#5"8"59#%)-#4.#6"#)""-#+*574$5"#74+"('9#47#3%)#,"3/+"#3*+,"('/+"#7/#2""$#7(%32
int x = -offset; /.#%55#7!"#74+"(#MG'1#M)#'*3!#'47*%74/)'9#47#4'#*'*%55C#"%'4"(#7/#3("%7"#% QTimer#/,V"37#./(#"%3!#74+"(1
while (x < width()) { QTimer#"+47'#7!" timeout()#'4&)%5#%7#"%3!#74+"#4)7"(8%51 QTimer#%5'/#$(/84-"'#%#3/)8")4")7#4)7"(.%3"
painter.drawText(x, 0, textWidth, height(), ./(#'4)&5"L'!/7#74+"('#K74+"('#7!%7#74+"#/*7#V*'7#/)3"O1
Qt::AlignLeft | Qt::AlignVCenter, text());
x += textWidth;
}
}
!4'#%$$(/%3!#!%'#/)"#+%4)#-4'%-8%)7%&"A#M.#6"#*'"#'"8"(%5#-4.."(")7#24)-'#/.#64-&"7'#4)#7!"#./(+ ^7#/.."('#.48"#5"8"5'#%7#6!43!#"8")7'#3%)#,"#$(/3"''"-#%)-#.457"("-A
K./(#"=%+$5"9 QComboBox"'#%)- QSpinBox"'O9#6"#+*'7#%5'/#'*,35%''#7!"+#7/#+%2"#7!"+#"=!4,47#7!"
'%+"#,"!%84/(1#I#,"77"(#'/5*74/)#4'#7/#+%2" CustomerInfoDialog#+/)47/(#47'#3!45-#64-&"7'@#2"C#$("'' D1 R%&4-3&$%!L,6%L%30&-&.,%4!/!4&%P%30&1-356%$(
"8")7'#%)-#4+$5"+")7#7!"#("_*4("-#,"!%84/(#4)#7!"#+/)47/(4)/-"1# !4'#3%)#,"#%3!4"8"-#*'4)&
"8")7#.457"('1#T"774)&#*$#%)#"8")7#.457"(#4)8/58"'#76/#'7"$'A j"4+$5"+")74)&#"8")7#!%)-5"('#'*3!#%' mousePressEvent()9 keyPress-Event()9#%)-
paintEvent()#4'#,C#.%(#7!"#+/'7#3/++/)#6%C#7/#$(/3"''#"8")7'1 B"#!%8"#%5("%-C#'"")#+%)C
@( j"&4'7"(#7!"#+/)47/(4)&#/,V"37#647!#7!"#7%(&"7#/,V"37#,C#3%554)& install-EventFilter()#/)#7!" "=%+$5"'#/.#7!4'1
7%(&"71
H1 R%&4-3&$%!L,6%L%30 S>JT%40UU%P%30VW(
C( ?%)-5"#7!"#7%(&"7#/,V"37@'#"8")7'#4)#7!"#+/)47/(@' eventFilter()#.*)374/)1
]C#("4+$5"+")74)!" event()#.*)374/)9#6"#3%)#$(/3"''#"8")7'#,"./("#7!"C#("%3!#7!"#'$"34.43
"8")7#!%)-5"('1# !4'#%$$(/%3!#4'#+/'75C#)""-"-#7/#/8"((4-"#7!"#-".%*57#+"%)4)&#/.#7!"# %,
I#&//-#$5%3"#7/#("&4'7"(#7!"#+/)47/(4)&#/,V"37#4'#4)#7!" CustomerInfoDialog#3/)'7(*37/(A 2"C9#%'#'!/6)#"%(54"(#K$1#D<PO1# !4'#4'#%5'/#*'"-#7/#!%)-5"#(%("#7C$"'#/.#"8")7#./(#6!43!#)/
'$"34.43#"8")7#!%)-5"(#"=4'7'#K./(#"=%+$5"9 QEvent::HoverEnterO1#B!")#6"#("4+$5"+")7
event()9#6"#+*'7#3%55#7!"#,%'"#35%''@' event()#.*)374/)#./(#!%)-54)!"#3%'"'#6"#-/)@7
CustomerInfoDialog::CustomerInfoDialog(QWidget *parent) "=$543475C#!%)-5"1
: QDialog(parent)
{ J1 R%&4-3&!3.0-66&-3&%P%30&/!60%$&+3&-&.!3"6%&S>JT%40(
...
firstNameEdit->installEventFilter(this); [)3"#%)#/,V"37#!%'#,"")#("&4'7"("-#*'4)& installEventFilter()9#%55#7!"#"8")7'#./(#7!"#7%(&"7
lastNameEdit->installEventFilter(this);
/,V"37#%("#.4('7#'")7#7/#7!"#+/)47/(4)&#/,V"37@' event-Filter()#.*)374/)1#M.#+*574$5"#"8")7
cityEdit->installEventFilter(this);
phoneNumberEdit->installEventFilter(this); .457"('#%("#4)'7%55"-#/)#7!"#'%+"#/,V"379#7!"#.457"('#%("#%3748%7"-#4)#7*()9#.(/+#7!"#+/'7
} ("3")75C#4)'7%55"-#,%32#7/#7!"#.4('7#4)'7%55"-1
P1 R%&4-3&!3.0-66&-3&%P%30&/!60%$&+3&01%&SG,,6!4-0!+3&+JT%40(
[)3"#7!"#"8")7#.457"(#4'#("&4'7"("-9#7!"#"8")7'#7!%7#%("#'")7#7/#7!" firstName-Edit9 lastNameEdit9
cityEdit9#%)- phoneNumberEdit#64-&"7'#%("#.4('7#'")7#7/#7!" CustomerInfoDialog@' eventFilter() [)3"#%)#"8")7#.457"(#!%'#,"")#("&4'7"("-#./( qApp#K7!"#*)4_*" QApplication#/,V"37O9#"8"(C
.*)374/)#,"./("#7!"C#%(" '")7#/)#7/#7!"4(#4)7")-"-#-"'74)%74/)1 "8")7#./( "8"(C#/,V"37#4)#7!"#%$$543%74/)#4'#'")7#7/#7!" event-Filter()#.*)374/)#,"./("#47#4'
'")7#7/#%)C#/7!"(#"8")7#.457"(1# !4'#%$$(/%3!#4'#+/'75C#*'".*5#./(#-",*&&4)&1#M7#3%)#%5'/#,"
*'"-#7/#!%)-5"#+/*'"#"8")7'#'")7#7/#-4'%,5"-#64-&"7'9#6!43! QApplication#)/(+%55C#-4'3%(-'1
?"("@'#7!" eventFilter()#.*)374/)#7!%7#("3"48"'#7!"#"8")7'A
S1 R%&4-3&.#J46-..&SG,,6!4-0!+3&-35&$%!L,6%L%30&3+0!/XVW(
bool CustomerInfoDialog::eventFilter(QObject *target, QEvent *event)
{ ^7#3%55' QApplication::notify()#7/#'")-#/*7#%)#"8")71#j"4+$5"+")74)!4'#.*)374/)#4'#7!"
if (target == firstNameEdit || target == lastNameEdit /)5C#6%C#7/#&"7#%55#7!"#"8")7'9#,"./("#%)C#"8")7#.457"('#&"7#7!"#/$$/(7*)47C#7/#5//2#%7#7!"+1
|| target == cityEdit || target == phoneNumberEdit) { >8")7#.457"('#%("#&")"(%55C#+/("#*'".*59#,"3%*'"#7!"("#3%)#,"#%)C#)*+,"(#/.#3/)3*((")7#"8")7
if (event->type() == QEvent::KeyPress) { .457"('9#,*7#/)5C#/)" notify()#.*)374/)1
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
if (keyEvent->key() == Qt::Key_Space) {
focusNextChild(); X%)C#"8")7#7C$"'9#4)35*-4)&#+/*'"#%)-#2"C#"8")7'9#3%)#,"#$(/$%&%7"-1#M.#7!"#"8")7#!%'#)/7#,"")
return true; !%)-5"-#/)#7!"#6%C#7/#47'#7%(&"7#/,V"37#/(#,C#7!"#7%(&"7#/,V"37#47'"5.9#7!"#6!/5"#"8")7#$(/3"''4)&
} $(/3"''#4'#("$"%7"-9#,*7#7!4'#74+"#647!#7!"#7%(&"7#/,V"37@'#$%(")7#%'#7!"#)"6#7%(&"71# !4'#3/)74)*"'9
} &/4)&#.(/+#$%(")7#7/#$%(")79#*)745#"47!"(#7!"#"8")7#4'#!%)-5"-#/(#7!"#7/$L5"8"5#/,V"37#4'#("%3!"-1
}
return QDialog::eventFilter(target, event); ;4&*("#W1H#'!/6'#!/6#%#2"C#$("''#"8")7#4'#$(/$%&%7"-#.(/+#3!45-#7/#$%(")7#4)#%#-4%5/&1#B!")#7!"
} *'"(#$("''"'#%#2"C9#7!"#"8")7#4'#.4('7#'")7#7/#7!"#64-&"7#7!%7#!%'#./3*'9#4)#7!4'#3%'"#7!"#,/77/+L(4&!7
QCheckBox1#M.#7!" QCheckBox#-/"')@7#!%)-5"#7!"#"8")79#^7#'")-'#47#7/#7!" QGroupBox9#%)-#.4)%55C#7/#7!"
QDialog#/,V"371
[)"#-%)&"(#647!#7!4'#%$$(/%3!#4'#7!%7#7!"#*'"(#+4&!7#35/'"#7!"#+%4)#64)-/6#6!45"#7!"#%$$543%74/)#4'
!"#$%&7(C(&OP%30&,$+,-"-0!+3&!3&-&5!-6+" '7455#'%84)&9#/(#"8")#35432#;45"ZT%8"#%#'"3/)-#74+"9#("'*574))#*)-".4)"-#,"!%84/(1# !"#"%'4"'7
'/5*74/)#7/#7!4'#$(/,5"+#4'#7/#("$5%3"
qApp->processEvents();
647!
qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
7"554)&#^7#7/#4&)/("#+/*'"#%)-#2"C#"8")7'1
[.7")9#6"#6%)7#7/#'!/6#% QProgressDialog#6!45"#%#5/)&L(*))4)&#/$"(%74/)#4'#7%24)&#$5%3"1
QProgressDialog#!%'#%#$(/&("''#,%(#7!%7#2""$'#7!"#*'"(#4)./(+"-#%,/*7#7!"#$(/&("''#,"4)&#+%-"#,C
7!"#%$$543%74/)1 QProgressDialog#%5'/#$(/84-"'#%#E%)3"5#,*77/)#7!%7#%55/6'#7!"#*'"(#7/#%,/(7#7!"
/$"(%74/)1#?"("@'#7!"#3/-"#./(#'%84)&#%#T$("%-'!""7#.45"#*'4)!4'#%$$(/%3!A
Staying Responsive During Intensive Processing
B!")#6"#3%55 QApplication::exec()9#6"#'7%(7#^7@'#"8")7#5//$1#^7#4''*"'#%#."6#"8")7'#/)#'7%(7*$#7/ bool Spreadsheet::writeFile(const QString &fileName)
'!/6#%)-#$%4)7#7!"#64-&"7'1#I.7"( 7!%79#7!"#"8")7#5//$#4'#(*))4)&9#3/)'7%)75C#3!"324)/#'""#4.#%)C {
"8")7'#!%8"#/33*(("-#%)-#-4'$%73!4)!"'"#"8")7'#7/ QObject'#4)#7!"#%$$543%74/)1 QFile file(fileName);
...
B!45"#/)"#"8")7#4'#,"4)&#$(/3"''"-9%--474/)%5#"8")7'#+%C#,"#&")"(%7"-#%)-#%$$")-"-#7/#^7@'#"8")7 QProgressDialog progress(this);
progress.setLabelText(tr("Saving %1").arg(fileName));
_*"*"1#M. 6"#'$")-#7//#+*3!#74+"#$(/3"''4)&#%#$%(743*5%(#"8")79#7!"#*'"(#4)7"(.%3"#6455#,"3/+"
progress.setRange(0, RowCount);
*)("'$/)'48"1#;/(#"=%+$5"9#%)C#"8")7'#&")"(%7"-#,C#7!"#64)-/6#'C'7"+#6!45"#7!"#%$$543%74/)#4'
progress.setModal(true);
'%84)&#%#.45"#7/#-4'2#6455#)/7#,"#$(/3"''"-#*)745#7!"#.45"#4'#'%8"-1#G*(4)!"#'%8"9#7!"#%$$543%74/)#6455 for (int row = 0; row < RowCount; ++row) {
)/7#("'$/)-#7/#("_*"'7'#.(/+#7!"#64)-/6#'C'7"+#7/#("$%4)7#47'"5.1 progress.setValue(row);
qApp->processEvents();
[)"#'/5*74/)#4'#7/#*'"#+*574$5"#7!("%-'A#/)"#7!("%-#./(#7!"#%$$543%74/)@'#*'"(#4)7"(.%3"#%)-#%)/7!"( if (progress.wasCanceled()) {
7!("%-#7/#$"(./(+#.45"#'%84)&#K/(#%)C#/7!"(#74+"L3/)'*+4)& /$"(%74/)O1# !4'#6%C9#7!"#%$$543%74/)@' file.remove();
*'"(#4)7"(.%3"#6455#'7%C#("'$/)'48"#6!45"#7!"#.45"#4'#,"4)&#'%8"-1#B"#6455#'""#!/6#7/#%3!4"8"#7!4'#4) return false;
E!%$7"(#Df1 }
for (int column = 0; column < ColumnCount; ++column) {
QString str = formula(row, column);
I#'4+$5"(#'/5*74/)#4'#7/#+%2"#.("_*")7#3%55'#7/ QApplication::processEvents()#4)#7!"#.45"#'%84)/-"1
if (!str.isEmpty())
!4'#.*)374/)#7"55'#^7#7/#$(/3"''#%)C#$")-4)&#"8")7'9#%)-#7!")#("7*()'#3/)7(/5#7/#7!"#3%55"(1#M)#.%379 out << quint16(row) << quint16(column) << str;
QApplication::exec()#4'#54775"#+/("#7!%)#% while#5//$#%(/*)-#% processEvents()#.*)374/)#3%551 }
}
?"("@'#%)#"=%+$5"#/.#!/6#6"#3%)#2""$#7!"#*'"(#4)7"(.%3"#("'$/)'48"#*'4)& processEvents()9#,%'"- return true;
/)#7!"#.45"#'%84)/-"#./( Spreadsheet#K$1#f0OA }
A& 5'/ #-': ,'-*"$) )='2&) $)*/0 QPainterB) draw...() C$/5+*"/)7 >*0$-& D7E %*)+) +=& !")+
*!2"-+'/+ "/&)7 8=& :'. +=& #-':*/0 *) 2&-C"-!&# *) */C%$&/5&# F. QPainterB) )&++*/0)7 G"!& "C
+=&)& '-& '#"2+&# C-"! +=& #&,*5&< "+=&-) '-& */*+*'%*H&# +" #&C'$%+ ,'%$&)7 8=& +=-&& !'*/ 2'*/+&-
)&++*/0) '-& +=& 2&/< +=& F-$)=< '/# +=& C"/+@
• 8=& !" *) $)&# C"- #-':*/0 %*/&) '/# )='2& "$+%*/&)7 I+ 5"/)*)+) "C ' 5"%"-< ' :*#+=< ' %*/&
)+.%&< ' 5'2 )+.%&< '/# ' J"*/ )+.%&7
• 8=& #$%&' *) +=& 2'++&-/ $)&# C"- C*%%*/0 0&"!&+-*5 )='2&)7 I+ /"-!'%%. 5"/)*)+) "C ' 5"%"- '/#
' )+.%&< F$+ 5'/ '%)" F& ' +&?+$-& 9' 2*?!'2 +='+ *) -&2&'+&# */C*/*+&%.; "- ' 0-'#*&/+7
• 8=& ()"* *) $)&# C"- #-':*/0 +&?+7 K C"/+ =') !'/. '++-*F$+&)< */5%$#*/0 ' C'!*%. '/# ' 2"*/+
)*H&7
!"#$%&'(=(&<$%4%/!1%4&>$#+?&+.32%+
[View full size image]
8=&)& )&++*/0) 5'/ F& !"#*C*&# '+ '/. +*!& F. 5'%%*/0 setPen()< setBrush()< '/# setFont() :*+= '
QPen< QBrush< "- QFont "FJ&5+7
!"#$%&'(6(&789&814&:-!1&+.32%+
4&+B) )&& ' C&: &?'!2%&) */ 2-'5+*5&7 L&-&B) +=& 5"#& +" #-': +=& &%%*2)& )=":/ */ >*0$-& D7M 9';@
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true);
painter.setPen(QPen(Qt::black, 12, Qt::DashDotLine, Qt::RoundCap));
painter.setBrush(QBrush(Qt::green, Qt::SolidPattern)); )&5+*"/ 5"!F*/&) '%% +=-&& +.2&) "C 0-'#*&/+) */ ' )*/0%& :*#0&+ +" !'(& *+ %""( %*(& +=& -&'% +=*/07
painter.drawEllipse(80, 80, 400, 240);
• +,"!-$./$-0,!"*& '-& #&C*/&# F. +:" 5"/+-"% 2"*/+) '/# F. ' )&-*&) "C V5"%"- )+"2)V "/ +=&
%*/& +='+ 5"//&5+) +=&)& +:" 2"*/+)7 >"- &?'!2%&< +=& %*/&'- 0-'#*&/+ "C >*0$-& D7W *) 5-&'+&#
!"#$%&'(@(&A%-,%.$!5&+?89%&%B8,92%+ $)*/0 +=& C"%%":*/0 5"#&@
•
[View full size image]
• QLinearGradient gradient(50, 100, 300, 350);
• gradient.setColorAt(0.0, Qt::white);
• gradient.setColorAt(0.2, Qt::green);
• gradient.setColorAt(1.0, Qt::black);
!"#$%&'(C( QPainter*+&"$84!%1.&>$#+?%+
[View full size image]
8=& setRenderHint() 5'%% &/'F%&) '/+*'%*')*/0< +&%%*/0 QPainter +" $)& #*CC&-&/+ 5"%"- */+&/)*+*&) "/ +=&
�&) +" -&#$5& +=& ,*)$'% #*)+"-+*"/ +='+ /"-!'%%. "55$-) :=&/ +=& �&) "C ' )='2& '-& 5"/,&-+&#
*/+" 2*?&%)7 8=& -&)$%+ *) )!""+=&- �&) "/ 2%'+C"-!) '/# #&,*5&) +='+ )$22"-+ +=*) C&'+$-&7
L&-&B) +=& 5"#& +" #-': +=& 2*& )&0!&/+ )=":/ */ >*0$-& D7M 9F;@
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true);
painter.setPen(QPen(Qt::black, 15, Qt::SolidLine, Qt::RoundCap,
Qt::MiterJoin));
painter.setBrush(QBrush(Qt::blue, Qt::DiagCrossPattern));
painter.drawPie(80, 80, 400, 240, 60 * 16, 270 * 16);
8=& %')+ +:" '-0$!&/+) +" drawPie() '-& &?2-&))&# */ )*?+&&/+=) "C ' #&0-&&7
L&-&B) +=& 5"#& +" #-': +=& 5$F*5 NOH*&- 5$-,& )=":/ */ >*0$-& D7M 95;@
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true); A& )2&5*C. +=-&& 5"%"-) '+ +=-&& #*CC&-&/+ 2")*+*"/) F&+:&&/ +=& +:" 5"/+-"% 2"*/+)7 Q")*+*"/)
QPainterPath path; '-& )2&5*C*&# ') C%"'+*/0R2"*/+ ,'%$&) F&+:&&/ X '/# E< :=&-& X 5"--&)2"/#) +" +=& C*-)+
path.moveTo(80, 320); 5"/+-"% 2"*/+ '/# E +" +=& )&5"/# 5"/+-"% 2"*/+7 Y"%"-) F&+:&&/ +=& )2&5*C*&# )+"2) '-&
path.cubicTo(200, 80, 320, 80, 480, 320); */+&-2"%'+
painter.setPen(QPen(Qt::black, 8));
painter.drawPath(path); • 1-0,-2./$-0,!"*& '-& #&C*/&# F. ' 5&/+&- 2"*/+ 935<45;< ' -'#*$) $< '/# ' C"5'% 2"*/+ 93C<4C;<
*/ '##*+*"/ +" +=& 5"%"- )+"2)7 8=& 5&/+&- 2"*/+ '/# +=& -'#*$) )2&5*C. ' 5*-5%&7 8=& 5"%"-)
)2-&'# "$+:'-# C-"! +=& C"5'% 2"*/+< :=*5= 5'/ F& +=& 5&/+&- 2"*/+ "- '/. "+=&- 2"*/+ */)*#&
8=& QPainterPath 5%')) 5'/ )2&5*C. '-F*+-'-. ,&5+"- )='2&) F. 5"//&5+*/0 F')*5 0-'2=*5'% &%&!&/+) +=& 5*-5%&7
+"0&+=&-@ )+-'*0=+ %*/&)< &%%*2)&)< 2"%.0"/)< '-5)< P$'#-'+*5 '/# 5$F*5 NOH*&- 5$-,&)< '/# "+=&- • 5)",6-2./$-0,!"*& '-& #&C*/&# F. ' 5&/+&- 2"*/+ 935<45; '/# '/ '/0%& 7 8=& 5"%"-) )2-&'#
2'*/+&- 2'+=)7 Q'*/+&- 2'+=) '-& +=& $%+*!'+& #-':*/0 2-*!*+*,& */ +=& )&/)& +='+ '/. )='2& "- '-"$/# +=& 5&/+&- 2"*/+ %*(& +=& ):&&2 "C ' :'+5=B) )&5"/#) ='/#7
5"!F*/'+*"/ "C )='2&) 5'/ F& &?2-&))&# ') ' 2'+=7
G" C'- :& =',& !&/+*"/&# QPainterB) 2&/< F-$)=< '/# C"/+ )&++*/0)7 I/ '##*+*"/ +" +=&)&< QPainter
K 2'+= )2&5*C*&) '/ "$+%*/&< '/# +=& '-&' #&)5-*F&# F. +=& "$+%*/& 5'/ F& C*%%&# $)*/0 ' F-$)=7 I/ +=& =') "+=&- )&++*/0) +='+ */C%$&/5& +=& :'. )='2&) '/# +&?+ '-& #-':/@
&?'!2%& "C >*0$-& D7M 95;< :& #*#/B+ )&+ ' F-$)=< )" "/%. +=& "$+%*/& *) #-':/7
• 8=& #-67/$)%"0.#$%&' *) $)&# +" C*%% +=& F'5(0-"$/# "C 0&"!&+-*5 )='2&) 9$/#&-/&'+= +=&
8=& +=-&& &?'!2%&) 'F",& $)& F$*%+R*/ F-$)= 2'++&-/) 9Qt::SolidPattern< Qt:: DiagCrossPattern< F-$)= 2'++&-/;< +&?+< "- F*+!'2) :=&/ +=& #-67/$)%"0.8)0! *) Qt::OpaqueMode 9+=& #&C'$%+
'/# Qt::NoBrush;7 I/ !"#&-/ '22%*5'+*"/)< 0-'#*&/+ C*%%) '-& ' 2"2$%'- '%+&-/'+*,& +" !"/"5=-"!& C*%% *) Qt::transparentMode;7
2'++&-/)7 3-'#*&/+) -&%. "/ 5"%"- */+&-2"%'+*"/ +" "F+'*/ )!""+= +-'/)*+*"/) F&+:&&/ +:" "- !"-& • 8=& #$%&'.)$,/," *) +=& )+'-+*/0 2"*/+ C"- F-$)= 2'++&-/)< /"-!'%%. +=& +"2R%&C+ 5"-/&- "C +=&
5"%"-)7 8=&. '-& C-&P$&/+%. $)&# +" 2-"#$5& ST &CC&5+)U C"- &?'!2%&< +=& Q%')+*P$& )+.%& $)&) :*#0&+7
0-'#*&/+) +" -&/#&- QPushButton)7 • 8=& 62, .$!/,)" *) +=& '-&' "C +=& #&,*5& +='+ 5'/ F& 2'*/+ Q'*/+*/0 "$+)*#& +=& 5%*2 -&0*"/
=') /" &CC&5+7
6+ )$22"-+) +=-&& +.2&) "C 0-'#*&/+)@ %*/&'-< 5"/*5'%< '/# -'#*'%7 8=& 1,&/ 8*!&- &?'!2%& */ +=& /&?+ • 8=& 9,!: )$*;.:,"0):< '/# :)$20.8-*$,3 #&+&-!*/& =": %"0*5'% QPainter 5""-#*/'+&) !'2
+" 2=.)*5'% 2'*/+ #&,*5& 5""-#*/'+&)7 N. #&C'$%+< +=&)& '-& )&+ $2 )" +='+ +=& %"0*5'% '/# 2=.)*5'% 5""-#*/'+&)7 8=& :*/#": )2&5*C*&) +=& )'!& -&5+'/0%&< F$+ */ %"0*5'% 5""-#*/'+&)7 A=&/ :&
2=.)*5'% 5""-#*/'+& ).)+&!) 5"*/5*#&7 Y""-#*/'+& ).)+&!) '-& 5",&-&# */ +=& /&?+ )&5+*"/7 #" +=& 2'*/+*/0< :& )2&5*C. 2"*/+) */ %"0*5'% 5""-#*/'+&)< '/# +=")& 5""-#*/'+&) '-& 5"/,&-+&# */+"
• 8=& 6)8 )&,*,)".8)0! )2&5*C*&) =": +=& /&:%. #-':/ 2*?&%) )="$%# */+&-'5+ :*+= +=& 2*?&%) 2=.)*5'% 5""-#*/'+&) */ ' %*/&'- '%0&F-'*5 !'//&-< F')&# "/ +=& 5$--&/+ :*/#":,*&:2"-+ )&++*/0)7
'%-&'#. 2-&)&/+ "/ +=& 2'*/+ #&,*5&7 8=& #&C'$%+ *) V)"$-5& ",&-V< :=&-& #-':/ 2*?&%) '-&
#-':/ "/ +"2 "C &?*)+*/0 2*?&%)7 8=*) *) )$22"-+&# "/%. "/ 5&-+'*/ #&,*5&) '/# *) 5",&-&# %'+&- N. #&C'$%+< +=& ,*&:2"-+ '/# +=& :*/#": '-& )&+ +" +=& #&,*5&B) -&5+'/0%&7 >"- &?'!2%&< *C +=& #&,*5&
*/ +=*) 5='2+&-7 *) ' S_X ? _XX :*#0&+< F"+= +=& ,*&:2"-+ '/# +=& :*/#": '-& +=& )'!& S_X ? _XX -&5+'/0%& :*+= *+)
+"2R%&C+ 5"-/&- '+ 2")*+*"/ 9X< X;7 I/ +=*) 5')&< +=& %"0*5'% '/# 2=.)*5'% 5""-#*/'+& ).)+&!) '-& +=&
K+ '/. +*!&< :& 5'/ )',& +=& 5$--&/+ )+'+& "C ' 2'*/+&- "/ '/ */+&-/'% )+'5( F. 5'%%*/0 save() '/# )'!&7
-&)+"-& *+ %'+&- "/ F. 5'%%*/0 restore()7 8=*) 5'/ F& $)&C$% *C :& :'/+ +" +&!2"-'-*%. 5='/0& )"!&
2'*/+&- )&++*/0) '/# +=&/ -&)&+ +=&! +" +=&*- 2-&,*"$) ,'%$&)< ') :& :*%% )&& */ +=& /&?+ )&5+*"/7 8=& :*/#":,*&:2"-+ !&5='/*)! *) $)&C$% +" !'(& +=& #-':*/0 5"#& */#&2&/#&/+ "C +=& )*H& "-
-&)"%$+*"/ "C +=& 2'*/+ #&,*5&7 >"- &?'!2%&< *C :& :'/+ +=& %"0*5'% 5""-#*/'+&) +" &?+&/# C-"! 9RMX< R
MX; +" 9[MX< [MX;< :*+= 9X< X; */ +=& !*##%&< :& 5'/ )&+ +=& :*/#": ') C"%%":)@
8=*) #*)+*/5+*"/ !'. )&&! -'+=&- '5'#&!*5 '+ C*-)+< F$+ *+ =') *!2"-+'/+ 5"/)&P$&/5&) */ 2-'5+*5&7
>*-)+< +=& )=*C+*/0 F. [X7M "/%. "55$-) *C '/+*'%*')*/0 *) #*)'F%&# 9+=& #&C'$%+;U *C '/+*'%*')*/0 *)
&/'F%&# '/# :& +-. +" #-': ' 2*?&% '+ 9EXX< EXX; */ F%'5(< QPainter :*%% '5+$'%%. 5"%"- +=& C"$- 2*?&%)
9\\7M< \\7M;< 9\\7M< EXX7M;< 9EXX7M< \\7M;< '/# 9EXX7M< EXX7M; %*0=+ 0-'.< +" 0*,& +=& *!2-&))*"/ "C '
2*?&% %.*/0 &?'5+%. '+ +=& !&&+*/0 2"*/+ "C +=& C"$- 2*?&%)7 IC +=*) &CC&5+ *) $/#&)*-'F%&< :& 5'/ ',"*# *+
F. )2&5*C.*/0 ='%CR2*?&% 5""-#*/'+&)< C"- &?'!2%&< 9EXX7M< EXX7M;7
A=&/ #-':*/0 )='2&) )$5= ') %*/&)< -&5+'/0%&)< '/# &%%*2)&)< )*!*%'- -$%&) '22%.7 >*0$-& D7] )=":)
=": +=& -&)$%+ "C ' drawRect(2, 2, 6, 5) 5'%% ,'-*&) '55"-#*/0 +" +=& 2&/B) :*#+=< :=&/ '/+*'%*')*/0
*) "CC7 I/ 2'-+*5$%'-< *+ *) *!2"-+'/+ +" /"+*5& +='+ ' W ? M -&5+'/0%& #-':/ :*+= ' 2&/ :*#+= "C E ^": 5"!&) +=& :"-%# !'+-*?7 8=& :"-%# !'+-*? *) ' +-'/)C"-!'+*"/ !'+-*? +='+ *) '22%*&# */ '##*+*"/
&CC&5+*,&%. 5",&-) '/ '-&' "C )*H& ] ? W7 8=*) *) #*CC&-&/+ C-"! "%#&- +""%(*+)< */5%$#*/0 &'-%*&- ,&-)*"/) +" +=& :*/#":,*&:2"-+ 5"/,&-)*"/7 I+ '%%":) $) +" +-'/)%'+&< )5'%&< -"+'+&< "- )=&'- +=& *+&!) :& '-&
"C 6+< F$+ *+ *) &))&/+*'% C"- !'(*/0 +-$%. )5'%'F%&< -&)"%$+*"/R*/#&2&/#&/+ ,&5+"- 0-'2=*5) 2"))*F%&7 #-':*/07 >"- &?'!2%&< *C :& :'/+&# +" #-': +&?+ '+ ' `Ma '/0%&< :& :"$%# $)& +=*) 5"#&@
8=& %"0*5'% 5""-#*/'+&) :& 2')) +" drawText() '-& +-'/)C"-!&# F. +=& :"-%# !'+-*?< +=&/ !'22&# +"
2=.)*5'% 5""-#*/'+&) $)*/0 +=& :*/#":,*&:2"-+ )&++*/0)7
IC :& )2&5*C. !$%+*2%& +-'/)C"-!'+*"/)< +=&. '-& '22%*&# */ +=& "-#&- */ :=*5= +=&. '-& 0*,&/7 >"-
&?'!2%&< *C :& :'/+ +" $)& +=& 2"*/+ 9EX< _X; ') +=& -"+'+*"/B) 2*,"+ 2"*/+< :& 5'/ #" )" F.
+-'/)%'+*/0 +=& :*/#":< 2&-C"-!*/0 +=& -"+'+*"/< '/# +=&/ +-'/)%'+*/0 +=& :*/#": F'5( +" *+) "-*0*/'%
2")*+*"/@
^": +='+ :& $/#&-)+'/# +=& #&C'$%+ 5""-#*/'+& ).)+&!< :& 5'/ +'(& ' 5%")&- %""( '+ =": *+ 5'/ F&
5='/0&# $)*/0 QPainterB) ,*&:2"-+< :*/#":< '/# :"-%# !'+-*?7 9I/ +=*) 5"/+&?+< +=& +&-! V:*/#":V
#"&) /"+ -&C&- +" ' :*/#": */ +=& )&/)& "C ' +"2R%&,&% :*#0&+< '/# +=& V,*&:2"-+V =') /"+=*/0 +" #" QMatrix matrix;
:*+= QScrollAreaB) ,*&:2"-+7; matrix.translate(-10.0, -20.0);
matrix.rotate(45.0);
matrix.translate(+10.0, +20.0);
8=& ,*&:2"-+ '/# +=& :*/#": '-& +*0=+%. F"$/#7 8=& ,*&:2"-+ *) '/ '-F*+-'-. -&5+'/0%& )2&5*C*&# */ painter.setMatrix(matrix);
painter.drawText(rect, Qt::AlignCenter, tr("Revenue")); mousePressEvent()7
K )*!2%&- :'. +" )2&5*C. +-'/)C"-!'+*"/) *) +" $)& QPainterB) translate()< scale()< rotate()< '/# const double DegreesPerMinute = 7.0;
shear() 5"/,&/*&/5& C$/5+*"/)@ const double DegreesPerSecond = DegreesPerMinute / 60;
const int MaxMinutes = 45;
const int MaxSeconds = MaxMinutes * 60;
const int UpdateInterval = 1;
painter.translate(-10.0, -20.0);
painter.rotate(45.0);
painter.translate(+10.0, +20.0);
painter.drawText(rect, Qt::AlignCenter, tr("Revenue")); A& )+'-+ F. #&C*/*/0 ' C&: 5"/)+'/+) +='+ 5"/+-"% +=& ",&/ +*!&-B) %""( '/# C&&%7
N$+ *C :& :'/+ +" $)& +=& )'!& +-'/)C"-!'+*"/) -&2&'+&#%.< *+B) !"-& &CC*5*&/+ +" )+"-& +=&! */ ' OvenTimer::OvenTimer(QWidget *parent)
: QWidget(parent)
QMatrix "FJ&5+ '/# )&+ +=& :"-%# !'+-*? "/ +=& 2'*/+&- :=&/&,&- +=& +-'/)C"-!'+*"/) '-& /&&#
{
finishTime = QDateTime::currentDateTime();
8" *%%$)+-'+& 2'*/+&- +-'/)C"-!'+*"/)< :& :*%% -&,*&: +=& 5"#& "C +=& OvenTimer :*#0&+ )=":/ */ updateTimer = new QTimer(this);
>*0$-& D7\7 8=& OvenTimer :*#0&+ *) !"#&%&# 'C+&- +=& (*+5=&/ +*!&-) +='+ :&-& $)&# F&C"-& *+ :') connect(updateTimer, SIGNAL(timeout()), this, SLOT(update()));
5"!!"/ +" =',& ",&/) :*+= 5%"5() F$*%+R*/7 8=& $)&- 5'/ 5%*5( ' /"+5= +" )&+ +=& #$-'+*"/7 8=& :=&&% finishTimer = new QTimer(this);
'$+"!'+*5'%%. +$-/) 5"$/+&-5%"5(:*)& $/+*% X *) -&'5=&#< '+ :=*5= 2"*/+ OvenTimer &!*+) +=& timeout() finishTimer->setSingleShot(true);
)*0/'%7 connect(finishTimer, SIGNAL(timeout()), this, SIGNAL(timeout()));
connect(finishTimer, SIGNAL(timeout()), updateTimer, SLOT(stop()));
}
!"#$%&'(H(&I?% OvenTimer&F!4"%.
I/ +=& 5"/)+-$5+"-< :& 5-&'+& +:" QTimer "FJ&5+)@ updateTimer *) $)&# +" -&C-&)= +=& '22&'-'/5& "C
+=& :*#0&+ &,&-. )&5"/#< '/# finishTimer &!*+) +=& :*#0&+B) timeout() )*0/'% :=&/ +=& ",&/ +*!&-
-&'5=&) X7 8=& finishTimer "/%. /&&#) +" +*!&"$+ "/5&< )" :& 5'%% setSingleShot(true)U F. #&C'$%+<
+*!&-) C*-& -&2&'+&#%. $/+*% +=&. '-& )+"22&# "- #&)+-". 8=& %')+ connect() 5'%% *) '/ "2+*!*H'+*"/
+" )+"2 $2#'+*/0 +=& :*#0&+ &,&-. )&5"/# :=&/ +=& +*!&- *) */'5+*,&7
8=& duration() C$/5+*"/ -&+$-/) +=& /$!F&- "C )&5"/#) %&C+ F&C"-& +=& +*!&- *) #$& +" C*/*)=7 IC +=&
+*!&- *) */'5+*,&< :& -&+$-/ X7
IC +=& $)&- 5%*5() +=& :*#0&+< :& C*/# +=& 5%")&)+ /"+5= $)*/0 ' )$F+%& F$+ &CC&5+*,& !'+=&!'+*5'%
C"-!$%'< '/# :& $)& +=& -&)$%+ +" )&+ +=& /&: #$-'+*"/7 8=&/ :& )5=&#$%& ' -&2'*/+7 8=& /"+5= +='+ IC :& ='# /"+ )&+ +=& ,*&:2"-+ +" F& ' )P$'-&< +=& ",&/ +*!&- :"$%# F& '/ &%%*2)& :=&/ +=& :*#0&+ *)
+=& $)&- 5%*5(&# :*%% /": F& '+ +=& +"2 '/# :*%% !",& 5"$/+&-5%"5(:*)& ') +*!& 2'))&) $/+*% X *) -&)*H&# +" ' /"/R)P$'-& -&5+'/0%&7 8" ',"*# )$5= #&C"-!'+*"/)< :& !$)+ )&+ +=& ,*&:2"-+ '/# +=&
-&'5= :*/#": +" -&5+'/0%&) :*+= +=& )'!& ')2&5+ -'+*"7
A& #-': +=& "$+&- 5*-5%& '/# C*%% *+ $)*/0 ' 5"/*5'% 0-'#*&/+7 8=& 0-'#*&/+B) 5&/+&- 2"*/+ *) %"5'+&# '+
9X< X;< '/# +=& '/0%& *) R\Xa7
if (i % 5 == 0) {
QRadialGradient haloGradient(0, 0, 20, 0, 0); painter->setPen(thickPen);
haloGradient.setColorAt(0.0, Qt::lightGray); painter->drawLine(0, -41, 0, -44);
haloGradient.setColorAt(0.8, Qt::darkGray); painter->drawText(-15, -41, 30, 25,
haloGradient.setColorAt(0.9, Qt::white); Qt::AlignHCenter | Qt::AlignTop,
haloGradient.setColorAt(1.0, Qt::black); QString::number(i));
painter->setPen(Qt::NoPen); } else {
painter->setBrush(haloGradient); painter->setPen(thinPen);
painter->drawEllipse(-20, -20, 40, 40); painter->drawLine(0, -42, 0, -44);
}
painter->restore();
}
A& C*%% +=& *//&- 5*-5%& $)*/0 ' -'#*'% 0-'#*&/+7 8=& 5&/+&- 2"*/+ '/# +=& C"5'% 2"*/+ "C +=& 0-'#*&/+
'-& %"5'+&# '+ 9X< X;7 8=& -'#*$) "C +=& 0-'#*&/+ *) _X7
K/"+=&- :'. "C *!2%&!&/+*/0 '/ ",&/ +*!&- :"$%# =',& F&&/ +" 5"!2$+& +=& 93;.4; 2")*+*"/)
QLinearGradient knobGradient(-7, -25, 7, -25); "$-)&%,&)< $)*/0 sin() '/# cos() +" C*/# +=& 2")*+*"/) '%"/0 +=& 5*-5%&7 N$+ +=&/ :& :"$%# )+*%% /&&#
knobGradient.setColorAt(0.0, Qt::black); +" $)& ' +-'/)%'+*"/ '/# ' -"+'+*"/ +" #-': +=& +&?+ '+ '/ '/0%&7
knobGradient.setColorAt(0.2, niceBlue);
knobGradient.setColorAt(0.3, Qt::lightGray);
knobGradient.setColorAt(0.8, Qt::white);
knobGradient.setColorAt(1.0, Qt::black);
painter->rotate(duration() * DegreesPerSecond);
painter->setBrush(knobGradient);
painter->setPen(thinPen);
High-Quality Rendering with QImage
painter->drawRoundRect(-7, -25, 14, 50, 150, 50);
for (int i = 0; i <= MaxMinutes; ++i) { A=&/ #-':*/0< :& !'. F& C'5&# :*+= ' +-'#&R"CC F&+:&&/ )2&&# '/# '55$-'5.7 >"- &?'!2%&< "/ bEE
if (i % 5 == 0) { '/# c'5 1G b< #-':*/0 "/ ' QWidget "- QPixmap -&%*&) "/ +=& 2%'+C"-!B) /'+*,& 2'*/+ &/0*/&7 1/ bEE<
painter->setPen(thickPen); +=*) &/)$-&) +='+ 5"!!$/*5'+*"/ :*+= +=& b )&-,&- *) (&2+ +" ' !*/*!$!U "/%. 2'*/+ 5"!!'/#) '-&
painter->drawLine(0, -41, 0, -44); )&/+ -'+=&- +='/ '5+$'% *!'0& #'+'7 8=& !'*/ #-':F'5( "C +=*) '22-"'5= *) +='+ 6+ *) %*!*+&# F. +=&
painter->drawText(-15, -41, 30, 25, 2%'+C"-!B) /'+*,& )$22"-+@
Qt::AlignHCenter | Qt::AlignTop,
QString::number(i));
} else { • 1/ bEE< C&'+$-&) )$5= ') '/+*'%*')*/0 '/# )$22"-+ C"- C-'5+*"/'% 5""-#*/'+&) '-& ','*%'F%& "/%.
painter->setPen(thinPen); *C +=& b d&/#&- &?+&/)*"/ *) 2-&)&/+ "/ +=& b )&-,&-7
painter->drawLine(0, -42, 0, -44); • 1/ c'5 1G b< +=& /'+*,& '%*')&# 0-'2=*5) &/0*/& $)&) #*CC&-&/+ '%0"-*+=!) C"- #-':*/0
} 2"%.0"/) +='/ bEE '/# A*/#":)< :*+= )%*0=+%. #*CC&-&/+ -&)$%+)7
painter->rotate(-DegreesPerMinute);
} A=&/ '55$-'5. *) !"-& *!2"-+'/+ +='/ &CC*5*&/5.< :& 5'/ #-': +" ' QImage '/# 5"2. +=& -&)$%+ "/+"
} +=& )5-&&/7 8=*) '%:'.) $)&) 6+B) ":/ */+&-/'% 2'*/+ &/0*/&< 0*,*/0 *#&/+*5'% -&)$%+) "/ '%% 2%'+C"-!)7
8=& "/%. -&)+-*5+*"/ *) +='+ +=& QImage "/ :=*5= :& 2'*/+ !$)+ F& 5-&'+&# :*+= '/ '-0$!&/+ "C &*+=&-
QImage::Format_RGB32 "- QImage::Format_ARGB32_Premultiplied7
A& 5'%% rotate() +" -"+'+& +=& 2'*/+&-B) 5""-#*/'+& ).)+&!7 I/ +=& "%# 5""-#*/'+& ).)+&!< +=& XR
!*/$+& !'-( :') "/ +"2U /":< +=& XR!*/$+& !'-( *) !",&# +" +=& 2%'5& +='+ *) '22-"2-*'+& C"- +=& 8=& 2-&!$%+*2%*&# Kd3NS_ C"-!'+ *) '%!")+ *#&/+*5'% +" +=& 5"/,&/+*"/'% Kd3NS_ C"-!'+
+*!& %&C+7 A& #-': +=& -&5+'/0$%'- (/"F ='/#%& 'C+&- +=& -"+'+*"/< )*/5& *+) "-*&/+'+*"/ #&2&/#) "/ 90xaarrggbb;< +=& #*CC&-&/5& F&*/0 +='+ +=& -&#< 0-&&/< '/# F%$& 5='//&%) '-& V2-&!$%+*2%*&#V :*+=
+=& -"+'+*"/ '/0%&7 +=& '%2=' 5='//&%7 8=*) !&'/) +='+ +=& d3N ,'%$&)< :=*5= /"-!'%%. -'/0& C-"! 0x00 +" 0xFF< '-&
)5'%&# C-"! 0x00 +" +=& '%2=' ,'%$&7 >"- &?'!2%&< ' MXeR+-'/)2'-&/+ F%$& 5"%"- *) -&2-&)&/+&# ')
I/ +=& for %""2< :& #-': +=& +*5( !'-() '%"/0 +=& "$+&- 5*-5%&B) �& '/# +=& /$!F&-) C"- &'5= 0x7F0000FF */ Kd3NS_ C"-!'+< F$+ 0x7F00007F */ 2-&!$%+*2%*&# Kd3NS_ C"-!'+< '/# )*!*%'-%. ' ]MeR
!$%+*2%& "C M !*/$+&)7 8=& +&?+ *) #-':/ */ '/ */,*)*F%& -&5+'/0%& $/#&-/&'+= +=& +*5( !'-(7 K+ +=& +-'/)2'-&/+ #'-( 0-&&/ "C 0x3F008000 */ Kd3NS_ C"-!'+ :"$%# F& 0x3F002000 */ 2-&!$%+*2%*&#
&/# "C &'5= *+&-'+*"/< :& -"+'+& +=& 2'*/+&- 5%"5(:*)& F. ]a< :=*5= 5"--&)2"/#) +" "/& !*/$+&7 8=& Kd3NS_ C"-!'+7
/&?+ +*!& :& #-': ' +*5( !'-(< *+ :*%% F& '+ ' #*CC&-&/+ 2")*+*"/ '-"$/# +=& 5*-5%&< &,&/ +="$0= +=&
5""-#*/'+&) :& 2')) +" +=& drawLine() '/# drawText() 5'%%) '-& '%:'.) +=& )'!&7 4&+B) )$22")& :& :'/+ +" $)& '/+*'%*')*/0 C"- #-':*/0 ' :*#0&+< '/# :& :'/+ +" "F+'*/ 0""# -&)$%+)
&,&/ "/ bEE ).)+&!) :*+= /" b d&/#&- &?+&/)*"/7 8=& "-*0*/'% paintEvent() ='/#%&-< :=*5= -&%*&) "/
8=& 5"#& */ +=& for %""2 )$CC&-) C-"! ' !*/"- C%':< :=*5= :"$%# P$*5(%. F&5"!& '22'-&/+ *C :& b d&/#&- C"- +=& '/+*'%*')*/0< !*0=+ %""( %*(& +=*)@
2&-C"-!&# !"-& *+&-'+*"/)7 Z'5= +*!& :& 5'%% rotate()< :& &CC&5+*,&%. !$%+*2%. +=& 5$--&/+ :"-%#
!'+-*? :*+= ' -"+'+*"/ !'+-*?< 2-"#$5*/0 ' /&: :"-%# !'+-*?7 8=& -"$/#*/0 &--"-) '))"5*'+&# :*+=
C%"'+*/0R2"*/+ '-*+=!&+*5 '## $2< -&)$%+*/0 */ '/ */5-&')*/0%. */'55$-'+& :"-%# !'+-*?7 L&-&B) "/& :'. void MyWidget::paintEvent(QPaintEvent *event)
+" -&:-*+& +=& 5"#& +" ',"*# +=*) *))$&< $)*/0 save() '/# restore() +" )',& '/# -&%"'# +=& "-*0*/'% {
+-'/)C"-!'+*"/ !'+-*? C"- &'5= *+&-'+*"/@ QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true);
draw(&painter);
for (int i = 0; i <= MaxMinutes; ++i) { }
painter->save();
painter->rotate(-i * DegreesPerMinute);
L&-&B) =": +" -&:-*+& +=& :*#0&+B) paintEvent() C$/5+*"/ +" $)& 6+B) 2%'+C"-!R*/#&2&/#&/+ 0-'2=*5)
&/0*/&@ 1/& *))$& +" F& ':'-& "C *) +='+ +=& QImage::CompositionMode_Xor "2&-'+*"/ '22%*&) +" +=& '%2='
5='//&%7 8=*) !&'/) +='+ *C :& b1d +=& 5"%"- :=*+& 9 0xFFFFFFFF; :*+= *+)&%C< :& "F+'*/ ' +-'/)2'-&/+
5"%"- 90x00000000;< /"+ F%'5( 90xFF000000;7
void MyWidget::paintEvent(QPaintEvent *event)
{
QImage image(size(), QImage::Format_ARGB32_Premultiplied);
QPainter imagePainter(&image);
imagePainter.initFrom(this);
imagePainter.setRenderHint(QPainter::Antialiasing, true);
imagePainter.eraseRect(rect()); Printing
draw(&imagePainter);
imagePainter.end(); Q-*/+*/0 */ 6+ *) )*!*%'- +" #-':*/0 "/ ' QWidget< QPixmap< "- QImage7 I+ 5"/)*)+) "C +=& C"%%":*/0
QPainter widgetPainter(this); )+&2)@
widgetPainter.drawImage(0, 0, image);
}
)( Y-&'+& ' QPrinter +" )&-,& ') +=& 2'*/+ #&,*5&7
A& 5-&'+& ' QImage "C +=& )'!& )*H& ') +=& :*#0&+ */ 2-&!$%+*2%*&# Kd3NS_ C"-!'+< '/# ' QPainter 6( Q"2 $2 ' QPrintDialog< '%%":*/0 +=& $)&- +" 5="")& ' 2-*/+&- '/# +" )&+ ' C&: "2+*"/)7
+" #-': "/ +=& *!'0&7 8=& initFrom() 5'%% */*+*'%*H&) +=& 2'*/+&-B) 2&/< F'5(0-"$/#< '/# C"/+ F')&#
"/ +=& :*#0&+7 A& 2&-C"-! +=& #-':*/0 $)*/0 +=& QPainter ') $)$'%< '/# '+ +=& &/# :& -&$)& +=& ;( Y-&'+& ' QPainter +" "2&-'+& "/ +=& QPrinter7
QPainter "FJ&5+ +" 5"2. +=& *!'0& "/+" +=& :*#0&+7
=( T-': ' 2'0& $)*/0 +=& QPainter7
8=*) '22-"'5= 2-"#$5&) *#&/+*5'% =*0=RP$'%*+. -&)$%+) "/ '%% 2%'+C"-!)< :*+= +=& &?5&2+*"/ "C C"/+
-&/#&-*/0< :=*5= #&2&/#) "/ +=& */)+'%%&# C"/+)7
@( Y'%% QPrinter::newPage() +" '#,'/5& +" +=& /&?+ 2'0&7
1/& 2'-+*5$%'-%. 2":&-C$% C&'+$-& "C 6+B) 0-'2=*5) &/0*/& *) *+) )$22"-+ C"- 5"!2")*+*"/ !"#&)7 8=&)&
)2&5*C. =": ' )"$-5& '/# ' #&)+*/'+*"/ 2*?&% '-& !&-0&# +"0&+=&- :=&/ #-':*/07 8=*) '22%*&) +" '%%
2'*/+*/0 "2&-'+*"/)< */5%$#*/0 2&/< F-$)=< 0-'#*&/+< '/# *!'0& #-':*/07 C( d&2&'+ )+&2) ` '/# M $/+*% '%% +=& 2'0&) '-& 2-*/+
8=& #&C'$%+ 5"!2")*+*"/ !"#& *) QImage::CompositionMode_SourceOver< !&'/*/0 +='+ +=& )"$-5& 2*?&%
9+=& 2*?&% :& '-& #-':*/0; *) F%&/#&# "/ +"2 "C +=& #&)+*/'+*"/ 2*?&% 9+=& &?*)+*/0 2*?&%; */ )$5= ' 1/ A*/#":) '/# c'5 1G b< QPrinter $)&) +=& ).)+&!B) 2-*/+&- #-*,&-)7 1/ f/*?< *+ 0&/&-'+&)
:'. +='+ +=& '%2=' 5"!2"/&/+ "C +=& )"$-5& #&C*/&) *+) +-'/)%$5&/5.7 >*0$-& D7EE )=":) +=& -&)$%+ "C Q")+G5-*2+ '/# )&/#) *+ +" lp "- lpr 9"- +" +=& 2-"0-'! )&+ $)*/0 QPrinter::setPrintProgram();7
#-':*/0 ' )&!*R+-'/)2'-&/+ F$++&-C%. "/ +"2 "C ' 5=&5(&- 2'++&-/ :*+= +=& #*CC&-&/+ !"#&)7 QPrinter 5'/ '%)" F& $)&# +" 0&/&-'+& QT> C*%&) F. 5'%%*/0 setOutputFormat(QPrinter::PdfFormat)7
Y"!2")*+*"/) !"#&) '-& )&+ $)*/0 QPainter::setCompositionMode()7 >"- &?'!2%&< =&-&B) =": +"
5-&'+& ' QImage 5"/+'*/*/0 +=& b1d "C +=& F$++&-C%. '/# +=& 5=&5(&- 2'++&-/@
A& '))$!& +='+ +=& PrintWindow 5%')) =') ' !&!F&- ,'-*'F%& 5'%%&# printer "C +.2& QPrinter7 A&
5"$%# )*!2%. =',& 5-&'+&# +=& QPrinter "/ +=& )+'5( */ printImage()< F$+ +=&/ *+ :"$%# /"+
-&!&!F&- +=& $)&-B) )&++*/0) C-"! "/& 2-*/+ -$/ +" '/"+=&-7
A& 5-&'+& ' QPrintDialog '/# 5'%% exec() +" )=": *+7 I+ -&+$-/) true *C +=& $)&- 5%*5(&# +=& 1g
F$++"/U "+=&-:*)&< *+ -&+$-/) false7 KC+&- +=& 5'%% +" exec()< +=& QPrinter "FJ&5+ *) -&'#. +" $)&7 9I+ *)
'%)" 2"))*F%& +" 2-*/+ :*+="$+ $)*/0 ' QPrintDialog< F. #*-&5+%. 5'%%*/0 QPrinter !&!F&- C$/5+*"/) +"
)&+ +=*/0) $27;
^&?+< :& 5-&'+& ' QPainter +" #-': "/ +=& QPrinter7 A& )&+ +=& :*/#": +" +=& *!'0&B) -&5+'/0%& '/#
+=& ,*&:2"-+ +" ' -&5+'/0%& :*+= +=& )'!& ')2&5+ -'+*"< '/# :& #-': +=& *!'0& '+ 2")*+*"/ 9X< X;7
N. #&C'$%+< QPainterB) :*/#": *) */*+*'%*H&# )" +='+ +=& 2-*/+&- '22&'-) +" =',& ' )*!*%'- -&)"%$+*"/ ')
+=& )5-&&/ 9$)$'%%. )"!&:=&-& F&+:&&/ ]_ '/# EXX #"+) 2&- */5=;< !'(*/0 *+ &'). +" -&$)& :*#0&+
2'*/+*/0 5"#& C"- 2-*/+*/07 L&-&< *+ #*#/B+ !'++&-< F&5'$)& :& )&+ "$- ":/ :*/#":7
Q-*/+*/0 *+&!) +='+ +'(& $2 /" !"-& +='/ ' )*/0%& 2'0& *) )*!2%&< F$+ !'/. '22%*5'+*"/) /&&# +"
2-*/+ !$%+*2%& 2'0&)7 >"- +=")&< :& /&&# +" 2'*/+ "/& 2'0& '+ ' +*!& '/# 5'%% newPage() +" '#,'/5&
+" +=& /&?+ 2'0&7 8=*) -'*)&) +=& 2-"F%&! "C #&+&-!*/*/0 =": !$5= */C"-!'+*"/ :& 5'/ 2-*/+ "/
&'5= 2'0&7 8=&-& '-& +:" !'*/ '22-"'5=&) +" ='/#%*/0 !$%+*R2'0& #"5$!&/+) :*+= 6+@
• A& 5'/ 5"/,&-+ "$- #'+' +" L8c4 '/# -&/#&- *+ $)*/0 QTextdocument< 6+B) -*5= +&?+ &/0*/&7
• A& 5'/ 2&-C"-! +=& #-':*/0 '/# +=& 2'0& F-&'(*/0 F. ='/#7
A& :*%% -&,*&: F"+= '22-"'5=&) */ +$-/7 K) '/ &?'!2%&< :& :*%% 2-*/+ ' C%":&- 0$*#&@ ' %*)+ "C C%":&-
/'!&)< &'5= :*+= ' +&?+$'% #&)5-*2+*"/7 Z'5= &/+-. */ +=& 0$*#& *) )+"-&# ') ' )+-*/0 "C +=& C"-!'+
V"-8!@0!&6$, *,)"V< C"- &?'!2%&@
G*/5& &'5= C%":&-B) #'+' *) -&2-&)&/+&# F. ' )*/0%& )+-*/0< :& 5'/ -&2-&)&/+ '%% +=& C%":&-) */ +=&
0$*#& $)*/0 "/& QStringList7 L&-&B) +=& C$/5+*"/ +='+ 2-*/+) ' C%":&- 0$*#& $)*/0 6+B) -*5= +&?+
&/0*/&@
8=& paginate() C$/5+*"/ #*)+-*F$+&) +=& C%":&- 0$*#& &/+-*&) */+" 2'0&)7 I+ -&%*&) "/ +=& entryHeight()
C$/5+*"/< :=*5= 5"!2$+&) +=& =&*0=+ "C "/& &/+-.7 I+ '%)" +'(&) */+" '55"$/+ +=& ,&-+*5'% 0'2) '+ +=&
+"2 '/# F"++"! "C +=& 2'0&< "C )*H& LargeGap7
A& *+&-'+& +=-"$0= +=& &/+-*&) '/# '22&/# +=&! +" +=& 5$--&/+ 2'0& $/+*% :& 5"!& +" '/ &/+-. +='+
#"&)/B+ C*+U +=&/ :& '22&/# +=& 5$--&/+ 2'0& +" +=& pages %*)+ '/# )+'-+ ' /&: 2'0&7
!"#$%&'()=(&L&/2-F%$&%1.$3*+&283-#.
KC+&- )&++*/0 $2 +=& 2-*/+&- '/# 5"/)+-$5+*/0 +=& 2'*/+&-< :& 5'%% +=& paginate() =&%2&- C$/5+*"/ +"
#&+&-!*/& :=*5= &/+-. )="$%# '22&'- "/ :=*5= 2'0&7 8=& -&)$%+ "C +=*) *) ' %*)+ "C QStringList)< :*+=
numCopies() C"- +=& )'(& "C )*!2%*5*+.7;
!"#$%&'()@(&<$!1.!1"&8&/2-F%$&"#!4%&#+!1" QPainter
[View full size image]
A& )+'-+ F. #&+&-!*/*/0 +=& -'/0& +" 2-*/+7 QPrinterB) fromPage() '/# toPage() C$/5+*"/) -&+$-/ +=&
2'0& /$!F&-) )&%&5+&# F. +=& $)&-< "- X *C /" -'/0& :') 5=")&/7 A& )$F+-'5+ E F&5'$)& "$- pages 8=& printPage() C$/5+*"/ *+&-'+&) +=-"$0= '%% +=& C%":&- 0$*#& &/+-*&) '/# 2-*/+) +=&! $)*/0 +:" 5'%%)
%*)+ *) */#&?&# C-"! X< '/# )&+ firstPage '/# lastPage +" 5",&- +=& C$%% -'/0& *C +=& $)&- #*#/B+ )&+ +" printBox()@ "/& C"- +=& +*+%& 9+=& C%":&-B) /'!&; '/# "/& C"- +=& F"#. 9*+) #&)5-*2+*"/;7 I+ '%)"
'/. -'/0&7 #-':) +=& 2'0& /$!F&- 5&/+&-&# '+ +=& F"++"! "C +=& 2'0&7
8=&/ :& 2-*/+ &'5= 2'0&7 8=& "$+&- for %""2 *+&-'+&) ') !'/. +*!&) ') /&5&))'-. +" 2-"#$5& +=& !"#$%&'()C(&I?%&/2-F%$&"#!4%*+&98"%&283-#.
/$!F&- "C 5"2*&) -&P$&)+&# F. +=& $)&-7 c")+ 2-*/+&- #-*,&-) )$22"-+ !$%+*2%& 5"2*&)< )" C"- +=")&
QPrinter::numCopies() '%:'.) -&+$-/) E7 IC +=& 2-*/+&- #-*,&- 5'/B+ ='/#%& !$%+*2%& 5"2*&)<
numCopies() -&+$-/) +=& /$!F&- "C 5"2*&) -&P$&)+&# F. +=& $)&-< '/# +=& '22%*5'+*"/ *) -&)2"/)*F%&
C"- 2-*/+*/0 +='+ /$!F&- "C 5"2*&)7 9I/ +=& QImage &?'!2%& &'-%*&- */ +=*) )&5+*"/< :& *0/"-&#
8" )=": =": +=*) :"-()< :& :*%% -&,*&: +=& 5"#& "C +=& 8&+-'=&#-"/ '22%*5'+*"/ )=":/ */ >*0$-&
D7E]7 8=& '22%*5'+*"/ 2-&)&/+) ' ST +&+-'=&#-"/< "- C"$-R)*#&# #*&< :*+= &'5= C'5& #-':/ $)*/0 '
#*CC&-&/+ 5"%"-7 8=& $)&- 5'/ -"+'+& +=& +&+-'=&#-"/ F. 2-&))*/0 ' !"$)& F$++"/ '/# #-'00*/07 8=&
$)&- 5'/ )&+ +=& 5"%"- "C ' C'5& F. #"$F%&R5%*5(*/0 *+ '/# 5="")*/0 ' 5"%"- C-"! +=& QColorDialog +='+
2"2) $27
!"#$%&'()D(&I?%&I%.$8?%4$-1&8992!58.!-1
T-':*/0 0-'2=*5) :*+= 12&/34 C-"! ' 6+ '22%*5'+*"/ *) )+-'*0=+C"-:'-#@ A& !$)+ )$F5%')) !" Tetrahedron#$%&''#()!"*(+'#,*-. QGLWidget/# !" initializeGL()0 resizeGL()0#&)1 paintGL()
QGLWidget< -&*!2%&!&/+ ' C&: ,*-+$'% C$/5+*"/)< '/# %*/( +=& '22%*5'+*"/ '0'*/)+ +=& A*B !"C+ '/# ,2)$+(-)'#&*"#*"(.3%".")+"1#,*-. QGLWidget/# !"#.-2'"#"4")+#!&)1%"*'#&*"#*"(.3%".")+"1#,*-.
12&/34 %*F-'-*&)7 N&5'$)& QGLWidget */=&-*+) C-"! QWidget< !")+ "C :='+ :& '%-&'#. (/": )+*%% QWidget#&' 2'2&%/
'22%*&)7 8=& !'*/ #*CC&-&/5& *) +='+ :& $)& )+'/#'-# 12&/34 C$/5+*"/) +" 2&-C"-! +=& #-':*/0
*/)+&'# "C QPainter7
Tetrahedron::Tetrahedron(QWidget *parent)
: QGLWidget(parent)
{ {
setFormat(QGLFormat(QGL::DoubleBuffer | QGL::DepthBuffer)); static const GLfloat P1[3] = { 0.0, -1.0, +2.0 };
rotationX = -21.0; static const GLfloat P2[3] = { +1.73205081, -1.0, -1.0 };
rotationY = -57.0; static const GLfloat P3[3] = { -1.73205081, -1.0, -1.0 };
rotationZ = 0.0; static const GLfloat P4[3] = { 0.0, +2.0, 0.0 };
faceColors[0] = Qt::red; static const GLfloat * const coords[4][3] = {
faceColors[1] = Qt::green; { P1, P2, P3 }, { P1, P3, P4 }, { P1, P4, P2 }, { P2, P4, P3 }
faceColors[2] = Qt::blue; };
faceColors[3] = Qt::yellow; glMatrixMode(GL_MODELVIEW);
} glLoadIdentity();
glTranslatef(0.0, 0.0, -10.0);
glRotatef(rotationX, 1.0, 0.0, 0.0);
glRotatef(rotationY, 0.0, 1.0, 0.0);
5)#+!"#$-)'+*2$+-*0#6"#$&%% QGLWidget::setFormat()#+-#'3"$(,7#+!"#83")9:#1('3%&7#$-)+";+0#&)1#6" glRotatef(rotationZ, 0.0, 0.0, 1.0);
()(+(&%(<"#+!"#$%&''='#3*(4&+"#4&*(&>%"'/ for (int i = 0; i < 4; ++i) {
glLoadName(i);
glBegin(GL_TRIANGLES);
void Tetrahedron::initializeGL() qglColor(faceColors[i]);
{ for (int j = 0; j < 3; ++j) {
qglClearColor(Qt::black); glVertex3f(coords[i][j][0], coords[i][j][1],
glShadeModel(GL_FLAT); coords[i][j][2]);
glEnable(GL_DEPTH_TEST); }
glEnable(GL_CULL_FACE); glEnd();
} }
}
!" faceAtPosition()#,2)$+(-)#*"+2*)'#+!"#)2.>"*#-,#+!"#,&$"#&+#&#$"*+&()#3-'(+(-)#-)#+!"#6(1@"+0#-*
GH#(,#+!"*"#('#)-#,&$"#&+#+!&+#3-'(+(-)/# !"#$-1"#,-*#1"+"*.()()@#+!('#()#83")9:#('#&#>(+#$-.3%($&+"1/
E''")+(&%%70#6!&+#6"#1-#('#*")1"*#+!"#'$")"#() GL_SELECT#.-1"#+-#+&B"#&14&)+&@"#-,#83")9:='
3($B()@#$&3&>(%(+("'#&)1#+!")#*"+*("4"#+!"#,&$"#)2.>"*#I(+'#J)&."JK#,*-.#+!"#83")9:#!(+#*"$-*1/
L"*"=' main.cppM
#include <QApplication>
#include <iostream>
#include "tetrahedron.h"
using namespace std;
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
if (!QGLFormat::hasOpenGL()) {
cerr << "This system has no OpenGL support" << endl;
return 1;
}
Tetrahedron tetrahedron;
&$$"3+'#+";+2&%#1*&@'#,*-.#-+!"*#&33%($&+(-)'0#&)1#(,#+!"#2'"*#1*-3'#&#,(%"#-)+-#(+0#(+#6(%%#()'"*+#+!"#,(%"
)&."#()+-#+!" +";+/#Q()$"#1*-3#"4")+'#&*"#3*-3&@&+"1#,*-.#$!(%1#+-#3&*")+0#>7#1('&>%()@#1*-33()@#-)
Chapter 9. Drag and Drop +!" QTextEdit#&)1#")&>%()@#(+#-)#+!"#.&()#6()1-60#6"#@"+#+!"#1*-3#"4")+'#,-*#+!"#6!-%"#6()1-6#()
MainWindow/
• !"#$%!&'()"&'"!*'()+,
• -.,,+)/%!&'0.1/+2'()"&'34,51
void MainWindow::dragEnterEvent(QDragEnterEvent *event)
• 0$%,#+")*'6"!*$%!&
{
if (event->mimeData()->hasFormat("text/uri-list"))
O*&@#&)1#1*-3#('#&#.-1"*)#&)1#()+2(+(4"#6&7#-,#+*&)',"**()@#(),-*.&+(-)#6(+!()#&)#&33%($&+(-)#-* event->acceptProposedAction();
>"+6"")#1(,,"*")+#&33%($&+(-)'/#5+#('#-,+")#3*-4(1"1#()#&11(+(-)#+-#$%(3>-&*1#'233-*+#,-*#.-4()@#&)1 }
$-37()@#1&+&/
F!")#+!"#2'"*#.-4"'#+!"#.-2'"#$2*'-*#6!(%"#!-%1()@#+!"#%",+#.-2'"#>2++-)0#6"#$-)'(1"*#'+&*+()@#&
!"#T*-?"$+#W!--'"*#&33%($&+(-)#3*"'")+'#+!"#2'"*#6(+!#+6-#%('+#6(1@"+'0#3-32%&+"1#6(+!#)&."'/#E&$! 1*&@/#F"#$-.32+"#+!"#1('+&)$"#>"+6"")#+!"#$2**")+#.-2'"#3-'(+(-)#&)1#+!"#3-'(+(-)#6!"*"#+!"#%",+
%('+#6(1@"+#*"3*"'")+'#*-?"$+/# !"#2'"*#$&)#1*&@#&)1#1*-3#+!"#)&."'#()#+!"#%('+#6(1@"+'#+-#.-4"#& .-2'"#>2++-)#6&'#3*"''"1/#5, +!"#1('+&)$"#('#%&*@"*#+!&) QApplication='#*"$-..")1"1#1*&@#'+&*+
3"*'-)#,*-.#-)"#3*-?"$+#+-#&)-+!"*/ 1('+&)$"#I)-*.&%%7#Y#3(;"%'K0#6"#$&%%#+!"#3*(4&+"#,2)$+(-) startDrag()#+-#'+&*+#1*&@@()@/# !('#&4-(1'
()(+(&+()@#*&@#?2'+#>"$&2'"#+!"#2'"*='#!&)1#'!&B"'/
!"#1*&@#&)1#1*-3#$-1"#('#&%%#%-$&+"1#()#+!" QListWidget#'2>$%&''/#L"*"='#+!"#$%&''#1",()(+(-)M
void ProjectListWidget::startDrag()
{
class ProjectListWidget : public QListWidget QListWidgetItem *item = currentItem();
{ if (item) {
Q_OBJECT QMimeData *mimeData = new QMimeData;
public: mimeData->setText(item->text());
ProjectListWidget(QWidget *parent = 0); QDrag *drag = new QDrag(this);
protected: drag->setMimeData(mimeData);
void mousePressEvent(QMouseEvent *event); drag->setPixmap(QPixmap(":/images/person.png"));
void mouseMoveEvent(QMouseEvent *event); if (drag->start(Qt::MoveAction) == Qt::MoveAction)
void dragEnterEvent(QDragEnterEvent *event); delete item;
void dragMoveEvent(QDragMoveEvent *event); }
void dropEvent(QDropEvent *event); }
private:
void startDrag();
QPoint startPos;
}; 5) startDrag()0#6"#$*"&+"#&)#->?"$+#-,#+73" QDrag#6(+! this#&'#(+'#3&*")+/# !" QDrag#->?"$+#'+-*"'#+!"
1&+&#()#& QMimeData#->?"$+/#N-* +!('#";&.3%"0#6"#3*-4(1"#+!"#1&+&#&'#& text/plain#'+*()@#2'()@
QMimeData::setText()/ QMimeData#3*-4(1"'#'"4"*&%#,2)$+(-)'#,-*#!&)1%()@#+!"#.-'+#$-..-)#+73"'#-,
!" ProjectListWidget#$%&''#*"(.3%".")+'#,(4"#"4")+#!&)1%"*'#1"$%&*"1#() QWidget/ 1*&@'#I(.&@"'0#SC:'0#$-%-*'0#"+$/K#&)1#$&)#!&)1%"#&*>(+*&*7#R5RE#+73"'#*"3*"'")+"1#&' QByteArray'/
!"#$&%%#+- QDrag::setPixmap()#'"+'#+!"#($-)#+!&+#,-%%-6'#+!"#$2*'-*#6!(%"#+!"#1*&@#('#+&B()@#3%&$"/
A%+!-2@!#6"#3*-4(1"#+!"#1&+&#()#+!*""#1(,,"*")+#,-*.&+'0#6"#-)%7#&$$"3+#+6-#-,#+!".#() dropEvent()/
5,#+!"#2'"*#1*&@'#$"%%'#,*-.#& QTableWidget#+-#&)#L R:#"1(+-*0#6"#6&)+#+!"#$"%%'#+-#>"#$-)4"*+"1#()+- QVariant TableMimeData::retrieveData(const QString &format,
&)#L R:#+&>%"/#D2+#(,#+!"#2'"*#1*&@'#&*>(+*&*7#L R:#()+-#& QTableWidget0#6"#1-)=+#6&)+#+-#&$$"3+#(+/ QVariant::Type preferredType) const
{
if (format == "text/plain") {
-#.&B"#+!('#";&.3%"#6-*B0#6"#&%'-#)""1#+-#$&%% setAcceptDrops(true)#&)1 return rangeAsPlainText();
setSelectionMode(ContiguousSelection)#()#+!" MyTableWidget#$-)'+*2$+-*/ } else if (format == "text/csv") {
return toCsv(rangeAsPlainText());
F"#6(%%#)-6#*"1-#+!"#";&.3%"0#>2+#+!('#+(."#6"#6(%%#'2>$%&'' QMimeData#+-#3-'+3-)"#-*#&4-(1#+!" } else if (format == "text/html") {
I3-+")+(&%%7#";3")'(4"K#$-)4"*'(-)'#>"+6"") QTableWidget-Item'#&)1 QByteArray/#L"*"='#+!" return toHtml(rangeAsPlainText());
} else {
1",()(+(-)#-,#-2*#'2>$%&''M
return QMimeData::retrieveData(format, preferredType);
}
}
class TableMimeData : public QMimeData
{
Q_OBJECT
public: !" retrieveData()#,2)$+(-)#*"+2*)'#+!"#1&+&#,-*#&#@(4")#R5RE#+73"#&'#& QVariant/# !"#4&%2"#-,#+!"
format#3&*&."+"*#('#)-*.&%%7#-)"#-,#+!"#'+*()@'#*"+2*)"1#>7 formats()0#>2+#6"#$&))-+#&''2."#+!&+0 $%(3>-&*1#2'"#()#+!"#Q3*"&1'!""+#&33%($&+(-)#,*-. W!&3+"*#Y/
'()$"#)-+#&%%#&33%($&+(-)'#$!"$B#+!"#R5RE#+73"#&@&()'+ formats()/# !"#@"++"*#,2)$+(-)' text()0
html()0 urls()0 image-Data()0 colorData()0#&)1 data()#3*-4(1"1#>7 QMimeData#&*"#(.3%".")+"1#() N-*#'-."#&33%($&+(-)'0#+!"#>2(%+G()#,2)$+(-)&%(+7#.(@!+ )-+#>"#'2,,($(")+/#N-*#";&.3%"0#6"#.(@!+#6&)+
+"*.'#-, retrieveData()/ +-#3*-4(1"#1&+&#+!&+#(')=+#?2'+#+";+#-*#&)#(.&@"0#-*#6"#.(@!+#6&)+#+-#3*-4(1"#1&+&#()#.&)7#1(,,"*")+
,-*.&+'#,-*#.&;(.2.#()+"*-3"*&>(%(+7#6(+!#-+!"*#&33%($&+(-)'/# !"#(''2"#('#4"*7#'(.(%&*#+-#6!&+#6"
!" preferredType#3&*&."+"*#@(4"'#2'#&#!()+#&>-2+#6!($!#+73"#6"#'!-2%1#32+#()#+!" QVariant/#L"*"0 ")$-2)+"*"1#"&*%("*#6(+!#1*&@#&)1#1*-30#&)1#+!"#&)'6"*#('#&%'-#'(.(%&*M#F"#$&)#'2>$%&'' QMimeData
6"#(@)-*"#(+#&)1#+*2'+ QMimeData#+-#$-)4"*+#+!"#*"+2*)#4&%2"#()+-#+!"#1"'(*"1#+73"0#(,#)"$"''&*7/ &)1#*"(.3%".")+#&#,"6#4(*+2&%#,2)$+(-)'/
5,#-2*#&33%($&+(-)#'233-*+'#1*&@#&)1#1*-3#+!*-2@!#&#$2'+-. QMimeData#'2>$%&''0#6"#$&)#'(.3%7#*"2'"
void MyTableWidget::dropEvent(QDropEvent *event) +!" QMimeData#'2>$%&''#&)1#32+#(+#-)#+!"#$%(3>-&*1#2'()@#+!" setMimeData()#,2)$+(-)/# -#*"+*("4"#+!"
{ 1&+&0#6"#$&)#$&%% mimeData()#-)#+!"#$%(3>-&*1/
const TableMimeData *tableData =
qobject_cast<const TableMimeData *>(event->mimeData());
8)#`HH0#(+#('#2'2&%%7#3-''(>%"#+-#3&'+"#&#'"%"$+(-)#>7#$%($B()@#+!"#.(11%"#>2++-)#-,#&#+!*""G>2++-)
if (tableData) {
.-2'"/# !('#('#1-)"#2'()@#&#'"3&*&+"#J'"%"$+(-)J#$%(3>-&*1/#5,#7-2#6&)+#7-2*#6(1@"+'#+-#'233-*+#+!('
const QTableWidget *otherTable = tableData->tableWidget();
QTableWidgetSelectionRange otherRange = tableData->range(); B()1#-,#$%(3>-&*1#&'#6"%%#&'#+!"#'+&)1&*1#-)"0#7-2#.2'+#3&'' QClipboard::Selection#&'#&)#&11(+(-)&%
... &*@2.")+#+-#+!"#4&*(-2'#$%(3>-&*1#$&%%'/#N-*#";&.3%"0#!"*"='#!-6#6"#6-2%1#*"(.3%".")+
event->acceptProposedAction(); mouseReleaseEvent()#()#&#+";+#"1(+-*#+-#'233-*+#3&'+()@#2'()@#+!"#.(11%"#.-2'"#>2++-)M
} else if (event->mimeData()->hasFormat("text/csv")) {
QByteArray csvData = event->mimeData()->data("text/csv");
QString csvText = QString::fromUtf8(csvData); void MyTextEditor::mouseReleaseEvent(QMouseEvent *event)
... {
event->acceptProposedAction(); QClipboard *clipboard = QApplication::clipboard();
} else if (event->mimeData()->hasFormat("text/plain")) { if (event->button() == Qt::MidButton
QString plainText = event->mimeData()->text(); && clipboard->supportsSelection()) {
... QString text = clipboard->text(QClipboard::Selection);
event->acceptProposedAction(); pasteText(text);
} }
QTableWidget::mouseMoveEvent(event); }
}
5)#+!('#";&.3%"0#6"#")$-1"1#+!"#WQ_#+";+#2'()@#+!"#S NG^#")$-1()@/#5,#6"#6&)+#+-#>"#$"*+&()#-,
2'()@#+!"#*(@!+#")$-1()@0#6"#$-2%1#2'"#+!" charset#3&*&."+"*#-,#+!" text/plain#R5RE#+73"#+-
'3"$(,7#&)#";3%($(+#")$-1()@/#L"*"#&*"#&#,"6#";&.3%"'M
text/plain;charset=US-ASCII
text/plain;charset=ISO-8859-1
text/plain;charset=Shift_JIS
text/plain;charset=UTF-8
Clipboard Handling
R-'+#&33%($&+(-)'#.&B"#2'"#-,#P+='#>2(%+G()#$%(3>-&*1#!&)1%()@#()#-)"#6&7#-*#&)-+!"*/#N-*#";&.3%"0
+!" QTextEdit#$%&''#3*-4(1"' cut()0 copy()0#&)1 paste()#'%-+'#&'#6"%%#&'#B"7>-&*1#'!-*+$2+'0#'-#%(++%"
-*#)-#&11(+(-)&%#$-1"#('#*"Z2(*"1/
F!")#6*(+()@#-2*#-6)#$%&''"'0#6"#$&)#&$$"''#+!"#$%(3>-&*1#+!*-2@! QApplication::clipboard()0
6!($!#*"+2*)'#-()+"*#+-#+!"#&33%($&+(-)=' QClipboard#->?"$+/#L&)1%()@#+!"#'7'+".#$%(3>-&*1#('
"&'7M#W&%% setText()0 setImage()0#-* setPixmap()#+-#32+#1&+&#-)+-#+!"#$%(3>-&*10#&)1#$&%% text()0
image()0#-* pixmap()#+-#*"+*("4"#1&+&#,*-.#+!"#$%(3>-&*1/#F"#!&4"#&%*"&17#'"")#";&.3%"'#-,
Chapter 10. Item View Classes
• 71%!&'/85'9/52':%5;'0+!<5!%5!=5'0$"1151
• 71%!&'>)5*5?%!5*'@+*5$1
• 92,$525!/%!&'0.1/+2'@+*5$1
• 92,$525!/%!&'0.1/+2'(5$5&"/51
R&)7#&33%($&+(-)'#%"+#+!"#2'"*#'"&*$!0#4("60#&)1#"1(+#()1(4(12&%#(+".'#+!&+#>"%-)@#+-#&+&#'"+/# !"
1&+&#.(@!+#>"#!"%1#()#,(%"'#-*#&$$"''"1#,*-.#&+&>&'"#-*#&#)"+6-*B#'"*4"*/# !"#'+&)1&*1#&33*-&$!
+-#1"&%()@#6(+!#1&+&#'"+'#%(B"#+!('#('#+-#2'"#P+='#(+".#4("6#$%&''"'/ 5)#.&)7#'(+2&+(-)'0#6"#-)%7#)""1#+-#3*"'")+#*"%&+(4"%7#'.&%%#)2.>"*'#-,#(+".'#+-#+!"#2'"*/#5)#+!"'"
$-..-)#$&'"'0#6"#$&)#2'"#P+='#$-)4")(")$"#(+".#4("6#$%&''"'#I QListWidget0 QTableWidget0#&)1
5)#"&*%("*#4"*'(-)'#-,#P+0#+!" (+".#4("6#6(1@"+'#6"*"#3-32%&+"1#6(+!#+!"#")+(*"#$-)+")+'#-,#&+& QTReeWidgetK#&)1#3-32%&+"#+!".#6(+!#(+".'#1(*"$+%7/# !"'"#$%&''"'#>"!&4"#()#&#'(.(%&*#6&7#+-#+!"
'"+[#+!"#2'"*'#6-2%1#3"*,-*.#&%%#+!"(*#'"&*$!"'#&)1#"1(+'#-)#+!"#1&+&#!"%1#()#+!"#6(1@"+0#&)1#&+ (+".#4("6#$%&''"'#3*-4(1"1#>7#"&*%("*#4"*'(-)'#-,#P+/# !"7#'+-*"#+!"(*#1&+&#()#J(+".'J#I,-*#";&.3%"0#&
'-."#3-()+#+!"#$!&)@"'#6-2%1#>"#6*(++")#>&$B#+-#+!"#1&+&#'-2*$"/#A%+!-2@!#'(.3%"#+-#2)1"*'+&)1 QTableWidget#$-)+&()' QTableWidgetItem'K/#5)+"*)&%%70#+!"#$-)4")(")$"#$%&''"'#2'"#$2'+-.#.-1"%'
&)1#2'"0#+!('#&33*-&$!#1-"')=+#'$&%"#6"%%#+-#4"*7#%&*@"#1&+&#'"+'#&)1#1-"')=+#%")1#(+'"%,#+-#'(+2&+(-)' +!&+#.&B"#+!"#(+".'#4('(>%"#+-#+!"#4("6'/
6!"*"#6"#6&)+#+-#1('3%&7#+!"#'&."#1&+&#'"+#()#+6-#-*#.-*"#1(,,"*")+#6(1@"+'/
N-*#%&*@"#1&+&#'"+'0#123%($&+()@#+!"#1&+&#('#-,+")#)-+#&)#-3+(-)/#5)#+!"'"#$&'"'0#6"#$&)#2'"#P+='
!"#Q.&%%+&%B#%&)@2&@"#3-32%&*(<"1#&#,%";(>%"#&33*-&$!#+-#4('2&%(<()@#%&*@"#1&+&#'"+'M 4("6'#IQListView0 QTableView0#&)1 QtreeViewK0#()#$-)?2)$+(-)#6(+!#&+&#.-1"%0#6!($!#$&)#>"#&
.-1"%4("6$-)+*-%%"*#IR_WK/#5)#+!"#R_W#&33*-&$!0#+!" -./)0#*"3*"'")+'#+!"#1&+&#'"+#&)1#(' $2'+-.#.-1"%#-*#-)"#-,#P+='#3*"1",()"1#.-1"%'/#N-*#";&.3%"0#(,#+!"#1&+&#'"+#('#!"%1#()#&+&>&'"0
*"'3-)'(>%"#,-*#,"+$!()@#+!"#1&+&#+!&+#('#)""1"1#,-*#4("6()@#&)1#,-*#6*(+()@#>&$B#&)7#$!&)@"'/#E&$! 6"#$&)#$-.>()"#& QTableView#6(+!#& QSqlTableModel/
+73"#-,#1&+&#'"+#!&'#(+'#-6)#.-1"%0#>2+#+!"#AT5#+!&+#+!"#.-1"%'#3*-4(1"#+-#+!"#4("6'#('#2)(,-*.#)-
.&++"*#6!&+#+!"#2)1"*%7()@#1&+&#'"+/# !" 12)3#3*"'")+'#+!"#1&+&#+-#+!"#2'"*/#F(+!#&)7#%&*@"#1&+&
'"+#-)%7#&#%(.(+"1#&.-2)+#-,#1&+(%%#>"#4('(>%"#&+#&)7#-)"#+(."0#'-#+!&+#('#+!"#-)%7#1&+&#+!&+#+!"
4("6#&'B' ,-*/# !" 4.*&5.00)5#."1(&+"'#>"+6"")#+!"#2'"*#&)1#+!"#4("60#$-)4"*+()@#2'"*#&$+(-)'#()+- Using the Item View Convenience Classes
*"Z2"'+'#+-#)&4(@&+"#-*#"1(+#1&+&0#6!($!#+!"#4("6#+!")#+*&)'.(+'#+-#+!"#.-1"%#&'#)"$"''&*7/
S'()@#P+='#(+".#4("6#$-)4")(")$"#'2>$%&''"'#('#2'2&%%7#'(.3%"*#+!&)#1",()()@#&#$2'+-.#.-1"%#&)1#('
!"#$%&)7()(&8092&:-;%5<=!%>&3$/+!0%/0#$% &33*-3*(&+"#6!")#6"#1-)=+#)""1#+!"#>")",(+'#-,#'"3&*&+()@#+!"#.-1"%#&)1#+!"#4("6/#F"#2'"1#+!('
+"$!)(Z2"#() W!&3+"*#Y#6!")#6"#'2>$%&''"1 QTableWidget#&)1 QTableWidgetItem#+-#(.3%".")+
'3*"&1'!""+#,2)$+(-)&%(+7/
5)#+!('#'"$+(-)0#6"#6(%%#'!-6#!-6#+-#2'"#+!"#$-)4")(")$"#(+".#4("6#'2>$%&''"'#+-#1('3%&7#(+".'/# !"
,(*'+#";&.3%"#'!-6'#&#*"&1G-)%7 QListWidget0#+!"#'"$-)1#";&.3%"#'!-6'#&)#"1(+&>%" QTableWidget0
&)1#+!"#+!(*1#";&.3%"#'!-6'#&#*"&1G-)%7 QtreeWidget/
F"#>"@()#6(+!#&#'(.3%"#1(&%-@#+!&+#%"+'#+!"#2'"*#3($B#&#,%-6$!&*+#'7.>-%#,*-.#&#%('+/#E&$!#(+".
$-)'('+'#-,#&)#($-)0#&#+";+0#&)1#)(Z2"#5O/
S'()@#P+='#.-1"%V4("6#&*$!(+"$+2*"0#6"#$&)#2'"#.-1"%'#+!&+#-)%7#,"+$!#+!"#1&+&#+!&+#('#&$+2&%%7
)""1"1#,-*#1('3%&7#()#+!"#4("6/# !('#.&B"'#!&)1%()@#4"*7#%&*@"#1&+&#'"+'#.2$!#,&'+"*#&)1#%"''
.".-*7#!2)@*7#+!&)#*"&1()@#&%%#+!"#1&+&/#A)1#>7#*"@('+"*()@#&#.-1"%#6(+!#+6-#-*#.-*"#4("6'0#6"
$&)#@(4"#+!"#2'"*#+!"#-33-*+2)(+7#-,#4("6()@#&)1#()+"*&$+()@#6(+!#+!"#1&+&#()#1(,,"*")+#6&7'0#6(+!
%(++%"#-4"*!"&1/#P+#&2+-.&+($&%%7#B""3'#.2%+(3%"#4("6'#()#'7)$0#*",%"$+()@#$!&)@"'#+-#-)"#()#&%%#+!"
-+!"*'/#A)#&11(+(-)&%#>")",(+#-,#+!"#.-1"%V4("6#&*$!(+"$+2*"#('#+!&+#(,#6"#1"$(1"#+-#$!&)@"#!-6#+!"
2)1"*%7()@#1&+&#'"+#('#'+-*"10#6"#?2'+#)""1#+-#$!&)@"#+!"#.-1"%[#+!"#4("6'#6(%%#$-)+()2"#+-#>"!&4"
$-**"$+%7/
!"#$%&)7(?(&@6%&:-;%5&/36&2%$=%&:#50!45%&=!%>2
if (item)
:"+='#'+&*+#6(+!#&)#";+*&$+#,*-.#+!"#1(&%-@='#!"&1"*#,(%"M id = item->data(Qt::UserRole).toInt();
}
QDialog::done(result);
}
class FlowChartSymbolPicker : public QDialog
{
Q_OBJECT
public: !" done()#,2)$+(-)#('#*"(.3%".")+"1#,*-. QDialog/#5+#('#$&%%"1#6!")#+!"#2'"*#3*"''"'#8a#-*#W&)$"%/
FlowChartSymbolPicker(const QMap<int, QString> &symbolMap, 5,#+!"#2'"*#$%($B"1#8a0#6"#*"+*("4"#+!"#*"%"4&)+#(+".#&)1#";+*&$+#+!"#5O#2'()@#+!" data()#,2)$+(-)/#5,
QWidget *parent = 0); 6"#6"*"#()+"*"'+"1#()#+!"#(+".='#+";+0#6"#$-2%1#*"+*("4"#(+#>7#$&%%()@ item-
int selectedId() const { return id; } >data(Qt::DisplayRole).toString()#-*#.-*"#$-)4")(")+%70 item->text()/
void done(int result);
...
}; D7#1",&2%+0 QListWidget#('#*"&1G-)%7/#5,#6"#6&)+"1#+!"#2'"*#+-#"1(+#+!"#(+".'0#6"#$-2%1#'"+#+!"#4("6='
"1(+#+*(@@"*'#2'()@ QAbstractItemView::setEditTriggers()[#,-*#";&.3%"0#&#'"++()@#-,
QAbstractItemView::AnyKeyPressed#."&)'#+!&+#+!"#2'"*#$&)#>"@()#"1(+()@#&)#(+".#?2'+#>7#'+&*+()@#+-
+73"/#A%+"*)&+(4"%70#6"#$-2%1#3*-4(1"#&)#E1(+#>2++-)#I&)1#3"*!&3'#A11#&)1#O"%"+"#>2++-)'K#&)1
F!")#6"#$-)'+*2$+#+!"#1(&%-@0#6"#.2'+#3&''#(+#& QMap<int, QString>0 &)1#&,+"*#(+#!&'#";"$2+"1#6"
$-))"$+#+!".#+-#'%-+'#'-#+!&+#6"#$-2%1#!&)1%"#+!"#"1(+()@#-3"*&+(-)'#3*-@*&..&+($&%%7/
$&)#*"+*("4"#+!"#$!-'")#5O#I-* GH#(,#+!"#2'"*#1(1)=+#'"%"$+#&)7#(+".K#>7#$&%%()@ selectedId()/
U-6#+!&+#6"#!&4"#'"")#!-6#+-#2'"#&#$-)4")(")$"#(+".#4("6#$%&''#,-*#4("6()@#&)1#'"%"$+()@#1&+&0#6"
FlowChartSymbolPicker::FlowChartSymbolPicker( 6(%%#%--B#&+#&)#";&.3%"#6!"*"#6"#$&)#"1(+#1&+&/#A@&()#6"#&*"#2'()@#(&%-@0#+!('#+(."#-)"#+!&+
const QMap<int, QString> &symbolMap, QWidget *parent) 3*"'")+'#&#'"+#-,#I !"#K#$--*1()&+"'#+!&+#+!"#2'"*#$&)#"1(+/
: QDialog(parent)
{ !"#$%&)7(F(&*+%&1--$;!630%&B%00%$&3445!/30!-6
id = -1;
listWidget = new QListWidget;
listWidget->setIconSize(QSize(60, 60));
QMapIterator<int, QString> i(symbolMap);
while (i.hasNext()) {
i.next();
QListWidgetItem *item = new QListWidgetItem(i.value(),
listWidget);
item->setIcon(iconForSymbol(i.value()));
item->setData(Qt::UserRole, i.key());
}
...
}
!" QTableWidget#$-)'+*2$+-*#+&B"'#+!"#()(+(&%#)2.>"*#-,#+&>%"#*-6'#&)1#$-%2.)'#+-#1('3%&7/#E4"*7
(+".#()#& QTableWidget#('#*"3*"'")+"1#>7#& QTableWidgetItem0#()$%21()@#!-*(<-)+&%#&)1#4"*+($&%#!"&1"*
(+".'/# !" setHorizontalHeaderLabels()#,2)$+(-)#'"+'#+!"#+";+#,-*#"&$!#!-*(<-)+&%#+&>%"#6(1@"+#(+".
+-#+!"#$-**"'3-)1()@#+";+#()#+!"#'+*()@#%('+#(+#('#3&''"1/#D7#1",&2%+0 QTableWidget#3*-4(1"'#"*+($&%
!"&1"*#6(+!#*-6'#%&>"%"1#,*-.#H0#6!($!#('#";&$+%7#6!&+#6"#6&)+0#'-#6"#1-)=+#)""1#+-#'"+#+!"#4"*+($&%
!"&1"*#%&>"%'#.&)2&%%7/
8)$"#6"#!&4"#$*"&+"1#&)1#$")+"*"1#+!"#$-%2.)#%&>"%'0#6"#(+"*&+"#+!*-2@!#+!"#$--*1()&+"#1&+&#+!&+
6&'#3&''"1#()/#N-*#"4"*7#I !"#K#3&(*0#6"#$*"&+"#+6- QTableWidgetItem'#$-**"'3-)1()@#+-#+!" #&)1 #
$--*1()&+"'/# !"#(+".'#&*"#&11"1#+-#+!"#+&>%"#2'()@ QTableWidget::setItem()0#6!($!#+&B"'#&#*-6#&)1
&#$-%2.)#()#&11(+(-)#+-#+!"#(+"./
void CoordinateSetter::addRow()
{ L"*"='#&)#";+*&$+#,*-.#+!"#$-)'+*2$+-*M
int row = tableWidget->rowCount();
tableWidget->insertRow(row);
QTableWidgetItem *item0 = new QTableWidgetItem; SettingsViewer::SettingsViewer(QWidget *parent)
item0->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter); : QDialog(parent)
tableWidget->setItem(row, 0, item0); {
QTableWidgetItem *item1 = new QTableWidgetItem; organization = "Trolltech";
item1->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter); application = "Designer";
tableWidget->setItem(row, 1, item1); treeWidget = new QTreeWidget;
tableWidget->setCurrentItem(item0); treeWidget->setColumnCount(2);
} treeWidget->setHeaderLabels(
QStringList() << tr("Key") << tr("Value"));
treeWidget->header()->setResizeMode(0, QHeaderView::Stretch);
treeWidget->header()->setResizeMode(1, QHeaderView::Stretch);
!" addRow()#'%-+#('#()4-B"1#6!")#+!"#2'"*#$%($B'#+!"#A11#C-6#>2++-)/#F"#&33")1#&#)"6#*-6#2'()@ ...
insertRow()/#5,#+!"#2'"*#&++".3+'#+-#"1(+#&#$"%%#()#+!"#)"6#*-60#+!" QTableWidget#6(%%#&2+-.&+($&%%7 setWindowTitle(tr("Settings Viewer"));
$*"&+"#&#)"6 QTableWidgetItem/ readSettings();
}
N-*#-2*#+!(*1#&)1#,()&%#";&.3%"#-,#P+='#$-)4")(")$"#(+".#4("6#6(1@"+'0#6"#6(%%#%--B#&+#'-."#')(33"+'
QDirModel E)$&3'2%&+"'#+!"#%-$&%#,(%"#'7'+".
A33%($&+(-)#'"++()@'#&*"#'+-*"1#()#&#!("*&*$!7#-,#B"7'#&)1#4&%2"'/# !" addChildSettings()#3*(4&+"
,2)$+(-)#+&B"'#&#'"++()@'#->?"$+0#&*")+ QtreeWidgetItem0#&)1#+!"#$2**")+#J@*-23J/#A#@*-23#('#+!" QSqlQueryModel E)$&3'2%&+"'#&)#QP:#*"'2%+#'"+
QSettings#"Z2(4&%")+#-,#&#,(%"#'7'+".#1(*"$+-*7/# !" addChildSettings()#,2)$+(-)#$&)#$&%%#(+'"%,
*"$2*'(4"%7#+-#+*&4"*'"#&)#&*>(+*&*7#+*""#'+*2$+2*"/# !"#()(+(&%#$&%%#,*-.#+!" readSettings()#,2)$+(-) QSqlTableModel E)$&3'2%&+"'#&)#QP:#+&>%"
3&''"'#b#&'#+!"#3&*")+#(+".#+-#*"3*"'")+#+!"#*--+/
QSqlRelationalTableModel E)$&3'2%&+"'#&)#QP:#+&>%"#6(+!#,-*"(@)#B"7'
QSortFilterProxyModel Q-*+'#&)1V-*#,(%+"*'#&)-+!"*#.-1"%
void SettingsViewer::addChildSettings(QSettings &settings,
QTreeWidgetItem *parent, const QString &group)
{
QTreeWidgetItem *item; 5)#+!('#'"$+(-)0#6"#6(%%#%--B#&+#!-6#+-#2'"#+!" QStringListModel0#+!" QDirModel0#&)1#+!"
settings.beginGroup(group);
QSortFilterProxyModel/# !"#QP:#.-1"%'#&*"#$-4"*"1#() W!&3+"*#H]/
foreach (QString key, settings.childKeys()) {
if (parent) {
item = new QTreeWidgetItem(parent); :"+='#>"@()#6(+!#&#'(.3%"#1(&%-@#+!&+#2'"*'#$&)#2'"#+-#&110#1"%"+"0#&)1#"1(+#& QStringList0#6!"*"
} else { "&$!#'+*()@#*"3*"'")+'#&#+"&.#%"&1"*/
item = new QTreeWidgetItem(treeWidget);
}
item->setText(0, key);
!"#$%&)7(I(&*+%&*%3:&J%3;%$2&3445!/30!-6
item->setText(1, settings.value(key).toString());
}
foreach (QString group, settings.childGroups()) {
if (parent) {
item = new QTreeWidgetItem(parent);
} else {
item = new QTreeWidgetItem(treeWidget);
}
item->setText(0, group);
addChildSettings(settings, item, group);
}
settings.endGroup();
}
U";+0#+!"#,2)$+(-)#(+"*&+"'#-4"*#"4"*7#@*-23#&+#+!"#$2**")+#%"4"%/#N-*#"&$!#@*-230#&#)"6 L"*"='#+!"#*"%"4&)+#";+*&$+#,*-.#+!"#$-)'+*2$+-*M
QtreeWidgetItem#('#$*"&+"1#6(+!#(+'#,(*'+#$-%2.)#'"+#+-#+!"#@*-23='#)&."/# !"#,2)$+(-)#+!")#$&%%'#(+'"%,
*"$2*'(4"%7#6(+!#+!"#@*-23#(+".#&'#+!"#3&*")+#+-#3-32%&+"#+!" QTReeWidget#6(+!#+!"#@*-23='#$!(%1
(+".'/ TeamLeadersDialog::TeamLeadersDialog(const QStringList &leaders,
QWidget *parent)
!"#(+".#4("6#6(1@"+'#'!-6)#()#+!('#'"$+(-)#&%%-6#2'#+-#2'"#&#'+7%"#-,#3*-@*&..()@#+!&+#('#4"*7 : QDialog(parent)
'(.(%&*#+-#+!&+#2'"1#()#"&*%("*#4"*'(-)'#-,#P+M#*"&1()@#&)#")+(*"#1&+&#'"+#()+-#&)#(+".#4("6#6(1@"+0 {
model = new QStringListModel(this);
2'()@#(+".#->?"$+'#+-#*"3*"'")+#1&+&#"%".")+'0#&)1#I(,#+!"#(+".'#&*"#"1(+&>%"K#6*(+()@#>&$B#+-#+!"
model->setStringList(leaders);
1&+&#'-2*$"/#5)#+!"#,-%%-6()@#'"$+(-)'0#6"#6(%%#@-#>"7-)1#+!('#'(.3%"#&33*-&$!#&)1#+&B"#,2%%
listView = new QListView;
&14&)+&@"#-,#P+='#.-1"%V4("6#&*$!(+"$+2*"/ listView->setModel(model);
listView->setEditTriggers(QAbstractItemView::AnyKeyPressed
| QAbstractItemView::DoubleClicked);
...
Using Predefined Models }
P+#3*-4(1"'#'"4"*&%#3*"1",()"1#.-1"%'#,-*#2'"#6(+!#+!"#4("6#$%&''"'M
F"#>"@()#>7#$*"&+()@#&)1#3-32%&+()@#& QStringListModel/#U";+#6"#$*"&+"#& QListView#&)1#'"+#(+'
QStringListModel Q+-*"'#&#%('+#-,#'+*()@' .-1"%#+-#+!"#-)"#6"#!&4"#?2'+#$*"&+"1/#F"#&%'-#'"+#'-."#"1(+()@#+*(@@"*'#+-#&%%-6#+!"#2'"*#+-#"1(+#&
'+*()@#'(.3%7#>7#'+&*+()@#+-#+73"#-)#(+#-*#>7#1-2>%"G$%($B()@#(+/#D7#1",&2%+0#)-#"1(+()@#+*(@@"*'#&*"#'"+
QStandardItemModel Q+-*"'#&*>(+*&*7#!("*&*$!($&%#1&+& -)#& QListView0#.&B()@#+!"#4("6#",,"$+(4"%7#*"&1G-)%7/
void TeamLeadersDialog::insert()
{
int row = listView->currentIndex().row();
model->insertRows(row, 1);
QModelIndex index = model->index(row);
listView->setCurrentIndex(index);
listView->edit(index);
}
8)$"#6"#!&4"#+!"#*-6#)2.>"*0#6"#()'"*+#-)"#)"6#*-6#&+#+!&+#3-'(+(-)/# !"#()'"*+(-)#('#3"*,-*."1
-)#+!"#.-1"%0#&)1#+!"#.-1"%#&2+-.&+($&%%7#231&+"'#+!"#%('+#4("6/#F"#+!")#'"+#+!"#%('+#4("6='#$2**")+ F"#6(%%#>"@()#>7#%--B()@#&+#+!"#$*"&+(-)#&)1#'"++()@#23#-,#+!"#.-1"%#&)1#+!"#4("6#()#+!"#O(*"$+-*7
()1";#+-#+!"#>%&)B#*-6#6"#?2'+#()'"*+"1/#N()&%%70#6"#'"+#+!"#%('+#4("6#+-#"1(+()@#.-1"#-)#+!"#)"6#*-60 _("6"*#1(&%-@='#$-)'+*2$+-*/
?2'+#&'#(,#+!"#2'"*#!&1#3*"''"1#&#B"7#-*#1-2>%"G$%($B"1#+-#()(+(&+"#"1(+()@/
DirectoryViewer::DirectoryViewer(QWidget *parent)
void TeamLeadersDialog::del() : QDialog(parent)
{ {
model->removeRows(listView->currentIndex().row(), 1); model = new QDirModel;
} model->setReadOnly(false);
model->setSorting(QDir::DirsFirst | QDir::IgnoreCase | QDir::Name);
treeView = new QTreeView;
treeView->setModel(model);
5)#+!"#$-)'+*2$+-*0#+!"#O"%"+"#>2++-)=' clicked()#'(@)&%#('#$-))"$+"1#+-#+!" del()#'%-+/#Q()$"#6"#&*" treeView->header()->setStretchLastSection(true);
?2'+#1"%"+()@#+!"#$2**")+#*-60#6"#$&)#$&%% removeRows()#6(+!#+!"#$2**")+#()1";#3-'(+(-)#&)1#&#*-6 treeView->header()->setSortIndicator(0, Qt::AscendingOrder);
$-2)+#-,#H/#c2'+#%(B"#6(+!#()'"*+(-)0#6"#*"%7#-)#+!"#.-1"%#+-#231&+"#+!"#4("6#&$$-*1()@%7/ treeView->header()->setSortIndicatorShown(true);
treeView->header()->setClickable(true);
QModelIndex index = model->index(QDir::currentPath());
QStringList TeamLeadersDialog::leaders() const treeView->expand(index);
{ treeView->scrollTo(index);
return model->stringList(); treeView->resizeColumnToContents(0);
} ...
}
N()&%%70#+!" leaders()#,2)$+(-)#3*-4(1"'#&#."&)'#-,#*"&1()@#>&$B#+!"#"1(+"1#'+*()@'#6!")#+!"#1(&%-@
('#$%-'"1/ 8)$"#+!"#.-1"%#!&'#>"")#$-)'+*2$+"10#6"#.&B"#(+#"1(+&>%"#&)1#'"+#4&*(-2'#()(+(&%#'-*+#-*1"*()@
&++*(>2+"'/#F"#+!")#$*"&+"#+!" QtreeView#+!&+#6(%%#1('3%&7#+!"#.-1"%='#1&+&/# !" QtreeView='#!"&1"*
TeamLeadersDialog#$-2%1#>"#.&1"#()+-#&#@")"*($#'+*()@#%('+#"1(+()@#1(&%-@#'(.3%7#>7#3&*&."+"*(<()@#(+' $&)#>"#2'"1#+-#3*-4(1"#2'"*G$-)+*-%%"1#'-*+()@/#D7#.&B()@#+!"#!"&1"*#$%($B&>%"0#+!"#2'"*#$&)#'-*+#>7
6()1-6#+(+%"/#A)-+!"*#@")"*($#1(&%-@#+!&+#('#-,+")#*"Z2(*"1#('#-)"#+!&+#3*"'")+'#&#%('+#-,#,(%"'#-* 6!($!"4"*#$-%2.)#!"&1"*#+!"7#$%($B0#6(+!#*"3"&+"1#$%($B'#&%+"*)&+()@#>"+6"")#&'$")1()@#&)1
1(*"$+-*("'#+-#+!"#2'"*/# !"#)";+#";&.3%"#2'"'#+!" QDirModel#$%&''0#6!($!#")$&3'2%&+"'#+!" 1"'$")1()@#-*1"*'/#8)$"#+!"#+*""#4("6='#!"&1"*#!&'#>"")#'"+#230#6"#@"+#+!"#.-1"%#()1";#-,#+!"
$-.32+"*='#,(%"#'7'+".#&)1#('#$&3&>%"#-,#'!-6()@#I&)1#!(1()@K#4&*(-2'#,(%"#&++*(>2+"'/# !('#.-1"%#$&) $2**")+#1(*"$+-*7#&)1#.&B"#'2*"#+!&+#+!('#1(*"$+-*7#('#4('(>%"#>7#";3&)1()@#(+'#3&*")+'#(,#)"$"''&*7
&33%7#&#,(%+"*#+-#*"'+*($+#+!"#B()1'#-,#,(%"#'7'+".#")+*("'#+!&+#&*"#'!-6)#&)1#$&)#-*1"*#+!"#")+*("'#() 2'()@ expand()0#&)1#'$*-%%()@#+-#(+#2'()@ scrollTo()/# !")#6"#.&B"#'2*"#+!&+#+!"#,(*'+#$-%2.)#('#6(1"
4&*(-2'#6&7'/ ")-2@!#+-#'!-6#&%%#(+'#")+*("'#6(+!-2+#2'()@#"%%(3'"'#IdK/
5)#+!"#3&*+#-,#+!"#$-)'+*2$+-*#$-1"#+!&+#(')=+ '!-6)#!"*"0#6"#$-))"$+"1#+!"#W*"&+"#O(*"$+-*7#&)1
!"#$%&)7(K(&*+%&L!$%/0-$C&H!%>%$&3445!/30!-6
C".-4"#>2++-)'#+-#'%-+'#+-#3"*,-*.#+!"'"#&$+(-)'/#F"#1-#)-+#)""1#&#C")&."#>2++-)#'()$"#2'"*'#$&)
[View full size image] *")&."#()G3%&$"#>7#3*"''()@#N\#&)1#+73()@/
void DirectoryViewer::createDirectory()
{
QModelIndex index = treeView->currentIndex();
if (!index.isValid())
return;
QString dirName = QInputDialog::getText(this,
tr("Create Directory"),
tr("Directory name"));
if (!dirName.isEmpty()) {
if (!model->mkdir(index, dirName).isValid())
QMessageBox::information(this, tr("Create Directory"),
tr("Failed to create the directory"));
}
}
5,#+!"#2'"*#")+"*'#(*"$+-*7#)&."#()#+!"#()32+#1(&%-@0#6"#&++".3+ +-#$*"&+"#(*"$+-*7#6(+!#+!('
)&."#&'#&#$!(%1#-,#+!"#$2**")+#1(*"$+-*7/# !" QDirModel::mkdir()#,2)$+(-)#+&B"'#+!"#3&*")+
1(*"$+-*7='#()1";#&)1#+!"#)&."#-,#+!"#)"6#1(*"$+-*70#&)1#*"+2*)'#+!"#.-1"%#()1";#-,#+!"#1(*"$+-*7#(+
$*"&+"1/#5,#+!"#-3"*&+(-)#,&(%'0#(+#*"+2*)'#&)#()4&%(1#.-1"%#()1";/
void DirectoryViewer::remove()
{
QModelIndex index = treeView->currentIndex();
if (!index.isValid())
return; L"*"='#&)#";+*&$+#,*-.#+!" ColorNamesDialog#$-)'+*2$+-*M
bool ok;
if (model->fileInfo(index).isDir()) {
ok = model->rmdir(index);
} else { ColorNamesDialog::ColorNamesDialog(QWidget *parent)
ok = model->remove(index); : QDialog(parent)
} {
if (!ok) sourceModel = new QStringListModel(this);
QMessageBox::information(this, tr("Remove"), sourceModel->setStringList(QColor::colorNames());
tr("Failed to remove %1").arg(model->fileName(index))); proxyModel = new QSortFilterProxyModel(this);
} proxyModel->setSourceModel(sourceModel);
proxyModel->setFilterKeyColumn(0);
listView = new QListView;
listView->setModel(proxyModel);
5,#+!"#2'"*#$%($B'#C".-4"0#6"#&++".3+#+-#*".-4"#+!"#,(%"#-*#1(*"$+-*7#&''-$(&+"1#6(+!#+!"#$2**")+ ...
(+"./#F"#$-2%1#2'" QDir#+-#&$$-.3%('!#+!&+0#>2+ QDirModel#-,,"*'#$-)4")(")$"#,2)$+(-)'#+!&+#6-*B#-) syntaxComboBox = new QComboBox;
QModelIndex"'/ syntaxComboBox->addItem(tr("Regular expression"), QRegExp::RegExp);
syntaxComboBox->addItem(tr("Wildcard"), QRegExp::Wildcard);
syntaxComboBox->addItem(tr("Fixed string"), QRegExp::FixedString);
!"#%&'+#";&.3%"#()#+!('#'"$+(-)#'!-6'#!-6#+-#2'" QSortFilterProxyModel/#S)%(B"#+!"#-+!"*
...
3*"1",()"1#.-1"%'0 +!('#.-1"%#")$&3'2%&+"'#&)#";('+()@#.-1"%#&)1#.&)(32%&+"'#+!"#1&+&#+!&+#3&''"' }
>"+6"")#+!"#2)1"*%7()@#.-1"%#&)1#+!"#4("6/#5)#-2*#";&.3%"0#+!"#2)1"*%7()@#.-1"%#('#&
QStringListModel#()(+(&%(<"1#6(+!#+!"#%('+#-,#$-%-*#)&."'#*"$-@)(<"1#>7#P+#I->+&()"1#+!*-2@!
QColor::colorNames()K/# !"#2'"*#$&)#+73"#&#,(%+"*#'+*()@#()#& QLineEdit#&)1#'3"$(,7#!-6#+!('#'+*()@#('
+-#>"#()+"*3*"+"1#I&'#&#*"@2%&*#";3*"''(-)0#(%1$&*1#3&++"*)0#-*#&#,(;"1#'+*()@K#2'()@#&#$-.>->-;/ !" QStringListModel#('#$*"&+"1#&)1#3-32%&+"1#()#+!"#2'2&%#6&7/# !('#('#,-%%-6"1#>7#+!"#$-)'+*2$+(-)
-,#+!" QSortFilterProxyModel/#F"#3&''#+!"#2)1"*%7()@#.-1"%#2'()@ setSourceModel()#&)1#+"%%#+!"
3*-;7#+-#,(%+"*#>&'"1#-)#$-%2.)#b#-,#+!"#-*(@()&%#.-1"%/# !" QComboBox::addItem()#,2)$+(-)#&$$"3+'
!"#$%&)7(M(&*+%&1-5-$&N3:%2&3445!/30!-6 &)#-3+(-)&%#J1&+&J#&*@2.")+#-,#+73" QVariant[#6"#2'"#+!('#+-#'+-*"#+!" QRegExp::PatternSyntax#4&%2"
+!&+#$-**"'3-)1'#+-#"&$!#(+".='#+";+/
void ColorNamesDialog::reapplyFilter()
{
QRegExp::PatternSyntax syntax =
QRegExp::PatternSyntax(syntaxComboBox->itemData(
syntaxComboBox->currentIndex()).toInt());
QRegExp regExp(filterLineEdit->text(), Qt::CaseInsensitive, syntax);
proxyModel->setFilterRegExp(regExp);
}
!" reapplyFilter()#'%-+#('#()4-B"1#6!")"4"*#+!"#2'"*#$!&)@"'#+!"#,(%+"*#'+*()@#-*#+!"#3&++"*)#'7)+&;
$-.>->-;/#F"#$*"&+"#& QRegExp#2'()@#+!"#+";+#()#+!"#%()"#"1(+/# !")#6"#'"+#(+'#3&++"*)#'7)+&;#+-#+!"
-)"#'+-*"1#()#+!"#'7)+&;#$-.>->-;='#$2**")+#(+".='#1&+&/#F!")#6"#$&%% setFilterRegExp()0#+!"#)"6
,(%+"*#>"$-."'#&$+(4"#&)1#+!"#4("6#('#&2+-.&+($&%%7#231&+"1/ !"#$%&)7()7(&*+%&1#$$%6/!%2&3445!/30!-6
[View full size image]
D",-*"#6"#".>&*B#-)#$*"&+()@#$2'+-.#.-1"%'0#%"+='#,(*'+#*"4("6#+!"#B"7#$-)$"3+'#2'"1#()#P+='
.-1"%V4("6#&*$!(+"$+2*"/#E4"*7#1&+&#"%".")+#()#&#.-1"%#!&'#&#.-1"%#()1";#&)1#&#'"+#-,#&++*(>2+"'0 !"#&33%($&+(-)#$-2%1#>"#(.3%".")+"1#2'()@#&#'(.3%"#+&>%"0#>2+#6"#6&)+#+-#2'"#&#$2'+-.#.-1"%#+-
$&%%"1#*-%"'0#+!&+#$&)#+&B"#&*>(+*&*7#4&%2"'/#F"#'&6#"&*%("*#()#+!"#$!&3+"*#+!&+#+!"#.-'+#$-..-)%7 +&B"#&14&)+&@"#-,#$"*+&()#3*-3"*+("'#-,#+!"#1&+&#+-#.()(.(<"#'+-*&@"/#5,#6"#6"*"#+-#'+-*"#+!"#He\
2'"1#*-%"'#&*" Qt::DisplayRole#&)1 Qt::EditRole/#8+!"*#*-%"'#&*"#2'"1#,-*#'233%".")+&*7#1&+&#I,-* $2**")+%7#+*&1"1#$2**")$("'#()#&#+&>%"0#6"#6-2%1#)""1#+-#'+-*"#He\#;#He\#f#\e#\YY#4&%2"'[#6(+!#+!"
";&.3%"0 Qt::ToolTipRole0 Qt::StatusTipRole0#&)1 Qt::WhatsThisRoleK0#&)1#7"+#-+!"*'#,-*#$-)+*-%%()@ $2'+-.#.-1"%#3*"'")+"1#>"%-60 6"#-)%7#)""1#+-#'+-*"#He\#4&%2"'#I+!"#4&%2"#-,#"&$!#$2**")$7#()
>&'($#1('3%&7#&++*(>2+"'#I'2$!#&' Qt::FontRole0 Qt:: TextAlignmentRole0 Qt::TextColorRole0#&)1 *"%&+(-)#+-#+!"#S/Q/#1-%%&*K/
Qt::BackgroundColorRoleK/
!" CurrencyModel#$%&''#6(%%#>"#2'"1#6(+!#&#'+&)1&*1 QTableView/# !" Currency-Model#('#3-32%&+"1
!"#$%&)7('(&B/+%:30!/&=!%>&-O&8092&:-;%52 6(+!#& QMap<QString,double>[#"&$!#B"7#('#&#$2**")$7#$-1"#&)1#"&$!#4&%2"#('#+!"#4&%2"#-,#+!"
$2**")$7#()#S/Q/#1-%%&*'/#L"*"='#&#$-1"#')(33"+#+!&+#'!-6'#!-6#+!"#.&3#('#3-32%&+"1#&)1#!-6#+!"
[View full size image]
.-1"%#('#2'"1M
U-6#6"#$&)#%--B#&+#+!"#(.3%".")+&+(-)#-,#+!"#.-1"%0#'+&*+()@#6(+!#(+'#!"&1"*M
N-*#&#%('+#.-1"%0#+!"#-)%7#*"%"4&)+#()1";#$-.3-)")+#('#+!"#*-6#)2.>"*0 &$$"''(>%"#,*-.
QModelIndex::row()/#N-*#&#+&>%"#.-1"%0#+!"#*"%"4&)+#()1";#$-.3-)")+'#&*"#+!"#*-6#&)1#$-%2.)
)2.>"*'0#&$$"''(>%"#,*-. QModelIndex::row()#&)1 QModelIndex::column()/#N-*#>-+!#%('+#&)1#+&>%" class CurrencyModel : public QAbstractTableModel
{
.-1"%'0#"4"*7#(+".='#3&*")+#('#+!"#*--+0#6!($!#('#*"3*"'")+"1#>7#&)#()4&%(1 QModelIndex/# !"#,(*'+#+6-
public:
";&.3%"'#()#+!('#'"$+(-)#'!-6#!-6#+-#(.3%".")+#$2'+-.#+&>%"#.-1"%'/ CurrencyModel(QObject *parent = 0);
void setCurrencyMap(const QMap<QString, double> &map);
A#+*""#.-1"%#('#'(.(%&*#+-#&#+&>%"#.-1"%0#6(+!#+!"#,-%%-6()@#1(,,"*")$"'/#:(B"#&#+&>%"#.-1"%0#+!" int rowCount(const QModelIndex &parent) const;
3&*")+#-,#+-3G%"4"%#(+".'#('#+!"#*--+#I&)#()4&%(1 QModelIndexK0#>2+#"4"*7#-+!"*#(+".='#3&*")+#('#'-." int columnCount(const QModelIndex &parent) const;
-+!"*#(+".#()#+!"#!("*&*$!7/#T&*")+'#&*"#&$$"''(>%"#,*-. QModelIndex::parent()/#E4"*7#(+".#!&'#(+' QVariant data(const QModelIndex &index, int role) const;
*-%"#1&+&0#&)1#<"*-#-*#.-*"#$!(%1*")0#"&$!#&)#(+".#()#(+'#-6)#*(@!+/#Q()$"#(+".'#$&)#!&4"#-+!"*#(+".' QVariant headerData(int section, Qt::Orientation orientation,
&'#$!(%1*")0#(+#('#3-''(>%"#+-#*"3*"'")+#*"$2*'(4"#I+*""G%(B"K#1&+&#'+*2$+2*"'0#&'#+!"#,()&%#";&.3%"#() int role) const;
+!('#'"$+(-)#6(%%#'!-6/ private:
QString currencyAt(int offset) const;
QMap<QString, double> currencyMap;
!"#,(*'+#";&.3%"#()#+!('#'"$+(-)#('#&#*"&1G-)%7#+&>%"#.-1"%#+!&+#'!-6'#$2**")$7#4&%2"'#()#*"%&+(-)#+- };
"&$!#-+!"*/
F"#!&4"#$!-'")#+-#'2>$%&'' QAbstractTableModel#,-*#-2*#.-1"%#'()$"#+!&+#.-'+#$%-'"%7#.&+$!"'#-2*
1&+&#'-2*$"/#P+#3*-4(1"'#'"4"*&%#.-1"%#>&'"#$%&''"'0#()$%21()@ QAbstractListModel0 return QString("%1").arg(amount, 0, 'f', 4);
QAbstractTableModel0#&)1 QAbstractItemModel/# !" QAbstractItemModel#$%&''#('#2'"1#+-#'233-*+#& }
6(1"#4&*("+7#-,#.-1"%'0#()$%21()@#+!-'"#+!&+#&*"#>&'"1#-)#*"$2*'(4"#1&+&#'+*2$+2*"'0#6!(%"#+!" return QVariant();
}
QAbstractListModel#&)1 QAbstractTableModel#$%&''"'#&*"#3*-4(1"1#,-*#$-)4")(")$"#6!")#2'()@#-)"G
1(.")'(-)&%#-*#+6-G1(.")'(-)&%#1&+&#'"+'/
;$#(!"#+*/"#), Qt::TextAlignmentRole8#:"#+"(%+&#.&#./)9&1"&(#,%)(.7/"#$*+#&%17"+,3#;$#(!"#5),4/.0#+*/"
), Qt::DisplayRole8#:"#/**<#%4#(!"#-./%"#$*+#".'!#'%++"&'0#.&5#'./'%/.("#(!"#"='!.&9"#+.("3
>"#'*%/5#+"(%+&#(!"#'./'%/.("5#-./%"#.,#. double8#7%(#(!"&#:"#:*%/5#!.-"#&*#'*&(+*/#*-"+#!*:#1.&0
5"')1./#4/.'",#:"+"#,!*:&#?%&/",,#:"#%,"#.#'%,(*1#5"/"9.("@3#;&,(".58#:"#+"(%+&#(!"#-./%"#.,#.
,(+)&98#$*+1.(("5#.,#:"#:.&(3
!"#'*&,(+%'(*+#5*",#&*(!)&9#7"0*&5#4.,,#*&#(!" parent#4.+.1"("+#(*#(!"#7.,"#'/.,,3
J"+"2,#!*:#:"#,"(#%4#.&5#%,"#(!"#1*5"/K B)&'"#:"#!.-"#.#,D%.+"#9+)5#*$#')()",8#(!"#&%17"+#*$#+*:,#.&5#'*/%1&,#),#(!"#&%17"+#*$#')()",#)&#*%+
/),(3
QStringList cities;
cities << "Arvika" << "Boden" << "Eskilstuna" << "Falun" QVariant CityModel::data(const QModelIndex &index, int role) const
<< "Filipstad" << "Halmstad" << "Helsingborg" << "Karlstad" {
<< "Kiruna" << "Kramfors" << "Motala" << "Sandviken" if (!index.isValid())
<< "Skara" << "Stockholm" << "Sundsvall" << "Trelleborg"; return QVariant();
CityModel cityModel; if (role == Qt::TextAlignmentRole) {
cityModel.setCities(cities); return int(Qt::AlignRight | Qt::AlignVCenter);
QTableView tableView; } else if (role == Qt::DisplayRole) {
tableView.setModel(&cityModel); if (index.row() == index.column())
tableView.setAlternatingRowColors(true); return 0;
int offset = offsetOf(index.row(), index.column());
return distances[offset];
}
>"#1%,(#+")14/"1"&(#(!"#,.1"#$%&'()*&, .,#:"#5)5#$*+#(!"#4+"-)*%,#"=.14/"3#;&#.55)()*&8#:"#1%,(
return QVariant();
./,*#+")14/"1"&( setData()#.&5 flags()#(*#1.<"#(!"#1*5"/#"5)(.7/"3#J"+"#),#(!"#'/.,,#5"$)&)()*&K
}
!" createIndex()#$%&'()*&#),#%,"5#(*#9"&"+.("#.#1*5"/#)&5"=3#>"#&""5#)(#(*#9"(#(!"#1*5"/#)&5"=#*$
(!"#)("1#*&#(!"#*(!"+#,)5"#*$#(!"#1.)).9*&./#(!.(#'*++",4*&5,#:)(!#(!"#)("1#7")&9#,"(8#,)&'"#7*(!
)("1,#1%,(#,!*:#(!"#,.1"#5.(.3# !" createIndex()#$%&'()*&#(.<",#(!"#+*:#7"$*+"#(!"#'*/%1&C#!"+"
:"#)&-"+(#(!"#4.+.1"("+,#(*#9"(#(!"#1*5"/#)&5"=#*$#(!"#5).9*&.//0#*44*,)("#)("1#(*#(!"#*&"#,4"')$)"5
70 index3
!" flags()#$%&'()*&#),#%,"5#70#(!"#1*5"/#(*#'*11%&)'.("#:!.(#'."#5*&"#:)(!#.&#)("1#?$*+
"=.14/"8#:!"(!"+#)(#),#"5)(.7/"@3# !"#5"$.%/(#)14/"1"&(.()*&#$+*1 QAbstractTableModel#+"(%+&,
Qt::ItemIsSelectable | Qt::ItemIsEnabled3#>"#.55#(!" Qt::ItemIsEditable#$/.9#$*+#.//#)("1,#"='"4(
(!*,"#/0)&9#*&#(!"#5).9*&./,#?:!)'!#.+"#./:.0,#L@3
\*:#(!.(#:"#!.-"#5"$)&"5#*%+#5.(.#)("1,#?".'!#+"4+","&("5#70#. Node@8#:"#.+"#+".50#(*#'+".("#.
1*5"/K
class Node
{ !),#()1"#:"#!.-"#)&!"+)("5#$+*1 QAbstractItemModel#+.(!"+#(!.&#$+*1#)(,#'*&-"&)"&'"#,%7'/.,,
public: QAbstractTableModel8#7"'.%,"#:"#:.&(#(*#'+".("#.#!)"+.+'!)'./#1*5"/3# !"#",,"&()./#$%&'()*&,#(!.(
enum Type { RegExp, Expression, Term, Factor, Atom, Terminal }; :"#1%,(#+")14/"1"&(#+"1.)&#(!"#,.1"8#"='"4(#(!.(#:"#1%,(#./,*#)14/"1"&( index()#.&5 parent()3
Node(Type type, const QString &str = ""); *#,"(#(!"#1*5"/2,#5.(.8#:"#!.-"#. setRootNode()#$%&'()*&#(!.(#1%,(#7"#'.//"5#:)(!#.#4.+,"#(+""2,
~Node(); +**(#&*5"3
Type type;
QString str;
Node *parent; RegExpModel::RegExpModel(QObject *parent)
QList<Node *> children; : QAbstractItemModel(parent)
}; {
rootNode = 0;
}
W-"+0#&*5"#!.,#.#(04"8#.#,(+)&9#?:!)'!#1.0#7"#"14(0@8#.#4.+"&(#?:!)'!#1.0#7"#L@8#.&5#.#/),(#*$
'!)/5#&*5",#?:!)'!#1.0#7"#"14(0@3
;&#(!"#1*5"/2,#'*&,(+%'(*+8#:"#H%,(#&""5#(*#,"(#(!"#+**(#&*5"#(*#.#,.$"#&%//#-./%"#.&5#4.,,#*&#(!"
parent#(*#(!"#7.,"#'/.,,3
Node::Node(Type type, const QString &str)
{
this->type = type;
RegExpModel::~RegExpModel()
this->str = str;
{
parent = 0;
delete rootNode;
}
}
!"#'*&,(+%'(*+#,)14/0#)&)()./)A",#(!"#&*5"2,#(04"#.&5#,(+)&93#["'.%,"#.//#(!"#5.(.#),#4%7/)'8#'*5"#(!.(
;&#(!"#5",(+%'(*+#:"#5"/"("#(!"#+**(#&*5"3#;$#(!"#+**(#&*5"#!.,#'!)/5+"&8#".'!#*$#(!","#),#5"/"("58
%,", Node#'..&)4%/.("#(!"#(04"8#,(+)&98#4.+"&(8#.&5#'!)/5+")+"'(/03
.&5#,*#*&#+"'%+,)-"/08#70#(!" Node#5",(+%'(*+3
Node::~Node()
void RegExpModel::setRootNode(Node *node)
{
delete rootNode; !"#&%17"+#*$#+*:,#$*+#.#9)-"&#)("1#),#,)14/0#!*:#1.&0#'!)/5+"&#)(#!.,3
rootNode = node;
reset();
}
int RegExpModel::columnCount(const QModelIndex & /* parent */) const
{
return 2;
>!"&#.#&":#+**(#&*5"#),#,"(8#:"#7"9)F#5"/"()&9#.&0 4+"-)*%,#+**(#&*5"#?.&5#.//#*$#)(,#'!)/5+"&@3 }
!"&#:"#,"(#(!"#&":#+**(#&*5"#.&5#'.// reset()#(*#&*()$0#.&0#-)":,#(!.(#(!"0#1%,(#+"$"('!#(!"#5.(.
$*+#.&0#-),)7/"#)("1,3
!"#&%17"+#*$#'*/%1&,#),#$)="5#.(#Q3# !"#$)+,(#'*/%1&#!*/5,#(!"#&*5"#(04",C#(!"#,"'*&5#'*/%1&
!*/5,#(!"#&*5"#-./%",3
QModelIndex RegExpModel::index(int row, int column,
const QModelIndex &parent) const
{ QModelIndex RegExpModel::parent(const QModelIndex &child) const
if (!rootNode) {
return QModelIndex(); Node *node = nodeFromIndex(child);
Node *parentNode = nodeFromIndex(parent); if (!node)
return createIndex(row, column, parentNode->children[row]); return QModelIndex();
} Node *parentNode = node->parent;
if (!parentNode)
return QModelIndex();
!" index()#$%&'()*&#),#+")14/"1"&("5#$+*1 QAbstractItemModel3 ;(#),#'.//"5#:!"&"-"+#(!"#1*5"/#*+ Node *grandparentNode = parentNode->parent;
(!"#-)":#&""5,#(*#'+".("#. QModelIndex#$*+#.#4.+()'%/.+#'!)/5#)("1#?*+#.#(*4F/"-"/#)("1#)$ parent#),#.& if (!grandparentNode)
return QModelIndex();
)&-./)5 QModelIndex@3#6*+#(.7/"#.&5#/),(#1*5"/,8#:"#5*&2(#&""5#(*#+")14/"1"&(#(!),#$%&'()*&8#7"'.%,"
int row = grandparentNode->children.indexOf(parentNode);
QAbstractList-Model2,#.&5 QAbstractTableModel2,#5"$.%/(#)14/"1"&(.()*&,#&*+1.//0#,%$$)'"3
return createIndex(row, child.column(), parentNode);
}
;&#*%+ index()#)14/"1"&(.()*&8#)$#&*#4.+,"#(+""#),#,"(8#:"#+"(%+&#.&#)&-./)5 QModelIndex3#](!"+:),"8
:"#'+".("#. QModelIndex#:)(!#(!"#9)-"&#+*:#.&5#'*/%1&#.&5#:)(!#. Node *#$*+#(!"#+"D%",("5#'!)/53
6*+#!)"+.+'!)'./#1*5"/,8#<&*:)&9#(!"#+*:#.&5#'*/%1&#*$#.&#)("1#+"/.()-"#(*#)(,#4.+"&(#),#&*(#"&*%9!
Z"(+)"-)&9#(!"#4.+"&( QModelIndex#$+*1#.#'!)/5#),#.#7)(#1*+"#:*+<#(!.&#$)&5)&9#.#4.+"&(2,#'!)/53#>"
(*#%&)D%"/0#)5"&()$0#)(C#:"#1%,(#./,*#<&*: &'(#(!"#4.+"&(#),3# *#,*/-"#(!),8#:"#'.&#,(*+"#.#4*)&("+
'.&#".,)/0#+"(+)"-"#(!"#4.+"&(#&*5"#%,)&9 nodeFromIndex()#.&5#9*)&9#%4#%,)&9 (!" Node2,#4.+"&(
(*#(!"#)&("+&./#&*5"#)&#(!" QModelIndex3 QModelIndex#9)-",#%,#(!"#*4()*&#*$#,(*+)&9#. void *#*+#.& int
4*)&("+8#7%(#(*#*7(.)&#(!"#+*:#&%17"+#?(!"#4*,)()*&#*$#(!"#4.+"&(#.1*&9#)(,#,)7/)&9,@8#:"#&""5#(*#9*
)&#.55)()*&#(*#(!"#+*:#.&5#'*/%1&#&%17"+,3
7.'<#(*#(!"#9+.&54.+"&(#.&5#$)&5#(!"#4.+"&(2,#)&5"=#4*,)()*&#)&#)(,#4.+"&(2,#?(!.(#),8#(!"#'!)/52,
9+.&54.+"&(2,@#/),(#*$#'!)/5+"&3
!" Node *#$*+#(!"#'!)/5#),#*7(.)&"5#(!+*%9!#(!"#4.+"&(#&*5"2, children#/),(3# !"#4.+"&(#&*5"#),
"=(+.'("5#$+*1#(!" parent#1*5"/#)&5"=#%,)&9#(!" nodeFromIndex()#4+)-.("#$%&'()*&K
QVariant RegExpModel::data(const QModelIndex &index, int role) const
{
Node *RegExpModel::nodeFromIndex(const QModelIndex &index) const if (role != Qt::DisplayRole)
{ return QVariant();
if (index.isValid()) { Node *node = nodeFromIndex(index);
return static_cast<Node *>(index.internalPointer()); if (!node)
} else { return QVariant();
return rootNode; if (index.column() == 0) {
} switch (node->type) {
} case Node::RegExp:
return tr("RegExp");
case Node::Expression:
return tr("Expression");
!" nodeFromIndex()#$%&'()*&#'.,(,#(!"#9)-"&#)&5"=2, void *#(*#. Node *8#*+#+"(%+&,#(!"#+**(#&*5"#)$
case Node::Term:
(!"#)&5"=#),#)&-./)58#,)&'"#.&#)&-./)5#1*5"/#)&5"=#),#%,"5#(*#+"4+","&(#(!"#+**(#)&#.#1*5"/3 return tr("Term");
case Node::Factor:
return tr("Factor");
int RegExpModel::rowCount(const QModelIndex &parent) const case Node::Atom:
{ return tr("Atom");
Node *parentNode = nodeFromIndex(parent); case Node::Terminal:
if (!parentNode) return tr("Terminal");
return 0; default:
return parentNode->children.count(); return tr("Unknown");
} }
} else if (index.column() == 1) {
return node->str;
}
return QVariant(); Qt::BackgroundColorRole8#.&5#(!","#.+"#%,"5#70#(!"#5"$.%/(#5"/"9.("3#6*+#"=.14/"8#)&#(!"#I)()",#.&5
} I%++"&')",#"=.14/",#,!*:&#".+/)"+8#:"#!.&5/"5#(!" Qt::TextAlignmentRole#(*#9"(#+)9!(F./)9&"5
&%17"+,3
>"#%," QItemDelegate#.,#*%+#7.,"#'/.,,8#,*#(!.(#:"#7"&"$)(#$+*1#(!"#5"$.%/(#5"/"9.("
)14/"1"&(.()*&3#>"#'*%/5#./,*#!.-"#%,"5 QAbstractItemDelegate#)$#:"#!.5#:.&("5#(*#,(.+(#$+*1 >"#*&/0#:.&(#(*#'*&(+*/#(!"#"5)()&9#*$#(+.'<#5%+.()*&,8#/".-)&9#(!"#"5)()&9#*$#(+.'<#&.1",#(*#(!"
,'+.('!3# *#4+*-)5"#.#5"/"9.("#(!.(#'.&#"5)(#5.(.8#:"#1%,(#)14/"1"&( createEditor()8 5"$.%/(#5"/"9.("3#>"#.'!)"-"#(!),#70#'!"'<)&9#:!)'!#'*/%1&#(!"#5"/"9.("#!.,#7""&#.,<"5#(*#4+*-)5"
setEditorData()8#.&5 setModelData()3#>" ./,*#)14/"1"&( paint()#(*#'!.&9"#(!"#+"&5"+)&9#*$#(!" .&#"5)(*+#$*+3#;$#)(2,#(!"#5%+.()*&#'*/%1&8#:"#'+".("#. QTimeEdit8#,"(#(!"#5),4/.0#$*+1.(
5%+.()*&#'*/%1&3 .44+*4+).("/08.&5#'*&&"'(#)(, editingFinished()#,)9&./#(*#*%+ commitAndCloseEditor()#,/*(3#6*+#.&0
*(!"+#'*/%1&8#:"#4.,,#*&#(!"#"5)(#!.&5/)&9#(*#(!"#5"$.%/(#5"/"9.("3
I*&(.)&"+#'/.,,",#.+"#9"&"+./F4%+4*,"#("14/.("#'/.,,",#(!.(#,(*+"#)("1,#*$#.#9)-"&#(04"#)"1*+03
>!"&#(!"#%,"+#)&)().(",#"5)()&98#(!"#-)":#'.//, createEditor()#(*#'+".("#.&#"5)(*+8#.&5#(!"& IRR#./+".50#*$$"+,#1.&0#'*&(.)&"+,#.,#4.+(#*$#(!"#B(.&5.+5# "14/.("#E)7+.+0#?B E@8#:!)'!#),
setEditorData()#(*#)&)()./)A"#(!"#"5)(*+#:)(!#(!"#)("12,#'%++"&(#5.(.3#;$#(!"#"5)(*+#),#$*+#(!"#5%+.()*& )&'/%5"5#)&#(!"#B(.&5.+5#IRR#/)7+.+03
'*/%1&8#:"#"=(+.'(#(!"#(+.'<2,#5%+.()*&#)&#,"'*&5,#.&5#,"(#(!" QTimeEdit2,#()1"#(*#(!"#'*++",4*&5)&9
&%17"+#*$#1)&%(",#.&5#,"'*&5,C#*(!"+:),"8#:"#/"(#(!"#5"$.%/(#5"/"9.("#!.&5/"#(!"#)&)()./)A.()*&3 b(#4+*-)5",#)(,#*:&#'*&(.)&"+#'/.,,",8#,*#$*+#b(#4+*9+.1,#:"#'.&#%,"#7*(!#(!"#b(#.&5#(!"#B E
'*&(.)&"+,3# !"#1.)&#.5-.&(.9",#*$#(!"#b(#'*&(.)&"+,#.+"#(!.(#(!"0#7"!.-"#(!"#,.1"#*&#.//
4/.($*+1,#.&5#(!.(#(!"0#.+"#)14/)')(/0#,!.+"53#;14/)')(#,!.+)&98#*+#V'*40#*&#:+)("V8#),#.&#*4()1)A.()*&
void TrackDelegate::setModelData(QWidget *editor, (!.(#1.<",#)(#4*,,)7/"#(*#4.,, "&()+"#'*&(.)&"+,#.,#-./%",#:)(!*%(#.&0#,)9&)$)'.&(#4"+$*+1.&'"#'*,(3
QAbstractItemModel *model, !"#b(#'*&(.)&"+,#./,*#$".(%+"#".,0F(*F%,"#)("+.(*+#'/.,,",#)&,4)+"5#70#c.-.8#(!"0#'."#,(+".1"5
const QModelIndex &index) const %,)&9 QDataStream8#.&5#(!"0#%,%.//0#+",%/(#)&#/",,#'*5"#)&#(!"#"="'%(.7/"#(!.&#(!"#'*++",4*&5)&9#B E
{ '*&(.)&"+,3#6)&.//08#*&#,*1"#!.+5:.+"#4/.($*+1,#,%44*+("5#70#b(*4).#I*+"#?(!"#b(#-"+,)*&#$*+
if (index.column() == durationColumn) { 1*7)/"#5"-)'",@8#(!"#b(#'*&(.)&"+,#.+"#(!"#*&/0#*&",#.-.)/.7/"3
QTimeEdit *timeEdit = qobject_cast<QTimeEdit *>(editor);
QTime time = timeEdit->time();
int secs = (time.minute() * 60) + time.second(); b(#*$$"+,#7*(!#,"D%"&()./#'*&(.)&"+,#,%'!#., QVector<T>8 QLinkedList<T>8#.&5 QList<T>8#.&5
model->setData(index, secs); .,,*').()-"#'*&(.)&"+,#,%'!#., QMap<K, T>#.&5 QHash<K, T>3#I*&'"4(%.//08#(!"#,"D%"&()./#'*&(.)&"+,
} else { ,(*+"#)("1,#*&"#.$("+#.&*(!"+8#:!"+".,#(!"#.,,*').()-"#'*&(.)&"+,#,(*+"#<"0-./%"#4.)+,3
QItemDelegate::setModelData(editor, model, index);
} b(#./,*#4+*-)5",#9"&"+)'#./9*+)(!1,#(!.(#4"+$*+1#*4"+.()*&,#*& .+7)(+.+0#'*&(.)&"+,3#6*+#"=.14/"8
} (!" qSort()#./9*+)(!1#,*+(,#.#,"D%"&()./#'*&(.)&"+8#.&5 qBinaryFind()#4"+$*+1,#.#7)&.+0#,".+'!#*&#.
,*+("5#,"D%"&()./#'*&(.)&"+3# !","#./9*+)(!1,#.+"#,)1)/.+#(*#(!*,"#*$$"+"5#70#(!"#B E3
b(2,#*&/)&"#5*'%1"&(.()*+*-)5",#'*14+"!"&,)-"#'*-"+.9"#*$#)("1#-)":#4+*9+.11)&9#.&5#(!"
;$#:"#<&*:#)&#.5-.&'"#!*:#1.&0#)("1,#:"#.+"#9*)&9#(*#&""58#:"#'.	)-"#(!"#-"'(*+#.&#)&)()./#,)A"
'/.,,",#(!.(#)14/"1"&(#)(3#B"" !((4KPP5*'3(+*//("'!3'*1PT3OP1*5"/F-)":3!(1/#$*+#.#/),(#*$#.//#(!"
+"/"-.&(#'/.,,",8#.&5 !((4KPP5*'3(+*//("'!3'*1PT3OP1*5"/F-)":F4+*9+.11)&93!(1/#$*+#.55)()*&./ :!"&#:"#5"$)&"#)(#.&5#%,"#(!" []#*4"+.(*+#(*#.,,)9&#.#-./%"#(*#(!"#)("1,C#*(!"+:),"8#:"#1%,(#")(!"+
)&$*+1.()*&#.&5#/)&<,#(*#(!"#+"/"-.&(#"=.14/",#)&'/%5"5#:)(!#b(3 +",)A"#(!"#-"'(*+#/.("+#*&#*+#.44"&5#)("1,3#J"+"2,#.&#"=.14/"#:!"+"#:"#,4"')$0#(!"#)&)()./#,)A"K
!" QList<T>#,"D%"&()./#'*&(.)&"+#),#.&#V.++.0F/),(V#(!.(#'*17)&",#(!"#1*,(#)14*+(.&(#7"&"$)(,#*$
QVector<double> vect(3); QVector<T>#.&5 QLinkedList<T>#)&#.#,)&9/"#'/.,,3#;(#,%44*+(,#+.&5*1#.''",,8#.&5#)(, )&("+$.'"#),
vect[0] = 1.0; )&5"=F7.,"5#/)<" QVector2,3#;&,"+()&9#*+#+"1*-)&9#.&#)("1#.(#")(!"+#"&5#*$#. QList<T>#),#-"+0#$.,(8
vect[1] = 0.540302;
.&5#)&,"+()&9#)&#(!"#1)55/"#),#$.,(#$*+#/),(,#:)(!#%4#(*#.7*%(#*&"#(!*%,.&5#)("1,3#_&/",,#:"#:.&(#(*
vect[2] = -0.416147;
4"+$*+1#)&,"+()*&,#)&#(!"#1)55/"#*$#!%9"#/),(,#*+#&""5#(!"#/),(2,#)("1,#(*#*''%40#'*&,"'%()-"
.55+",,",#)"1*+08 QList<T>#),#%,%.//0#(!"#1*,(#.44+*4+).("#9"&"+./F4%+4*,"#'*&(.)&"+#'/.,,#(*
%,"3
J"+"2,#(!"#,.1"#"=.14/"8#(!),#()1"#,(.+()&9#:)(!#.&#"14(0#-"'(*+#.&5#%,)&9#(!" append()#$%&'()*&#(*
.44"&5#)("1,#.(#(!"#"&5K !" QStringList#'/.,,#),#.#,%7'/.,,#*$ QList<QString>#(!.(#),#:)5"/0#%,"5#)&#b(2,#GM;3#;&#.55)()*&#(*
(!"#$%&'()*&,#)(#)&!"+)(,#$+*1#)(,#7.,"#'/.,,8#)(#4+*-)5",#,*1"#"=(+.#$%&'()*&,#(!.(#1.<"#(!"#'/.,,
1*+"#-"+,.()/"#$*+#,(+)&9#!.&5/)&93 QStringList#),#5),'%,,"5#)&#(!"#/.,(#,"'()*&#*$#(!),#'!.4("+#?43
QVector<double> vect;
Qde@3
vect.append(1.0);
vect.append(0.540302);
vect.append(-0.416147); QStack<T>#.&5 QQueue<T>#.+"#(:*#1*+"#"=.14/",#*$ '*&-"&)"&'"#,%7'/.,,",3 QStack<T>#),#.#-"'(*+
(!.(#4+*-)5", push()8 pop()8#.&5 top()3 QQueue<T>#),#.#/),(#(!.(#4+*-)5", enqueue()8 dequeue()8#.&5
head()3
>"#'.&#./,*#%,"#(!" <<#*4"+.(*+#)&,(".5#*$ append()K
6*+#.//#(!"#'*&(.)&"+#'/.,,",#,""&#,*#$.+8#(!"#-./%"#(04" T#'."#.#7.,)'#(04"#/)<" int#*+ double8#.
4*)&("+#(04"8#*+#.#'/.,,#(!.(#!.,#.#5"$.%/(#'*&,(+%'(*+#?.#'*&,(+%'(*+#(!.(#(.<",#&*#.+9%1"&(,@8#.
vect << 1.0 << 0.540302 << -0.416147; '*40#'*&,(+%'(*+8#.&5#.&#.,,)9&1"&(#*4"+.(*+3#I/.,,",#(!.(#D%./)$0#)&'/%5" QByteArray8 QDateTime8
QRegExp8 QString8#.&5 QVariant3#b(#'/.,,",#(!.(#)&!"+)(#$+*1 QObject#5*#&*(#D%./)$08#7"'.%,"#(!"0
/.'<#.#'*40#'*&,(+%'(*+#.&5#.&#.,,)9&1"&(#*4"+.(*+3# !),#),#&*#4+*7/"1#)+.'()'"8#,)&'"#:"#'.&
]&"#:.0#(*#)("+.("#*-"+#(!"#-"'(*+2,#)("1,#),#(*#%," []#.&5 count()K ,)14/0#,(*+"#4*)&("+,#(* QObject#(04",#+.(!"+#(!.&#(!"#*7H"'(,#(!"1,"/-",3
6*+#".'!#'*&(.)&"+#'/.,,8#(!"+"#.+"#(:*#c.-.F,(0/"#)("+.(*+#(04",K#.#+".5F*&/0#)("+.(*+#.&5#.#+".5F
>"#:)//#(.<"#.#1*+"#5"(.)/"5#/**<#.(#)("+.(*+,#/.("+#)&#(!),#,"'()*&3
:+)("#)("+.(*+3# !"#+".5F*&/0#)("+.(*+#'/.,,",#.+" QVectorIterator<T>8 QLinkedListIterator<T>8#.&5
QListIterator<T>3# !"#'*++",4*&5)&9#+".5F:+)("#)("+.(*+,#!.-" Mutable#)&#(!")+#&.1"#?$*+#"=.14/"8 QMutableListIterator<double> i(list);
QMutableVectorIterator<T>@3#;&#(!),#5),'%,,)*&8#:"#:)//#'*&'"&(+.("#*& QList2,#)("+.(*+,C#(!"#)("+.(*+,
while (i.hasNext()) {
if (i.next() < 0.0)
$*+#/)&<"5#/),(,#.&5#-"'(*+,#!.-"#(!"#,.1"#GM;3
i.remove();
}
!"#$%&'')6)&D02!7&14/!.!45/&C4$&E0B0F/.G2%&!.%$0.4$/
!" remove()#$%&'()*&#./:.0,#*4"+.(",#*&#(!"#/.,(#)("1#(!.(#:.,#H%14"5#*-"+3#;(#./,*#:*+<,#:!"&
)("+.()&9#7.'<:.+5K
QMutableListIterator<double> i(list);
i.toBack();
while (i.hasPrevious()) {
!"#$)+,(#(!)&9#(*#<""4#))&5#:!"&#%,)&9#c.-.F,(0/"#)("+.(*+,#),#(!.(#(!"0#5*&2(#4*)&(#5)+"'(/0#.( if (i.previous() < 0.0)
)("1,3#;&,(".58#(!"0#'."#/*'.("5#7"$*+"#(!"#$)+,(#)("18#.$("+#(!"#/.,(#)("18#*+#7"(:""&#(:*#)("1,3 i.remove();
G#(04)'./#)("+.()*&#/**4#/**<,#/)<"#(!),K }
!"#B EF,(0/"#)("+.(*+#,0&(.=#),#1*5"/"5#.$("+#(!.(#*$#IRR#4*)&("+,#)&(*#.&#.++.03#>"#'.&#%,"#(!" ++
.&5 --#*4"+.(*+,#(*#1*-"#(*#(!"#&"=(#*+#4+"-)*%,#)("18#.&5#(!"#%&.+0 *#*4"+.(*+#(*#+"(+)"-"#(!"
'%++"&(#)("13#6*+ QVector<T>8#(!" iterator#.&5 const_iterator#(04",#.+"#1"+"/0#(04"5"$,#$*+ T *#.&5
a%(.7/"#)("+.(*+,#4+*-)5"#$%&'()*&,#(*#)&,"+(8#1*5)$08#.&5#+"1*-"#)("1,#:!)/"#)("+.()&93# !"#$*//*:)&9 const T *3#? !),#),#4*,,)7/"#7"'.%," QVector<T>#,(*+",#)(,#)("1,#)&#'*&,"'%()-"#1"1*+0#/*'.()*&,3@
/**4#+"1*-",#.//#(!"#&"9.()-"#&%17"+,#$+*1#.#/),(K
!"#$*//*:)&9#"=.14/"#+"4/.'",#".'!#-./%"#)&#. QList<double>#:)(!#)(,#.7,*/%("#-./%"K
{
QList<double>::iterator i = list.begin(); QVector<double> vect(360);
while (i != list.end()) { for (int i = 0; i < 360; ++i)
*i = qAbs(*i); vect[i] = sin(i / (2 * M_PI));
++i; return vect;
} }
G#$":#b(#$%&'()*&,#+"(%+&#.#'*&(.)&"+3#;$#:"#:.&(#(*#)("+.("#*-"+#(!"#+"(%+&#-./%"#*$#.#$%&'()*&#%,)&9 !"#'.//#(*#(!"#$%&'()*&#/**<,#/)<"#(!),K
.&#B EF,(0/"#)("+.(*+8#:"#1%,(#(.<"#.#'*40#*$#(!"#'*&(.)&"+#.&5#)("+.("#*-"+#(!"#'*403#6*+#"=.14/"8
(!"#$*//*:)&9#'*5"#),#(!"#'*++"'(#:.0#(*#)("+.("#*-"+#(!" QList<int>#+"(%+&"5#70 QSplitter::sizes()K
QVector<double> table = sineTable();
vector<double> table;
!),#),#7"'.%," QSplitter::sizes()#+"(%+&,#.#&": QList<int>#70#-./%"#"-"+0#()1"#)(#),#'.//"53#;$#:" sineTable(table);
5*&2(#,(*+"#(!"#+"(%+&#-./%"8#IRR#.%(*1.()'.//0#5",(+*0,#)(#7"$*+"#:"#!.-"#"-"&#,(.+("5#)("+.()&98
/".-)&9#%,#:)(!#.#5.&9/)&9#)("+.(*+3# *#1.<"#1.(("+,#:*+,"8#".'!#()1"#(!"#/**4#),#+%&8
QSplitter::sizes()#1%,(#9"&"+.("#.#&":#'*40#*$#(!"#/),(#7"'.%,"#*$#(!" splitter->sizes().end() b(#%,",#)14/)')(#,!.+)&9#$*+#.//#*$#)(,#'*&(.)&"+,#.&5#$*+#1.&0#*(!"+#'/.,,",8#)&'/%5)&9 QByteArray8
'.//3#;&#,%11.+0K#>!"&#%,)&9#B EF,(0/"#)("+.(*+,8#./:.0,#)("+.("#*&#.#'*40#*$#.#'*&(.)&"+#+"(%+&"5 QBrush8 QFont8 QImage8 QPixmap8#.&5 QString3# !),#1.<",#(!","#'/.,,",#-"+0#"$$)')"&(#(*#4.,,#70
70#-./%"3 -./%"8#7*(!#.,#$%&'()*.+.1"("+,#.&5#.,#+"(%+&#-./%",3
!"#7".%(0#*$#)14/)')(#,!.+)&9#),#(!.(#)(#),#.&#*4()1)A.()*&#(!.(#:"#5*&2(#&""5#(*#(!)&<#.7*%(C#)(
,)14/0#:*+<,8#:)(!*%(#+"D%)+)&9#.&0#4+*9+.11"+#)&("+-"&()*&3#G(#(!"#,.1"#()1"8#)14/)')(#,!.+)&9 QLinkedList<Movie> list;
"&'*%+.9",#.#'/".+*9+.11)&9#,(0/"#:!"+"#*7H"'(,#.+"#+"(%+&"5#70#-./%"3#I*&,)5"+#(!"#$*//*:)&9 ...
foreach (Movie movie, list) {
$%&'()*&K
if (movie.title() == "Citizen Kane") {
cout << "Found Citizen Kane" << endl;
break;
QVector<double> sineTable() }
}
QSharedDataPointer#'/.,,",3
QLinkedList<Movie> list;
Movie movie;
How Implicit Sharing Works ...
foreach (movie, list) {
;14/)')(#,!.+)&9#:*+<,#.%(*1.()'.//0#7"!)&5#(!"#,'"&",8#,*#:"#5*&2(#!.-"#(*#5*#.&0(!)&9 if (movie.title() == "Citizen Kane") {
)&#*%+#'*5"#(*#1.<"#(!),#*4()1)A.()*&#!.44"&3#[%(#,)&'"#)(2,#&)'"#(*#<&*:#!*:#(!)&9, cout << "Found Citizen Kane" << endl;
:*+<8#:"#:)//#,(%50#.&#"=.14/"#.&5#,""#:!.(#!.44"&,#%&5"+#(!"#!**53# !"#"=.14/" break;
%,", QString8#*&"#*$#b(2,#1.&0#)14/)')(/0#,!.+"5#'/.,,",3 }
}
str2.truncate(4);
str1 = str2;
QMap<QString, int> map;
map.insert("eins", 1);
>!"&#:"#.,,)9& str2#(* str18#(!"#+"$"+"&'"#'*%&(#$*+ str12,#5.(.#9*",#5*:&#(*#L8#:!)'! map.insert("sieben", 7);
1".&,#(!.(#&* QString#),#%,)&9#(!"#VJ%14(0V#5.(.#.&01*+"3# !"#5.(.#), (!"&#$+""5#$+*1 map.insert("dreiundzwanzig", 23);
1"1*+03#[*(! QString,#4*)&(#(*#V`%14V8#:!)'!#&*:#!.,#.#+"$"+"&'"#'*%&(#*$#Q3
`.(.#,!.+)&9#),#*$("),+"9.+5"5#.,#.&#*4()*&#)%/()(!+".5"5#4+*9+.1,8#7"'.%,"#*$ G/("+&.()-"/08#:"#'.&#,)14/0#.,,)9&#.#-./%"#(*#.#9)-"&#<"0#.,#$*//*:,K
+.'"#'*&5)()*&,#)&#(!"#+"$"+"&'"#'*%&()&93#>)(!#b(8#(!),#),#&*(#.&#),,%"3#;&("+&.//08#(!"
'*&(.)&"+#'/.,,",#%,"#.,,"17/0#/.&9%.9"#)&,(+%'()*&,#(*#4"+$*+1#.(*1)'#+"$"+"&'"
'*%&()&93# !),#("'!&*/*90#),#.-.)/.7/"#(*#b(#%,"+,#(!+*%9!#(!" QSharedData#.&5 map["eins"] = 1;
map["sieben"] = 7;
map["dreiundzwanzig"] = 23; (04",8 QChar8 QString8#.&5 QByteArray3
QHash<K, T>#.%(*1.()'.//0#.//*'.(",#.#4+)1"#&%17"+#*$#7%'<"(,#$*+#)(,#)&("+&./#!.,!#(.7/"#.&5#+",)A",
!" []#*4"+.(*+#'."#%,"5#$*+#7*(!#)&,"+()*&#.&5#+"(+)"-./3#;$ []#),#%,"5#(*#+"(+)"-"#.#-./%"#$*+#. (!),#.,#)("1,#.+"#)&,"+("5#*+#+"1*-"53#;(#),#./,*#4*,,)7/"#(*#$)&"F(%&"#4"+$*+1.&'"#70#'.//)&9
&*&F"=),("&(#<"0#)&#.#&*&F'*&,(#1.48#.#&":#)("1#:)//#7"#'+".("5#:)(!#(!"#9)-"&#<"0#.&5#.&#"14(0 reserve()#(*#,4"')$0#(!"#&%17"+#*$#)("1,#"=4"'("5#(*#7"#,(*+"5#)&#(!"#!.,!#.&5 squeeze()#(*#,!+)&<
-./%"3# *#.-*)5#.'')5"&(.//0#'+".()&9#"14(0#-./%",8#:"#'.&#%,"#(!" value()#$%&'()*&#(*#+"(+)"-"#)("1, (!"#!.,!#(.7/"#7.,"5#*&#(!"#'%++"&(#&%17"+#*$#)("1,3#G#'*11*&#)5)*1#),#(*#'.// reserve()#:)(!#(!"
)&,(".5#*$ []K 1.=)1%1#&%17"+#*$#)("1,#:"#"=4"'(8#(!"&#)&,"+(#(!"#5.(.8#.&5#$)&.//0#'.// squeeze()#(*#1)&)1)A"
1"1*+0#%,.9"#)$#(!"+"#:"+"#$":"+#)("1,#(!.&#"=4"'("53
!"#".,)",(#:.0#(*#)("+.("#(!+*%9!#.//#(!"#<"0-./%"#4.)+,#,(*+"5#)&#.&#.,,*').()-"#'*&(.)&"+#),#(*#%,"
int seconds = map.value("delay", 30); .#c.-.F,(0/"#)("+.(*+3#["'.%,"#(!"#)("+.(*+,#1%,(#9)-"#.''",,#(*#7*(!#.#<"0#.&5#.#-./%"8#(!"#c.-.F
,(0/"#)("+.(*+,#$*+#.,,*').()-"#'*&(.)&"+,#:*+<#,/)9!(/0#5)$$"+"&(/0#$+*1#(!")+#,"D%"&()./#'*%&("+4.+(,3
!"#1.))$$"+"&'"#),#(!.(#(!" next()#.&5 previous()#$%&'()*&,#+"(%+&#.&#*7H"'(#(!.(#+"4+","&(,#.
!),#),#"D%)-./"&(#(* <"0-./%"#4.)+8#+.(!"+#(!.&#,)14/0#.#-./%"3# !"#<"0#.&5#-./%"#'*14*&"&(,#.+"#.''",,)7/"#$+*1#(!),
*7H"'(#., key()#.&5 value()3#6*+#"=.14/"K
a.4,#.+"#&*+1.//0#,)&9/"F-./%"5K#;$#.#&":#-./%"#),#.,,)9&"5#(*#.&#"=),()&9#<"08#(!"#*/5#-./%"#),
QMapIterator<QString, int> i(map);
+"4/.'"5#70#(!"#&":#-./%"8#"&,%+)&9#(!.(#&*#(:*#)("1,#,!.+"#(!"#,.1"#<"03#;(#),#4*,,)7/"#(* !.-"
while (i.hasNext()) {
1%/()4/"#<"0-./%"#4.)+,#:)(!#(!"#,.1"#<"0#70#%,)&9#(!" insertMulti()#$%&'()*&#*+#(!" QMultiMap<K, i.next();
T>#'*&-"&)"&'"#,%7'/.,,3 QMap<K, T>#!.,#. values(const K &)#*-"+/*.5#(!.(#+"(%+&,#. QList#*$#.//#(!" if (i.value() > largestValue) {
-./%",#$*+#.#9)-"&#<"03#6*+#"=.14/"K largestKey = i.key();
largestValue = i.value();
}
QMultiMap<int, QString> multiMap; }
multiMap.insert(1, "one");
multiMap.insert(1, "eins");
multiMap.insert(1, "uno");
a%(.7/"#)("+.(*+,#!.-"#. setValue()#$%&'()*&#(!.(#1*5)$)",#(!"#-./%"#.,,*').("5#:)(!#(!"#'%++"&(
QList<QString> vals = multiMap.values(1);
)("1K
!" foreach#/**4#./,*#:*+<,#*&#.,,*').()-"#'*&(.)&"+,8#7%(#*&/0#*&#(!"#-./%"#'*14*&"&(#*$#(!"
<"0-./%"#4.)+,3#;$#:"#&""5#7*(!#(!"#<"0#.&5#(!"#-./%"#'*14*&"&(,#*$#(!"#)("1,8#:"#'.&#'.//#(!" QVector<int> vect(list.count());
keys()#.&5 values(const K &)#$%&'()*&,#)&#&",("5 foreach#/**4,#.,#$*//*:,K qCopy(list.begin(), list.end(), vect.begin());
!" <QtAlgorithms>#!".5"+#5"'/.+",#.#,"(#*$#9/*7./#("14/.("#$%&'()*&,#(!.(#)14/"1"&(#7.,)'
./9*+)(!1,#*&#'*&(.)&"+,3#a*,(#*$#(!","#$%&'()*&,#*4"+.("#*&#B EF,(0/"#)("+.(*+,3 qSort(list.begin(), list.end());
!" qFill()#./9*+)(!1#4*4%/.(",#.#'*&(.)&"+#:)(!#.#4.+()'%/.+#-./%"K
QStringList list;
...
QLinkedList<int> list(10); qSort(list.begin(), list.end(), insensitiveLessThan);
qFill(list.begin(), list.end(), 1009);
qDeleteAll(list);
list.clear();
!),#$%&'()*&#,%44*+(,#(!"#,.1"#$*+1.(#,4"')$)"+,#.,#(!"#IRR#/)7+.+02, sprintf()#$%&'()*&3#;&#(!"
!" qSwap()#./9*+)(!1#"='!.&9",#(!"#-./%"#*$#(:*#-.+).7/",3#6*+#"=.14/"K "=.14/"#.7*-"8 str#),#.,,)9&"5#V4"+$"'(#'*14"()()*&#OLL3LkV3
l"(#.&*(!"+#:.0#*$#7%)/5)&9#.#,(+)&9#$+*1#*(!"+#,(+)&9,#*+#$+*1#&%17"+,#),#(*#%," arg()
int x1 = line.x1();
int x2 = line.x2();
if (x1 > x2) str = QString("%1 %2 (%3s-%4s)")
qSwap(x1, x2); .arg("permissive").arg("society").arg(1950).arg(1970);
>"#:)//#,(.+(#:)(! QString3#B(+)&9,#.+"#%,"5#70#"-"+0#^_;#4+*9+.18#&*(#*&/0#$*+#(!"#%,"+#)&("+$.'"
7%(#*$("&#./,*#.,#5.(.#,(+%'(%+",3#IRR#&.()-"/0#4+*-)5",#(:*#<)&5,#*$#,(+)&9,K#(+.5)()*&./#IF,(0/"#2iL2F K2#B'&"H#$%( setNum()#GB"3$&9"
("+1)&.("5#'!.+.'("+#.++.0,#.&5#(!" std::string#'/.,,3#_&/)<"#(!","8 QString#!*/5,#OdF7)(#_&)'*5"
-./%",3#_&)'*5"#'*&(.)&,#GBI;;#.&5#E.()&FO#.,#.#,%7,"(8#:)(!#(!")+#%,%./#&%1"+)'#-./%",3#[%(#,)&'"
QString#),#OdF7)(8#)(#'.&#+"4+","&(#(!*%,.&5,#*$#*(!"+#'!.+.'("+,#$*+#:+)()&9#1*,(#*$#(!"#:*+/52, str.setNum(59.6);
/.&9%.9",3#B"" I!.4("+#Oj#$*+#1*+"#)&$*+1.()*&#.7*%(#_&)'*5"3
>!"&#%,)&9 QString8#:"#5*&2(#&""5#(*#:*++0#.7*%(#,%'!#.+'.&"#5"(.)/,#.,#.//*'.()&9#"&*%9!#1"1*+0
A%(#2(7(2'(#39"7(2'&9".#G29+#*#'$2&"H#$9#*#"B+5(2.#&'#*3%&(7(4#B'&"H toInt(). toLongLong().
*+#"&,%+)&9#(!.(#(!"#5.(.#),#2iL2F("+1)&.("53#I*&'"4(%.//08 QString,#'."#(!*%9!(#*$#.,#.#-"'(*+#*$
toDouble().#*"4#'9#9"@#L92#()*+,-(
QChar,3#G QString#'.&#"17"5#2iL2#'!.+.'("+,3# !" length()#$%&'()*&#+"(%+&,#(!"#,)A"#*$#(!"#"&()+"
,(+)&98#)&'/%5)&9#"17"55"5#2iL2#'!.+.'("+,3
bool ok;
QString#4+*-)5",#.#7)&.+0 +#*4"+.(*+#(*#'*&'.("&.("#(:*#,(+)&9,#.&5#. +=#*4"+.(*+#(*#.44"&5#*&" double d = str.toDouble(&ok);
,(+)&9#(*#.&*(!"+3#["'.%," QString#.%(*1.()'.//0#4+".//*'.(",#1"1*+0#.(#(!"#"&5#*$#(!"#,(+)&9#5.(.8
7%)/5)&9#%4#.#,(+)&9#70#+"4".("5/0#.44"&5)&9#'!.+.'("+,#),#-"+0#$.,(3#J"+"2,#.&#"=.14/"#(!.(
'*17)&", +#.&5 +=K A%('(#GB"3$&9"'#*33(,$#*"#9,$&9"*-#,9&"$(2#$9#* bool#7*2&*5-(#*"4#'($#$%(#7*2&*5-(#$9 TRue#92 false
4(,("4&"H#9"#$%(#'B33(''#9G#$%(#39"7(2'&9"@#!G#$%(#39"7(2'&9"#G*&-'.#$%('(#GB"3$&9"'#2($B2"#M(29@
QString str = "User: ";
str += userName + "\n"; K"3(#I(#%*7(#*#'$2&"H.#I(#9G$("#I*"$#$9#()$2*3$#,*2$'#9G#&$@#A%( mid()#GB"3$&9"#2($B2"'#$%(#'B5'$2&"H
'$*2$&"H#*$#*#H&7("#,9'&$&9"#C$%(#G&2'$#*2HB+("$E#*"4#9G#B,#$9#*#H&7("#-("H$%#C$%(#'(39"4#*2HB+("$E@
L92#()*+,-(.#$%(#G9--9I&"H#394(#,2&"$' /,*6'/#$9#$%(#39"'9-( NOP
A%(2(#*2(#97(2-9*4(4#7(2'&9"'#9G replace()#$%*$#2(,-*3(#*--#933B22("3('#9G#$%(&2#G&2'$#*2HB+("$#I&$%
QString str = "polluter pays principle"; $%(&2#'(39"4#*2HB+("$@#L92#()*+,-(.#%(2(S'#%9I#$9#2(,-*3(#*--#933B22("3('#9G#/U/#I&$%#/U*+,V/#&"#*
'$2&"H
!G#I(#I*"$#$9#G&"4#9B$#&G#*#'$2&"H#39"$*&"'#*#,*2$&3B-*2#3%*2*3$(2.#'B5'$2&"H.#92#2(HB-*2#(),2(''&9".#I(
3*"#B'(#9"(#9G QStringS' indexOf()#GB"3$&9"' K"(#7(26#G2(WB("$ "((4#&'#$9#'$2&,#$%(#I%&$(',*3(#C'B3%#*'#',*3('.#$*5'.#*"4#"(I-&"('E#G29+#*
'$2&"H@ QString#%*'#*#GB"3$&9"#$%*$#(-&+&"*$('#I%&$(',*3(#G29+#59$%#("4'#9G#*#'$2&"H
A%&'#&'#59$%#'&+,-(2#*"4#G*'$(2#$%*"#$%&'
X%("#%*"4-&"H#B'(2#&",B$.#I(#9G$("#*-'9#I*"$#$9#2(,-*3(#(7(26#'(WB("3(#9G#9"(#92#+92(#&"$(2"*-
I%&$(',*3(#3%*2*3$(2'#I&$%#'&"H-(#',*3('.#&"#*44&$&9"#$9#'$2&,,&"H#I%&$(',*3(#G29+#59$%#("4'@#A%&'#&'
if (url.left(5) == "http:" && url.right(4) == ".png") I%*$#$%( simplified()#GB"3$&9"#49('
...
if (fileName.toLower() == "readme.txt")
...
!"#$%(#()*+,-(#*597(.#I(#',-&$#$%(#'$2&"H#/,9--B$(2#,*6'#,2&"3&,-(/#&"$9#$%2((#'B5'$2&"H' #/,9--B$(2/.
/,*6'/.#*"4#/,2&"3&,-(/@#A%( split()#GB"3$&9"#%*'#*"#9,$&9"*-#$%&24#*2HB+("$#$%*$#',(3&G&('#I%($%(2
A%(#2('B-$#&'#/* 'B""6#4*6/@#A%(#394(#3*"#5(#2(I2&$$("#$9#B'( remove()#*"4 insert()
(+,$6#'B5'$2&"H'#'%9B-4#5(#T(,$#C$%(#4(G*B-$E#92#4&'3*24(4@
a*2&*"$'#*2(#B'(4#()$("'&7(-6#56#$%(#&$(+#7&(I#3-*''('.#$%(#4*$*5*'(#+94B-(.#*"4 QSettings.
words.sort(); *--9I&"H#B'#$9#2(*4#*"4#I2&$(#&$(+#4*$*.#4*$*5*'(#4*$*.#*"4#B'(2#,2(G(2("3('#G92#*"6 QVariantD
str = words.join("\n");
39+,*$&5-(#$6,(@#X(#%*7(#*-2(*46#'(("#*"#()*+,-(#9G#$%&'#&" [%*,$(2#:.#I%(2(#I(#,*''(4#* QRect.#*
QStringList.#*"4#*#39B,-(#9G bool'#*'#7*2&*"$'#$9 QSettings::setValue().#*"4#2($2&(7(4#$%(+#-*$(2#*'
7*2&*"$'@
X%("#4(*-&"H#I&$%#'$2&"H'.#I(#9G$("#"((4#$9#4($(2+&"(#I%($%(2#*#'$2&"H#&'#(+,$6#92#"9$@#A%&'#&'
49"(#56#3*--&"H isEmpty()#92#56#3%(3T&"H#I%($%(2 length()#&'#=@ !$#&'#,9''&5-(#$9#32(*$(#*25&$2*2&-6#39+,-()#4*$*#'$2B3$B2('#B'&"H QVariant#56#"('$&"H#7*-B('#9G
39"$*&"(2#$6,('
A%(#39"7(2'&9"#G29+ const char *#'$2&"H'#$9 QString#&'#*B$9+*$&3#&"#+9'$#3*'('.#G92#()*+,-(
!"#'9+(#'&$B*$&9"'.#I(#"((4#$9#'$92(#4*$*#9G#4&GG(2("$#$6,('#&"#$%(#'*+(#7*2&*5-(@#K"(#*,,29*3%#&'#$9 QVariant#3*"#*-'9#5(#B'(4#$9#'$92(#3B'$9+#4*$*#$6,('.#*''B+&"H#$%(6#,297&4(#*#4(G*B-$#39"'$2B3$92
("394(#$%(#4*$*#*'#* QByteArray#92#* QString@#L92#()*+,-(.#*#'$2&"H#39B-4#%9-4#*#$()$B*-#7*-B(#92#* *"4#*#39,6#39"'$2B3$92@#L92#$%&'#$9#I92T.#I(#+B'$#G&2'$#2(H&'$(2#$%(#$6,(#B'&"H#$%(
"B+(2&3#7*-B(#&"#'$2&"H#G92+@#A%('(#*,,29*3%('#H&7(#39+,-($(#G-()&5&-&$6.#5B$#49#*I*6#I&$%#'9+(#9G Q_DECLARE_METATYPE()#+*329.#$6,&3*--6#&"#*#%(*4(2#G&-(#5(-9I#$%(#3-*''#4(G&"&$&9" W
[``S'#5("(G&$'.#&"#,*2$&3B-*2#$6,(#'*G($6#*"4#(GG&3&("36@#\$#,297&4('#*#+B3%#3-(*"(2#I*6#9G#%*"4-&"H
7*2&*5-('#$%*$#3*"#%9-4#4&GG(2("$#$6,(' QVariant@
Q_DECLARE_METATYPE(BusinessCard)
A%( QVariant#3-*''#3*"#%9-4#7*-B('#9G#+*"6#\$#$6,('.#&"3-B4&"H QBrush. QColor. QCursor. QDateTime.
QFont. QKeySequence. QPalette. QPen. QPixmap. QPoint. QRect. QRegion. QSize.#*"4 QString.#*'#I(--#*'
A%&'#("*5-('#B'#$9#I2&$(#394(#-&T(#$%&'
Chapter 12. Input/Output
BusinessCard businessCard;
• !"#$%&'"%#'()$*$%&'+$%"),'-"*"
QVariant variant = QVariant::fromValue(businessCard);
• !"#$%&'"%#'()$*$%&'.!/*
...
if (variant.canConvert<BusinessCard>()) { • .)"0!)1$%&'-$)!2*3)$!1
BusinessCard card = variant.value<BusinessCard>(); • 456!##$%&' !137)2!1
... • 8%*!)9:)32!11';3557%$2"*$3%
}
A%(#"((4#$9#2(*4#G29+#92#I2&$(#$9#G&-('#92#9$%(2#4(7&3('#&'#39++9"#$9#*-+9'$#(7(26#*,,-&3*$&9"@#\$
,297&4('#()3(--("$#'B,,92$#G92#!fK#$%29BH% QIODevice.#*#,9I(2GB-#*5'$2*3$&9"#$%*$#("3*,'B-*$('
R(3*B'(#9G#*#39+,&-(2#-&+&$*$&9".#$%('(#$(+,-*$(#+(+5(2#GB"3$&9"'#*2(#"9$#*7*&-*5-(#G92#dFa[#e@#!G /4(7&3('/#3*,*5-(#9G#2(*4&"H#*"4#I2&$&"H#5-93T'#9G#56$('@ \$#&"3-B4('#$%(#G9--9I&"H QIODevice
69B#"((4#$9#B'(#$%&'#39+,&-(2.#B'(#$%( qVariantFromValue(). qVariantValue<T>().#*"4 'B53-*''('
qVariantCanConvert<T>()#H-95*-#GB"3$&9"'#&"'$(*4@
QFile Y33(''('#G&-('#&"#$%(#-93*-#G&-(#'6'$(+#*"4#&"#(+5(44(4#2('9B23('
!G#$%(#3B'$9+#4*$*#$6,(#%*' <<#*"4 >>#9,(2*$92'#G92#I2&$&"H#$9#*"4#2(*4&"H#G29+#* QDataStream.#I(
3*"#2(H&'$(2#$%(+#B'&"H qRegisterMetaTypeStreamOperators<T>()@#A%&'#+*T('#&$#,9''&5-(#$9#'$92( QTemporaryFile [2(*$('#*"4#*33(''('#$(+,92*26#G&-('#&"#$%(#-93*-#G&-(#'6'$(+
,2(G(2("3('#9G#3B'$9+#4*$*#$6,('#B'&"H QSettings.#*+9"H 9$%(2#$%&"H'@#L92#()*+,-(
QBuffer g(*4'#4*$*#G29+#92#I2&$('#4*$*#$9#* QByteArray
QProcess gB"'#()$(2"*-#,29H2*+'#*"4#%*"4-('#&"$(2D,293(''#39++B"&3*$&9"
qRegisterMetaTypeStreamOperators<BusinessCard>("BusinessCard");
QTcpSocket A2*"'G(2'#*#'$2(*+#9G#4*$*#97(2#$%(#"($I92T#B'&"H#A[]
A%&'#3%*,$(2#%*'#G93B'(4#9"#$%(#\$#39"$*&"(2'.#*'#I(--#*'#9" QString. QByteArray.#*"4 QVariant@#!" QUdpSocket F("4'#92#2(3(&7('#Jh]#4*$*H2*+'#97(2#$%(#"($I92T
*44&$&9"#$9#$%('(#3-*''('.#\$#*-'9#,297&4('#*#G(I#9$%(2#39"$*&"(2'@#K"(#&' QPair<T1, T2>.#I%&3%
'&+,-6#'$92('#$I9#7*-B('#*"4#&'#'&+&-*2#$9 std::pair<T1, T2>@#Y"9$%(2#&' QBitArray.#I%&3%#I(#I&--#B'(
&"#$%(#G&2'$#'(3$&9"#9G [%*,$(2#1;@#L&"*--6.#$%(2(#&' QVarLengthArray<T,Prealloc>.#*#-9ID-(7(-
QProcess. QTcpSocket.#*"4 QUdpSocket#*2(#'(WB("$&*-#4(7&3('.#+(*"&"H#$%*$#$%(#4*$*#3*"#9"-6#5(
*-$(2"*$&7(#$9 QVector<T>@#R(3*B'(#&$#,2(*--93*$('#+(+926#9"#$%(#'$*3T#*"4#&'"S$#&+,-&3&$-6#'%*2(4.#&$'
*33(''(4#9"3(.#'$*2$&"H#G29+#$%(#G&2'$#56$(#*"4#,29H2(''&"H#'(2&*--6#$9#$%(#-*'$#56$(@ QFile.
97(2%(*4#&'#-(''#$%*"#$%*$#9G QVector<T>.#+*T&"H#&$#+92(#*,,29,2&*$(#G92#$&H%$#-99,'@
QTemporaryFile.#*"4 QBuffer#*2(#2*"49+D*33(''#4(7&3('.#'9#56$('#3*"#5(#2(*4#*"6#"B+5(2#9G#$&+('
G29+#*"6#,9'&$&9"V#$%(6#,297&4(#$%( QIODevice::seek()#GB"3$&9"#G92#2(,9'&$&9"&"H#$%(#G&-(#,9&"$(2@
\$S'#*-H92&$%+'.#&"3-B4&"H#*#G(I#"9$#397(2(4#%(2(#'B3%#*' qCopyBackward()#*"4 qEqual().#*2(
4('32&5(4#&"#\$S'#493B+("$*$&9"#*$ %$$, ff493@$29--$(3%@39+f>@1f*-H92&$%+'@%$+-@#Y"4#G92#+92(
!"#*44&$&9"#$9#$%(#4(7&3(#3-*''('.#\$#*-'9#,297&4('#$I9#%&H%(2D-(7(-#'$2(*+#3-*''('#$%*$#I(#3*"#B'(
4($*&-'#9G#\$S'#39"$*&"(2'.#&"3-B4&"H#&"G92+*$&9"#9"#$%(&2#$&+(#39+,-()&$6#*"4#H29I$%#'$2*$(H&('.#'((
$9#2(*4#G29+#*"4#I2&$(#$9#*"6#!fK#4(7&3( QDataStream#G92#5&"*26#4*$*#*"4 QTextStream#G92#$()$@
%$$, ff493@$29--$(3%@39+f>@1f39"$*&"(2'@%$+-@
A%('(#3-*''('#$*T(#3*2(#9G#&''B('#'B3%#*'#56$(#924(2&"H#*"4#$()$#("394&"H'.#("'B2&"H#$%*$#\$
*,,-&3*$&9"'#2B""&"H#9"#4&GG(2("$#,-*$G92+'#92#&"#4&GG(2("$#39B"$2&('#3*"#2(*4#*"4#I2&$(#(*3%#9$%(2S'
G&-('@#A%&'#+*T('#\$S'#!fK#3-*''('#+B3%#+92(#39"7("&("$#$%*"#$%(#3922(',9"4&"H#F$*"4*24#[``
3-*''('.#I%&3%#-(*7(#$%('(#&''B('#$9#$%(#*,,-&3*$&9"#,29H2*++(2@
QFile#+*T('#&$#(*'6#$9#*33(''#&"4&7&4B*-#G&-('.#I%($%(2#$%(6#*2(#&"#$%(#G&-(#'6'$(+#92#(+5(44(4#&"
$%(#*,,-&3*$&9"S'#()(3B$*5-(#*'#2('9B23('@#L92#*,,-&3*$&9"'#$%*$#"((4#$9#&4("$&G6#I%9-(#'($'#9G#G&-('#$9
I92T#9".#\$#,297&4('#$%( QDir *"4 QFileInfo#3-*''('.#I%&3%#%*"4-(#4&2(3$92&('#*"4#,297&4(
&"G92+*$&9"#*59B$#$%(#G&-('#&"'&4(#$%(+@
A%( QProcess#3-*''#*--9I'#B'#$9#-*B"3%#()$(2"*-#,29H2*+'#*"4#$9#39++B"&3*$(#I&$%#$%(+#$%29BH%
$%(&2#'$*"4*24#&",B$.#'$*"4*24#9B$,B$.#*"4#'$*"4*24#(2292#3%*""(-'#Ccin. cout.#*"4 cerrE@#X(#3*"#'($
$%(#("7&29"+("$#7*2&*5-('#*"4#I92T&"H#4&2(3$926#$%*$#$%(#()$(2"*-#*,,-&3*$&9"#I&--#B'(@#R6#4(G*B-$.
39++B"&3*$&9"#I&$%#$%(#,293(''#&'#*'6"3%29"9B'#C"9"D5-93T&"HE.#5B$#&$#&'#*-'9#,9''&5-(#$9#5-93T#9"
3(2$*&"#9,(2*$&9"'@
b($I92T&"H#*"4#2(*4&"H#*"4#I2&$&"H#idj#*2(#'B3%#'B5'$*"$&*-#$9,&3'#$%*$#$%(6#*2(#397(2(4
'(,*2*$(-6#&"#$%(&2#9I"#4(4&3*$(4#3%*,$(2'#C[%*,$(2#1>#*"4 [%*,$(2#1<E@
in >> n >> image >> map;
X(#49"S$#"((4#$9#(),-&3&$-6#3-9'(#$%(#G&-(#'&"3(#$%&'#&'#49"(#*B$9+*$&3*--6#I%("#$%( QFile#7*2&*5-(
H9('#9B$#9G#'39,(@#!G#I(#I*"$#$9#7(2&G6#$%*$#$%(#4*$*#%*'#*3$B*--6#5(("#I2&$$(".#I(#3*"#3*-- flush()
Z(2(S'#%9I#I(#I9B-4#&+,-(+("$#$%( <<#9,(2*$92
*"4#3%(3T#&$'#2($B2"#7*-B(#Ctrue#9"#'B33(''E@
X(#3*"#2(*4#$%(#4*$*#*'#-9"H#*'#$%(#'$2(*+#7(2'&9"#&'#-(''#$%*"#92#(WB*-#$9#$%(#7(2'&9"#B'(4#56#$%(
QList<Painting> paintings = ...; *,,-&3*$&9"V#9$%(2I&'(.#I(#2(,92$#*"#(2292@
!G#$%(#G&-(#G92+*$#39"$*&"'#*#7(2'&9"#"B+5(2#9G#&$'#9I".#I(#3*"#B'(#&$#$9#4(4B3(#$%(#'$2(*+#7(2'&9"
out << paintings; "B+5(2#&"'$(*4#9G#'$92&"H#&$#(),-&3&$-6@#L92#()*+,-(.#-($S'#'B,,9'(#$%*$#$%(#G&-(#G92+*$#&'#G92#7(2'&9"
1@:#9G#9B2#*,,-&3*$&9"@#X(#+&H%$#$%("#I2&$(#$%(#4*$*#*'#G9--9I'
X(#3*"#2(*4#&"#39"$*&"(2'#QB'$#*'#(*'&-6
QDataStream out(&file);
out.setVersion(QDataStream::Qt_4_1);
out << quint32(MagicNumber) << quint16(0x0103);
QList<Painting> paintings;
in >> paintings;
X%("#I(#2(*4#&$#5*3T.#I(#4($(2+&"(#I%&3% QDataStream#7(2'&9"#$9#B'(#5*'(4#9"#$%(#*,,-&3*$&9"S'
7(2'&9"#"B+5(2
A%&'#I9B-4#2('B-$#&"#*#39+,&-(2#(2292#&G Painting#4&4"S$#'B,,92$ <<#92 >>@#Y"9$%(2#5("(G&$#9G#,297&4&"H
'$2(*+&"H#9,(2*$92'#G92#3B'$9+#$6,('#&'#$%*$#I(#3*"#'$92(#7*-B('#9G#$%('(#$6,('#*' QVariant'.#I%&3%
+*T('#$%(+#+92(#I&4(-6#B'*5-(.#G92#()*+,-(#56 QSettings@#A%&'#I92T'#,297&4(4#$%*$#I(#2(H&'$(2#$%(
QDataStream in(&file);
$6,(#B'&"H qRegisterMetaTypeStreamOperators<T>()#5(G92(%*"4.#*'#(),-*&"(4#&" [%*,$(2#11#C,@#8?=E@ in >> magic >> appVersion;
if (magic != MagicNumber) {
X%("#I(#B'( QDataStream.#\$#$*T('#3*2(#9G#2(*4&"H#*"4#I2&$&"H#(*3%#$6,(.#&"3-B4&"H#39"$*&"(2'#I&$% cerr << "File is not recognized by this application" << endl;
*"#*25&$2*26#"B+5(2#9G#&$(+'@#A%&'#2(-&(7('#B'#G29+#$%(#"((4#$9#'$2B3$B2(#I%*$#I(#I2&$(#*"4#G29+ return false;
,(2G92+&"H#*"6#T&"4#9G#,*2'&"H#9"#I%*$#I(#2(*4@#KB2#9"-6#95-&H*$&9"#&'#$9#("'B2(#$%*$#I(#2(*4#*-- } else if (appVersion > 0x0103) {
$%(#$6,('#&"#()*3$-6#$%(#'*+(#924(2#*'#I(#I29$(#$%(+.#-(*7&"H#\$#$9#%*"4-(#*--#$%(#4($*&-'@ cerr << "File is from a more recent version of the application"
<< endl;
return false;
QDataStream#&'#B'(GB-#59$%#G92#9B2#9I"#3B'$9+#*,,-&3*$&9"#G&-(#G92+*$'#*"4#G92#'$*"4*24#5&"*26
}
G92+*$'@#X(#3*"#2(*4#*"4#I2&$(#'$*"4*24#5&"*26#G92+*$'#B'&"H#$%(#'$2(*+&"H#9,(2*$92'#9"#5*'&3 if (appVersion < 0x0103) {
$6,('#C-&T( quint16#92 floatE#92#B'&"H readRawBytes()#*"4 writeRawBytes()@#!G#$%( QDataStream#&' in.setVersion(QDataStream::Qt_3_0);
5(&"H#B'(4#,B2(-6#$9#2(*4#*"4#I2&$(#5*'&3#[``#4*$*#$6,('.#I(#49"S$#(7("#"((4#$9#3*-- setVersion()@ } else {
in.setVersion(QDataStream::Qt_4_1);
F9#G*2.#I(#-9*4(4#*"4#'*7(4#4*$*#I&$%#$%(#'$2(*+S'#7(2'&9"#%*24D394(4#*' QDataStream::Qt_4_1@#A%&' }
*,,29*3%#&'#'&+,-(#*"4#'*G(.#5B$#&$#49('#%*7(#9"(#'+*--#42*I5*3T #X(#3*""9$#$*T(#*47*"$*H(#9G
"(I#92#B,4*$(4#G92+*$'@#L92#()*+,-(.#&G#*#-*$(2#7(2'&9"#9G#\$#*44(4#*#"(I#*$$2&5B$(#$9 QFont#C&"
*44&$&9"#$9#&$'#,9&"$#'&M(.#G*+&-6.#($3@E#*"4#I(#%*24D394(4#$%(#7(2'&9"#"B+5(2#$9 Qt_4_1.#$%*$ !"#$%&'#()*+,-(.#I(#',(3&G6#$%*$#*"6#G&-(#'*7(4#I&$%#7(2'&9"'#,2&92#$9#1@:#9G#$%(#*,,-&3*$&9"#B'('#4*$*
*$$2&5B$(#I9B-4"S$#5(#'*7(4#92#-9*4(4@#A%(2(#*2(#$I9#'9-B$&9"'@#A%(#G&2'$#*,,29*3%#&'#$9#(+5(4#$%( '$2(*+#7(2'&9"#>#CQt_3_0E.#*"4#$%*$#G&-('#'*7(4#I&$%#7(2'&9"#1@:#9G#$%(#*,,-&3*$&9"#B'(#4*$*#'$2(*+
QDataStream#7(2'&9"#"B+5(2#&"#$%(#G&-( 7(2'&9"#?#CQt_4_1E@
!G#I(#I*"$#$9#2(*4#92#I2&$(#*#G&-(#&"#9"(#H9.#I(#3*"#*79&4#B'&"H QDataStream#*-$9H($%(2#*"4#&"'$(*4
B'( QIODeviceS' write()#*"4 readAll()#GB"3$&9"'@#L92#()*+,-( X2&$&"H#$()$#&'#7(26#(*'6.#5B$#2(*4&"H#$()$#3*"#5(#3%*--("H&"H.#5(3*B'(#$()$B*-#4*$*#CB"-&T(#5&"*26
4*$*#I2&$$("#B'&"H QDataStreamE#&'#GB"4*+("$*--6#*+5&HB9B'@#j($S'#39"'&4(2#$%(#G9--9I&"H#()*+,-(
A%(#JALD^#("394&"H#B'(4#&"#$%(#()*+,-(#&'#*#,9,B-*2#YF[!!D39+,*$&5-(#("394&"H#$%*$#3*"#2(,2('("$
Reading and Writing Text $%(#("$&2(#J"&394(#3%*2*3$(2#'($@#L92#+92(#&"G92+*$&9"#*59B$#J"&394(#*"4 QTextStreamS'#'B,,92$#G92
("394&"H'.#'(( [%*,$(2#1?#C!"$(2D"*$&9"*-&M*$&9"E@
X%&-(#5&"*26#G&-(#G92+*$'#*2(#$6,&3*--6#+92(#39+,*3$#$%*"#$()$D5*'(4#G92+*$'.#$%(6#*2(#"9$#%B+*"D
2(*4*5-(#92#%B+*"D(4&$*5-(@#!"#3*'('#I%(2(#$%&'#&'#*"#&''B(.#I(#3*"#B'(#$()$#G92+*$'#&"'$(*4@#\$ QTextStream#%*'#7*2&9B'#9,$&9"'#+94(-(4#*G$(2#$%9'(#9GG(2(4#56 <iostream>@#A%('(#3*"#5(#'($#56
,297&4('#$%( QTextStream#3-*''#G92#2(*4&"H#*"4#I2&$&"H#,-*&"#$()$#G&-('#*"4#G92#G&-('#B'&"H#9$%(2#$()$ ,*''&"H#',(3&*-#95Q(3$'.#3*--(4 *"%&+,-,+ ).(/+"$%*.#9"#$%(#'$2(*+#$9#*-$(2#&$'#'$*$(@#A%(#G9--9I&"H
G92+*$'.#'B3%#*'#ZAdj.#idj.#*"4#'9B23(#394(@#Z*"4-&"H#idj#G&-('#&'#397(2(4#'(,*2*$(-6#&" [%*,$(2 ()*+,-(#'($'#$%( showbase. upper-casedigits.#*"4 hex#9,$&9"'#5(G92(#&$#9B$,B$'#$%(#&"$(H(2
1<@ 18:><e?^.#,294B3&"H#$%(#$()$#/=)R[e1>k/
QTextStream#$*T('#3*2(#9G#39"7(2$&"H#5($I(("#J"&394(#*"4#$%(#'6'$(+S'#-93*-#("394&"H#92#*"6#9$%(2
("394&"H.#*"4#$2*"',*2("$-6#%*"4-('#$%(#4&GG(2("$#-&"(D("4&"H#39"7("$&9"'#B'(4#56#4&GG(2("$ out << showbase << uppercasedigits << hex << 12345678;
9,(2*$&"H#'6'$(+'#C/_2_"/#9"#X&"49I'.#/_"/#9"#J"&)#*"4#d*3#KF#iE@ QTextStream#B'('#$%(#1eD5&$
QChar#$6,(#*'#&$'#GB"4*+("$*-#B"&$#9G#4*$*@#!"#*44&$&9"#$9#3%*2*3$(2'#*"4#'$2&"H'. QTextStream
'B,,92$'#[``S'#5*'&3#"B+(2&3#$6,('.#I%&3%#&$#39"7(2$'#$9#*"4#G29+#'$2&"H'@#L92#()*+,-(.#$%( K,$&9"'#3*"#*-'9#5(#'($#B'&"H#+(+5(2#GB"3$&9"'
G9--9I&"H#394(#I2&$('#/A%9+*'#d@#h&'3% #::>_"/#$9#$%(#G&-( sf-book.txt
out.setNumberFlags(QTextStream::ShowBase
QFile file("sf-book.txt"); | QTextStream::UppercaseDigits);
if (!file.open(QIODevice::WriteOnly)) { out.setIntegerBase(16);
cerr << "Cannot open file for writing: " out << 12345678;
<< qPrintable(file.errorString()) << endl;
return;
}
QTextStream out(&file);
!"#$%&'()')& #*+,!-*.&,-&.%, QTextStream/.&-0,!-*. for (int row = 0; row < RowCount; ++row) {
[View full size image]
for (int column = 0; column < ColumnCount; ++column) {
QString str = formula(row, column);
if (!str.isEmpty())
out << row << " " << column << " " << str << endl;
}
}
X(#%*7(#B'(4#*#'&+,-(#G92+*$.#I&$%#(*3%#-&"(#2(,2('("$&"H#9"(#3(--#*"4#I&$%#',*3('#5($I(("#$%(
29I#*"4#$%(#39-B+"#*"4#5($I(("#$%(#39-B+"#*"4#$%(#G92+B-*@#A%(#G92+B-*#3*"#39"$*&"#',*3('.#5B$
I(#3*"#*''B+(#$%*$#&$#39"$*&"'#"9#S_"S#CI%&3%#I(#B'(#$9#$(2+&"*$(#-&"('E@#b9I#-($S'#-99T#*$#$%(
3922(',9"4&"H#2(*4&"H#394(
QTextStream in(&file);
while (!in.atEnd()) {
QString line = in.readLine();
QStringList fields = line.split(' ');
if (fields.size() >= 3) {
int row = fields.takeFirst().toInt();
int column = fields.takeFirst().toInt();
setFormula(row, column, fields.join(' '));
}
}
X(#2(*4#&"#$%(#F,2(*4'%(($#4*$*#9"(#-&"(#*$#*#$&+(@#A%( readLine()#GB"3$&9"#2(+97('#$%(#$2*&-&"H
S_"S@ QString::split()#2($B2"'#*#'$2&"H#-&'$.#%*7&"H#',-&$#&$'#'$2&"H#I%(2(7(2#$%(#'(,*2*$92#&$#&'#H&7("
*,,(*2'@#L92#()*+,-(.#$%(#-&"(#/<#1;#A9$*-#7*-B(/#2('B-$'#&"#$%(#G9B2D&$(+#-&'$#N/</.#/1;/.#/A9$*-/.
/7*-B(/P@
!G#I(#%*7(#*$#-(*'$#$%2((#G&(-4'.#I(#*2(#2(*46#$9#()$2*3$#$%(#4*$*@#A%( QStringList::takeFirst()
GB"3$&9"#2(+97('#$%(#G&2'$#&$(+#&"#*#-&'$#*"4#2($B2"'#$%(#2(+97(4#&$(+@#X(#B'(#&$#$9#()$2*3$#$%(#29I
*"4#39-B+"#"B+5(2'@#X(#49"S$#,(2G92+#*"6#(2292#3%(3T&"HV#&G#I(#2(*4#*#"9"D&"$(H(2#29I#92#39-B+"
7*-B(. QString::toInt()#I&--#2($B2"#=@#X%("#I(#3*-- setFormula().#I(#+B'$#39"3*$("*$(#$%(
2(+*&"&"H#G&(-4'#5*3T#&"$9#*#'&"H-(#'$2&"H@
!"#9B2#'(39"4 QTextStream#()*+,-(.#I(#I&--#B'(#*#3%*2*3$(2#56#3%*2*3$(2#*,,29*3%#$9#&+,-(+("$#*
,29H2*+#$%*$#2(*4'#&"#*#$()$#G&-(#*"4#9B$,B$'#$%(#'*+(#$()$#5B$#I&$%#$2*&-&"H#',*3('#2(+97(4#G29+
-&"('#*"4#*--#$*5'#2(,-*3(4#56#',*3('@#A%(#,29H2*+S'#I92T#&'#49"(#56#$%( tidyFile()#GB"3$&9"
A9#32(*$(#(*3%#'B54&2(3$926S'#,*$%.#I(#39+5&"(#$%(#3B22("$#4&2(3$926S'#,*$%#I&$%#$%(#'B54&2(3$926
"*+(.#'(,*2*$&"H#$%(+#I&$%#*#'-*'%@ QDir#$2(*$'#SfS#*'#*#4&2(3$926#'(,*2*$92#9"#*--#,-*$G92+'.#&"
L29+#$%(#*,,-&3*$&9".#2('9B23('#*2(#&4("$&G&(4#56#$%( :/#,*$%#,2(G&)@#!"#$%&'#()*+,-(.#$%(#4&*-&"H
*44&$&9"#$9#2(39H"&M&"H#S_S#9"#X&"49I'@#X%("#,2('("$&"H#,*$%'#$9#$%(#B'(2.#I(#3*"#3*--#$%(#'$*$&3
394('#G&-(#%*'#$%(#,*$% :/datafiles/phone-codes.dat#*"4#3*"#5(#2(*4#QB'$#-&T(#*"6#9$%(2#G&-(#B'&"H
GB"3$&9" QDir::convertSeparators()#$9#39"7(2$#'-*'%('#$9#$%(#3922(3$#,-*$G92+D',(3&G&3#'(,*2*$92@
QFile@
j($S'#*44#* main()#GB"3$&9"#$9#9B2#'+*--#,29H2*+
k+5(44&"H#4*$*#&"#$%(#()(3B$*5-(#%*'#$%(#*47*"$*H(#$%*$#&$#3*""9$#H($#-9'$#*"4#+*T('#&$#,9''&5-(#$9
32(*$(#$2B-6#'$*"4D*-9"(#()(3B$*5-('#C&G#'$*$&3#-&"T&"H#&'#*-'9#B'(4E@ AI9#4&'*47*"$*H('#*2(#$%*$#&G#$%(
(+5(44(4#4*$*#"((4'#3%*"H&"H#$%(#I%9-(#()(3B$*5-(#+B'$#5(#2(,-*3(4.#*"4#$%(#'&M(#9G#$%(
int main(int argc, char *argv[])
()(3B$*5-(#I&--#5(#-*2H(2#5(3*B'(#&$#+B'$#*339++94*$(#$%(#(+5(44(4#4*$*@
{
QCoreApplication app(argc, argv);
QStringList args = app.arguments(); \$S'#2('9B23(#'6'$(+#,297&4('#+92(#G(*$B2('#$%*"#I(#,2('("$(4#&"#$%&'#()*+,-(.#&"3-B4&"H#'B,,92$
QString path = QDir::currentPath(); G92#G&-(#"*+(#*-&*'('#*"4#G92#-93*-&M*$&9"@#A%('(#G*3&-&$&('#*2(#493B+("$(4#*$
if (args.count() > 1) %$$, ff493@$29--$(3%@39+f>@1f2('9B23('@%$+-@
path = args[1];
cout << "Space used by images in " << qPrintable(path)
<< " and its subdirectories is " << (imageSpace(path) / 1024) Inter-Process Communication
<< " KB" << endl;
return 0; A%( QProcess#3-*''#*--9I'#B'#$9#2B"#()$(2"*-#,29H2*+'#*"4#$9#&"$(2*3$#I&$%#$%(+@#A%(#3-*''#I92T'
} *'6"3%29"9B'-6.#49&"H#&$'#I92T#&"#$%(#5*3TH29B"4#'9#$%*$#$%(#B'(2#&"$(2G*3(#2(+*&"'#2(',9"'&7(@
QProcess#(+&$'#'&H"*-'#$9#"9$&G6#B'#I%("#$%(#()$(2"*-#,293(''#%*'#4*$*#92#%*'#G&"&'%(4@
Embedding Resources
F9#G*2#&"#$%&'#3%*,$(2#I(#%*7(#$*-T(4#*59B$#*33(''&"H#4*$*#&"#()$(2"*-#4(7&3('.#5B$#I&$%#\$#&$#&'#*-'9
,9''&5-(#$9#(+5(4#5&"*26#4*$*#92#$()$#&"'&4(#$%(#*,,-&3*$&9"S'#()(3B$*5-(@#A%&'#&'#*3%&(7(4#B'&"H#\$S'
2('9B23(#'6'$(+@#!"#9$%(2#3%*,$(2'.#I(#B'(4#2('9B23(#G&-('#$9#(+5(4#&+*H('#&"#$%(#()(3B$*5-(.#5B$
&$#&'#,9''&5-(#$9#(+5(4#*"6#T&"4#9G#G&-(@#k+5(44(4#G&-('#3*"#5(#2(*4#B'&"H QFile#QB'$#-&T(#"92+*-#G&-('
&"#$%(#G&-(#'6'$(+@
RESOURCES = myresourcefile.qrc
A%( myresourcefile.qrc#G&-(#&'#*"#idj#G&-(#$%*$#-&'$'#$%(#G&-('#$9#(+5(4#&"#$%(#()(3B$*5-(@
j($S'#&+*H&"(#$%*$#I(#*2(#I2&$&"H#*"#*,,-&3*$&9"#$%*$#T((,'#39"$*3$#4($*&-'@#L92#$%(#39"7("&("3(#9G
A%(#B'(2#&"$(2G*3(#I*'#32(*$(4#&" !"-4&*)5 &%@#A%( .ui#G&-(#&'#9"#$%(#[h#$%*$#*339+,*"&('#$%&'
9B2#B'(2'.#I(#I*"$#$9#(+5(4#$%(#&"$(2"*$&9"*-#4&*-&"H#394('#&"#$%(#()(3B$*5-(@#!G#$%(#G&-(#&'#&"#$%(
datafiles#4&2(3$926#&"#$%(#*,,-&3*$&9"S'#5B&-4#4&2(3$926.#$%(#2('9B23(#G&-(#+&H%$#-99T#-&T(#$%&'
599T@#Z(2(.#I(#I&--#G93B'#9"#$%( 'B53-*''#$%*$#&"%(2&$'#G29+#$%( uicDH("(2*$(4 Ui::ConvertDialog
3-*''.#'$*2$&"H#I&$%#$%(#%(*4(2 }
!"#$%&'#()*+,-(.#I(#%*7(#,(2G92+(4#$%(#G&-(#39"7(2'&9"'#*'6"3%29"9B'-6$%*$#&'.#I(#%*7(#$9-4
QProcess#$9#2B"#$%( convert#,29H2*+#*"4#$9#2($B2"#39"$29-#$9#$%(#*,,-&3*$&9"#&++(4&*$(-6@#A%&'#T((,'
$%(#B'(2#&"$(2G*3(#2(',9"'&7(#I%&-(#$%(#,293(''&"H#933B2'#&"#$%(#5*3TH29B"4@#RB$#&"#'9+(#'&$B*$&9"'
I(#"((4#$%(#()$(2"*-#,293(''#$9#39+,-($(#5(G92(#I(#3*"#H9#*"6#GB2$%(2#&"#9B2#*,,-&3*$&9".#*"4#&"
'B3%#3*'('#I(#"((4 QProcess#$9#9,(2*$(#'6"3%29"9B'-6@
K"(#39++9"#()*+,-(#I%(2(#'6"3%29"9B'#5(%*7&92#&'#4('&2*5-(#&'#G92#*,,-&3*$&9"'#$%*$#'B,,92$#,-*&"
$()$#(4&$&"H#B'&"H#$%(#B'(2S'#,2(G(22(4#$()$#(4&$92@#A%&'#&'#'$2*&H%$G92I*24#$9#&+,-(+("$#B'&"H
QProcess@#L92#()*+,-(.#-($S'#*''B+(#$%*$#I(#%*7(#$%(#,-*&"#$()$#&"#* QTextEdit.#*"4#,297&4(#*"#k4&$
5B$$9"#$%*$#$%(#B'(2#3*"#3-&3T.#39""(3$(4#$9#*" edit()#'-9$@
void ExternalEditor::edit()
{
QTemporaryFile outFile;
if (!outFile.open())
return;
QString fileName = outFile.fileName();
QTextStream out(&outFile);
out << textEdit->toPlainText();
outFile.close();
QProcess::execute(editor, QStringList() << options << fileName);
QFile inFile(fileName);
if (!inFile.open(QIODevice::ReadOnly))
return;
QTextStream in(&inFile);
textEdit->setPlainText(in.readAll());
}
X(#B'( QTemporaryFile#$9#32(*$(#*"#(+,$6#G&-(#I&$%#*#B"&WB(#"*+(@#X(#49"S$#',(3&G6#*"6#*2HB+("$'
$9 QTemporaryFile::open()#'&"3(#&$#39"7("&("$-6#4(G*B-$'#$9#9,("&"H#&"#2(*4fI2&$(#+94(@#X(#I2&$(#$%(
39"$("$'#9G#$%(#$()$#(4&$#$9#$%(#$(+,92*26#G&-(.#*"4#$%("#I(#3-9'(#$%(#G&-(#5(3*B'(#'9+(#$()$#(4&$92'
3*""9$#I92T#9"#*-2(*46#9,("#G&-('@
A%( QProcess::execute()#'$*$&3#GB"3$&9"#2B"'#*"#()$(2"*-#,293(''#*"4#5-93T'#B"$&-#$%(#,293(''#%*'
G&"&'%(4@#A%( editor#*2HB+("$#&'#* QString#%9-4&"H#$%(#"*+(#9G#*"#(4&$92#()(3B$*5-(#CG92#()*+,-(.
/H7&+/E@#A%( options#*2HB+("$#&'#* QStringList#C39"$*&"&"H#9"(#&$(+.#/DG/.#&G#I(#*2(#B'&"H gvimE@
YG$(2#$%(#B'(2#%*'#3-9'(4#$%(#$()$#(4&$92.#$%(#,293(''#G&"&'%('#*"4#$%( execute()#3*--#2($B2"'@#X(
$%("#9,("#$%(#$(+,92*26#G&-(#*"4#2(*4#&$'#39"$("$'#&"$9#$%( QTextEdit@ QTemporaryFile#*B$9+*$&3*--6
db.setHostName("mozart.konkordia.edu");
db.setDatabaseName("musicdb");
Chapter 13. Databases db.setUserName("gbatstone");
db.setPassword("T17aV44");
if (!db.open()) {
• ;3%%!2*$%&'"%#'<7!),$%& QMessageBox::critical(0, QObject::tr("Database Error"),
• :)!1!%*$%&'-"*"'$%'."67=")'>3)5 db.lastError().text());
• 85?=!5!%*$%&'@"1*!)-!*"$='>3)51 return false;
}
return true;
A%( !"67/#+94B-(#,297&4('#*#,-*$G92+D#*"4#4*$*5*'(D&"4(,("4("$#&"$(2G*3(#G92#*33(''&"H#F\j
}
4*$*5*'('@#A%&'#&"$(2G*3(#&'#'B,,92$(4#56#*#'($#9G#3-*''('#$%*$#B'(#\$S'#+94(-f7&(I#*23%&$(3$B2(#$9
,297&4(#4*$*5*'(#&"$(H2*$&9"#I&$%#$%(#B'(2#&"$(2G*3(@#A%&'#3%*,$(2#*''B+('#G*+&-&*2&$6#I&$%#\$S'
+94(-f7&(I#3-*''('.#397(2(4#&" [%*,$(2#1=@
L&2'$.#I(#3*-- QSqlDatabase::addDatabase()#$9#32(*$(#* QSqlDatabase#95Q(3$@#A%(#G&2'$#*2HB+("$#$9
Y#4*$*5*'(#39""(3$&9"#&'#2(,2('("$(4#56#* QSqlDatabase#95Q(3$@#\$#B'('#42&7(2'#$9#39++B"&3*$(#I&$% addDatabase()#',(3&G&('#I%&3%#4*$*5*'(#42&7(2#\$#+B'$#B'(#$9#*33(''#$%(#4*$*5*'(@#!"#$%&'#3*'(.#I(
$%(#7*2&9B'#4*$*5*'(#Y]!'@ A%(#\$#h('T$9,#k4&$&9"#&"3-B4('#$%(#G9--9I&"H#42&7(2' B'(#d6F\j@
b()$.#I(#'($#$%(#4*$*5*'(#%9'$#"*+(.#$%(#4*$*5*'(#"*+(.#$%(#B'(2#"*+(.#*"4#$%(#,*''I924.#*"4
9$!7%$ 95,5:5.% I(#9,("#$%(#39""(3$&9"@#!G open()#G*&-'.#I(#'%9I#*"#(2292#+(''*H(@
\hR8 !Rd#hR8#7(2'&9"#?@1*"4#-*$(2
A6,&3*--6.#I(#I9B-4#3*-- createConnection()#&" main()
\!RYFk R92-*"4#!"$(2R*'(
\dmF\j d6F\j int main(int argc, char *argv[])
{
\K[! K2*3-(#CK2*3-(#[*--#!"$(2G*3(E QApplication app(argc, argv);
if (!createConnection())
\KhR[ KhR[#C&"3-B4('#d&329'9G$#F\j#F(27(2E return 1;
...
\]F\j ]9'$H2(F\j#7(2'&9"'#e@)#*"4#?@) return app.exec();
}
\F\j!Ak F\j&$(#7(2'&9"#:#*"4#-*$(2
\F\j!Ak8 F\j&$(#7(2'&9"#8
K"3(#*#39""(3$&9"#&'#('$*5-&'%(4.#I(#3*"#B'( QSqlQuery#$9#()(3B$(#*"6#F\j#'$*$(+("$#$%*$#$%(
\AhF F65*'(#Y4*,$&7(#F(27(2 B"4(2-6&"H#4*$*5*'(#'B,,92$'@#L92#()*+,-(.#%(2(S'#%9I#$9#()(3B$(#* SELECT#'$*$(+("$
QSqlQuery query;
hB(#$9#-&3("'(#2('$2&3$&9"'.#"9$#*--#9G#$%(#42&7(2'#*2(#,297&4(4#I&$%#$%(#\$#K,("#F9B23(#k4&$&9"@#X%("
query.exec("SELECT title, year FROM cd WHERE year >= 1998");
39"G&HB2&"H#\$.#I(#3*"#3%99'(#5($I(("#&"3-B4&"H#$%(#F\j#42&7(2'#&"'&4(#\$#&$'(-G#*"4#5B&-4&"H#$%(+
*'#,-BH&"'@#\$#&'#'B,,-&(4#I&$%#$%(#F\j&$(#4*$*5*'(.#*#,B5-&3#49+*&"#&"D,293(''#4*$*5*'(@
k*2-&(2#I(#',(3&G&(4#$%(#F\j#WB(26#*'#*"#*2HB+("$#$9 QSqlQuery::exec().#5B$#I(#3*"#*-'9#,*''#&$
4&2(3$-6#$9#$%(#39"'$2B3$92.#I%&3%#()(3B$('#&$#&++(4&*$(-6 9)('#&*)0#$3%($#%*!"#-%23#0%"*%3:#'/!7%./-($7%0("(%*$%3"$/-43%"&("%'*-"(/-%-*-; <=>>%*$%-*-;?("/-;@
'&($('"#$38%A#&/-0%"&#%3'#-#3+%B"%23#3%C-/'*0#%,/"&%"&*3#%0("(.(3#3%"&("%32::*$"%C-/'*0#+%(-0%!*$
"&*3#%"&("%0*-D"+%B"%"$(-3:($#-")7%'*-1#$"3%3"$/-43%"*%"&#%(::$*:$/("#%#-'*0/-48
QSqlQuery query("SELECT title, year FROM cd WHERE year >= 1998");
B"%32::*$"3%<B?%"$(-3('"/*-3%*-%0("(.(3#3%,&#$#%"%($#%(1(/)(.)#8%E*%3"($"%(%"$(-3('"/*-+%,#%'())
transaction()%*-%"&# QSqlDatabase%*.F#'"%"&("%$#:$#3#-"3%"&#%0("(.(3#%'*--#'"/*-8%E*%!/-/3&%"&#
"$(-3('"/*-+%,#%'())%#/"&#$ commit()%*$ rollback()8%G*$%#5(H:)#+%&#$#D3%&*,%,#%,*2)0 )**I%2:%(
X(#3*"#3%(3T#G92#*"#(2292#56#3*--&"H isActive()#9"#$%(#WB(26
!*$#/4-%I#7%(-0%#5#'2"#%(- INSERT%3"("#H#-"%/-3/0#%(%"$(-3('"/*-J
if (!query.isActive())
QMessageBox::warning(this, tr("Database Error"), QSqlDatabase::database().transaction();
query.lastError().text()); QSqlQuery query;
query.exec("SELECT id FROM artist WHERE name = 'Gluecifer'");
if (query.next()) {
int artistId = query.value(0).toInt();
!G#"9#(2292#933B2'.#$%(#WB(26#I&--#5(39+(#/*3$&7(/#*"4#I(#3*"#B'( next()#$9#"*7&H*$(#$%29BH%#$%( query.exec("INSERT INTO cd (id, artistid, title, year) "
2('B-$#'($@ "VALUES (201, " + QString::number(artistId)
+ ", 'Riding the Tiger', 1997)");
h9&"H#*" INSERT#&'#*-+9'$#*'#(*'6#*'#,(2G92+&"H#* SELECT }
QSqlDatabase::database().commit();
!G#I(#"((4#$9#&"'(2$#*#-9$#9G#2(3924'.#92#&G#I(#I*"$#$9#*79&4#39"7(2$&"H#7*-B('#$9#'$2&"H'#C*"4
('3*,&"H#$%(+#3922(3$-6E.#I(#3*"#B'( prepare()#$9#',(3&G6#*#WB(26#$%*$#39"$*&"'#,-*3(%9-4(2'#*"4 QSqlDriver *driver = QSqlDatabase::database().driver();
if (driver->hasFeature(QSqlDriver::Transactions))
$%("#5&"4#$%(#7*-B('#I(#I*"$#$9#&"'(2$@#\$#'B,,92$'#59$%#$%(#K2*3-(D'$6-(#*"4#$%(#KhR[D'$6-(#'6"$*)
...
G92#,-*3(%9-4(2'#G92#*--#4*$*5*'('.#B'&"H#"*$&7(#'B,,92$#I%(2(#&$#&'#*7*&-*5-(#*"4#'&+B-*$&"H#&$
9$%(2I&'(@#Z(2(S'#*"#()*+,-(#$%*$#B'('#$%(#K2*3-(D'$6-(#'6"$*)#I&$%#"*+(4#,-*3(%9-4(2'
<#1#$()%*"&#$%0("(.(3#%!#("2$#3%'(-%.#%"#3"#0%!*$+%/-')20/-4%,&#"&#$%"&#%0("(.(3#%32::*$"3%A?LA3
QSqlQuery query; MA/-($7%?($4#%L.F#'"3N+%C-/'*0#+%(-0%:$#:($#0%62#$/#38
query.prepare("INSERT INTO cd (id, artistid, title, year) "
"VALUES (:id, :artistid, :title, :year)"); >-%"&#%#5(H:)#3%3*%!($+%,#%&(1#%(332H#0%"&("%"&#%(::)/'("/*-%/3%23/-4%(%3/-4)#%0("(.(3#%'*--#'"/*-8
query.bindValue(":id", 203); >!%,#%,(-"%"*%'$#("#%H2)"/:)#%'*--#'"/*-3+%,#%'(-%:(33%(%-(H#%(3%3#'*-0%($42H#-"%"*
query.bindValue(":artistid", 102); addDatabase()8%G*$%#5(H:)#J
query.bindValue(":title", "Living in America");
query.bindValue(":year", 2002);
query.exec();
QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL", "OTHER");
db.setHostName("saturn.mcmanamy.edu");
db.setDatabaseName("starsdb");
Z(2(S'#$%(#'*+(#()*+,-(#B'&"H#KhR[D'$6-(#,9'&$&9"*-#,-*3(%9-4(2' db.setUserName("hilbert");
db.setPassword("ixtapa7");
QSqlQuery query;
query.prepare("INSERT INTO cd (id, artistid, title, year) " K#%'(-%"&#-%$#"$/#1#%(%:*/-"#$%"*%"&# QSqlDatabase%*.F#'"%.7%:(33/-4%"&#%-(H#%"*
"VALUES (?, ?, ?, ?)");
QSqlDatabase::database()J
query.addBindValue(203);
QSqlDatabase db = QSqlDatabase::database("OTHER");
E*%/-3#$"%(%$#'*$0%/-"*%(%0("(.(3#%"(.)#+%,#%23#%"&#%3(H#%(::$*('&%(3%,# ,*2)0%/-3#$"/-4%/-"*%(-7
",*;0/H#-3/*-()%H*0#)J%G/$3"+%,#%'()) insertRow()%"*%'$#("#%(%-#,%#H:"7%$*,%M$#'*$0N+%(-0%"&#-%,#
E*%#5#'2"#%62#$/#3%23/-4%"&#%*"&#$%'*--#'"/*-+%,#%:(33%"&# QSqlDatabase%*.F#'"%"*%"&# QSqlQuery 23# setData()%"*%3#"%"&#%1()2#3%*!%#('&%'*)2H-%M!/#)0N8
'*-3"$2'"*$J
QSqlTableModel model;
QSqlQuery query(db); model.setTable("cd");
query.exec("SELECT id FROM artist WHERE name = 'Mando Diao'"); int row = 0;
model.insertRows(row, 1);
model.setData(model.index(row, 0), 113);
model.setData(model.index(row, 1), "Shanghai My Heart");
O2)"/:)#%'*--#'"/*-3%($#%23#!2)%/!%,#%,(-"%"*%:#$!*$H%H*$#%"&(-%*-#%"$(-3('"/*-%("%(%"/H#+%3/-'#
model.setData(model.index(row, 2), 224);
#('&%'*--#'"/*-%'(-%*-)7%&(-0)#%(%3/-4)#%('"/1#%"$(-3('"/*-8%K&#-%,#%23#%H2)"/:)#%0("(.(3#
model.setData(model.index(row, 3), 2003);
'*--#'"/*-3+%,#%'(-%3"/))%&(1#%*-#%2--(H#0%'*--#'"/*-+%(-0 QSqlQuery%,/))%23#%"&("%'*--#'"/*-%/! model.submitAll();
-*-#%/3%3:#';/!/#08
model.select();
E&# QSqlRecord::value()%!2-'"/*-%"(I#3%#/"&#$%(%!/#)0%-(H#%*$%(%!/#)0%/-0#58%K&#-%*:#$("/-4%*-%)($4# if (model.rowCount() == 1) {
0("(%3#"3+%/"%/3%$#'*HH#-0#0%"&("%!/#)03%($#%3:#'/!/#0%.7%"&#/$%/-0#5#38%G*$%#5(H:)#J model.setData(model.index(0, 1), "Melody A.M.");
model.setData(model.index(0, 3),
model.data(model.index(0, 3)).toInt() + 1);
int titleIndex = model.record().indexOf("title"); model.submitAll();
int yearIndex = model.record().indexOf("year"); }
for (int i = 0; i < model.rowCount(); ++i) {
QSqlRecord record = model.record(i);
QString title = record.value(titleIndex).toString(); S#)#"/-4%(%$#'*$0%/3%3/H/)($%"*%2:0("/-4J
int year = record.value(yearIndex).toInt();
cerr << qPrintable(title) << ": " << year << endl;
}
model.setTable("cd");
model.setFilter("id = 125");
model.select();
if (model.rowCount() == 1) {
model.removeRows(0, 1);
model.submitAll();
}
E&# removeRows()%'())%"(I#3%"&#%$*,%-2H.#$%*!%"&#%!/$3"%$#'*$0%"*%0#)#"#%(-0%"&#%-2H.#$%*!%$#'*$03
"*%0#)#"#8%E&#%-#5"%#5(H:)#%0#)#"#3%())%"&#%$#'*$03%"&("%H("'&%"&#%!/)"#$J
model.setTable("cd");
model.setFilter("year < 1990");
model.select();
if (model.rowCount() > 0) {
model.removeRows(0, model.rowCount());
model.submitAll();
}
!"#$%&'()5)&*+%&,-&,.//%01!.2&344/!031!.267&138/%7
E&#%'*-3"$2'"*$%/3%1#$7%3/H/)($%"*%*-#%"&("%,*2)0%.#%23#0%"*%'$#("#%(%!*$H%.(3#0%*-%(%-*-;<B?
H*0#)J
E&# ArtistForm%'*-3"$2'"*$%"(I#3%"&#%-(H#%*!%"&#%($"/3"%"&("%3&*2)0%.#%3#)#'"#0%,&#-%"&#%0/()*4
class ArtistForm : public QDialog :*:3%2:8%K#%/"#$("#%"&$*24&%"&# artist%"(.)#D3%$#'*$03%(-0%3#)#'"%"&#%3:#'/!/#0%($"/3"8%E&#%$#3"%*!%"&#
{ '*-3"$2'"*$D3%'*0#%/3%23#0%"*%'$#("#%(-0%'*--#'"%"&#%.2""*-3%(-0%"*%)(7%*2"%"&#%'&/)0%,/04#"38
Q_OBJECT
public:
ArtistForm(const QString &name, QWidget *parent = 0); void ArtistForm::addArtist()
private slots: {
void addArtist(); int row = model->rowCount();
void deleteArtist(); model->insertRow(row);
void beforeInsertArtist(QSqlRecord &record); QModelIndex index = model->index(row, Artist_Name);
private: tableView->setCurrentIndex(index);
enum { tableView->edit(index);
Artist_Id = 0, }
Artist_Name = 1,
Artist_Country = 2
};
QSqlTableModel *model; E*%(00%(%-#,%($"/3"+%,#%/-3#$"%(%3/-4)#%.)(-I%$*,%("%"&#%.*""*H%*!%"&# QTable-View8%R*,%"&#%23#$%'(-
QTableView *tableView; #-"#$%(%-#,%($"/3"D3%-(H#%(-0%'*2-"$78%>!%"&#%23#$%'*-!/$H3%"&#%/-3#$"/*-%.7%:$#33/-4%U-"#$+%"&#
QPushButton *addButton; beforeInsert()%3/4-()%/3%#H/""#0%(-0%"&#-%"&#%-#,%$#'*$0%/3%/-3#$"#0%/-"*%"&#%0("(.(3#8
QPushButton *deleteButton;
QPushButton *closeButton;
}; void ArtistForm::beforeInsertArtist(QSqlRecord &record)
{
record.setValue("id", generateId("artist"));
}
>-%"&#%'*-3"$2'"*$+%,#%'*--#'"#0%"&#%H*0#)D3 beforeInsert()%3/4-()%"*%"&/3%3)*"8%K#%($#%:(33#0%(
Implementing MasterDetail Forms
-*-;'*-3"%$#!#$#-'#%"*%"&#%$#'*$0%F23"%.#!*$#%/"%/3%/-3#$"#0%/-"*%"&#%0("(.(3#8% "%"&/3%:*/-"+%,#
:*:2)("#%/"3 id%!/#)08 K#%,/))%-*,%$#1/#,%"&#%H(/-%!*$H%,&/'&%"(I#3%(%H(3"#$0#"(/)%(::$*('&8%E&#%H(3"#$%1/#,%/3%(%)/3"%*!
=S38%E&#%0#"(/)%1/#,%/3%(%)/3"%*!%"$('I3%!*$%"&#%'2$$#-"%=S8%E&/3%!*$H%/3%"&#%H(/-%,/-0*,%*!%"&#%=S
</-'#%,#%,/))%-##0 generateId()%(%!#,%"/H#3+%,#%0#!/-#%/"%/-)/-#%/-%(%&#(0#$%!/)#%(-0%/-')20#%/"%#('& =*))#'"/*-%(::)/'("/*-%(3%3&*,-%/- G/42$#%@T8@%M:8%TXXN8
"/H#%,#%-##0%/"8%Q#$#D3%(%62/'I%M(-0 /-#!!/'/#-"N%,(7%*!%/H:)#H#-"/-4%/"J
class MainForm : public QWidget
{
inline int generateId(const QString &table)
Q_OBJECT
{
public:
QSqlQuery query;
MainForm();
query.exec("SELECT MAX(id) FROM " + table);
private slots:
int id = 0;
void addCd();
if (query.next())
void deleteCd();
id = query.value(0).toInt() + 1;
void addTrack();
return id;
void deleteTrack();
}
void editArtists();
void currentCdChanged(const QModelIndex &index);
void beforeInsertCd(QSqlRecord &record);
E&# generateId()%!2-'"/*-%'(-%*-)7%.#%42($(-"##0%"*%,*$I%'*$$#'")7%/!%/"%/3%#5#'2"#0%,/"&/-%"&# void beforeInsertTrack(QSqlRecord &record);
'*-"#5"%*!%"&#%3(H#%"$(-3('"/*-%(3%"&#%'*$$#3:*-0/-4 INSERT%3"("#H#-"8%<*H#%0("(.(3#3%32::*$" void refreshTrackViewHeader();
(2"*;4#-#$("#0%!/#)03+%(-0%/"%/3%232())7%!($%.#""#$%"*%23#%"&#%0("(.(3#;3:#'/!/'%32::*$"%!*$%"&/3 private:
*:#$("/*-8 enum {
Cd_Id = 0,
Cd_Title = 1,
E&#%)(3"%:*33/./)/"7%"&# ArtistForm%0/()*4%*!!#$3%/3%0#)#"/*-8%W("&#$%"&(-%:#$!*$H/-4%'(3'(0/-4 Cd_ArtistId = 2,
0#)#"/*-3%M'*1#$#0%3&*$")7N+%,#%&(1#%'&*3#-%"*%*-)7%:#$H/"%0#)#"/*-3%*!%($"/3"3%,&*%&(1#%-*%=S3%/- Cd_Year = 3
"&#%'*))#'"/*-8 };
enum {
Track_Id = 0,
void ArtistForm::deleteArtist() Track_Title = 1,
{ Track_Duration = 2,
tableView->setFocus(); Track_CdId = 3
QModelIndex index = tableView->currentIndex(); };
if (!index.isValid()) QSqlRelationalTableModel *cdModel;
return; QSqlTableModel *trackModel;
QSqlRecord record = model->record(index.row()); QTableView *cdTableView;
QSqlTableModel cdModel; QTableView *trackTableView;
cdModel.setTable("cd"); QPushButton *addCdButton;
cdModel.setFilter("artistid = " + record.value("id").toString()); QPushButton *deleteCdButton;
cdModel.select(); QPushButton *addTrackButton;
if (cdModel.rowCount() == 0) { QPushButton *deleteTrackButton;
model->removeRow(tableView->currentIndex().row()); QPushButton *editArtistsButton;
} else { QPushButton *quitButton;
QMessageBox::information(this, };
tr("Delete Artist"),
tr("Cannot delete %1 because there are CDs associated "
"with this artist in the collection.")
K#%23#%( QSqlRelationalTableModel%!*$%"&# cd%"(.)#%$("&#$%"&(-%(%:)(/- QSqlTableModel%.#'(23#%,#
.arg(record.value("name").toString()));
} -##0%"*%&(-0)#%!*$#/4-%I#738%K#%,/))%-*,%$#1/#,%#('&%!2-'"/*-%/-%"2$-+%.#4/--/-4%,/"&%"&#
} '*-3"$2'"*$+%,&/'&%,#%,/))%)**I%("%/-%3#'"/*-3%.#'(23# /"%/3%62/"#%)*-48
MainForm::MainForm()
>!%"&#$#%/3%(%$#'*$0%3#)#'"#0+%,#%'&#'I%"* 3##%/!%"&#%($"/3"%&(3%(-7%=S3+%(-0%/!%"%0*-D"+%,#%0#)#"# {
"&#H%/HH#0/("#)78%L"&#$,/3#+%,#%:*:%2:%(%H#33(4#%.*5%#5:)(/-/-4%,&7%"&#%0#)#"/*-%,(3%-*" cdModel = new QSqlRelationalTableModel(this);
:#$!*$H#08%<"$/'")7%3:#(I/-4+%,#%3&*2)0%&(1#%23#0%(%"$(-3('"/*-+%.#'(23#%(3%"&#%'*0#%3"(-03+%/"%/3 cdModel->setTable("cd");
:*33/.)#%!*$%(%=S%"*%&(1#%/"3%($"/3"%3#"%"*%"&#%*-#%,#%($#%0#)#"/-4%/-;.#",##-%"&# cdModel.select() cdModel->setRelation(Cd_ArtistId,
(-0 model->removeRow()%'())38 K#%,/))%3&*,%(%"$(-3('"/*-%/-%"&#%-#5"%3#'"/*-8 QSqlRelation("artist", "id", "name"));
cdModel->setSort(Cd_Title, Qt::AscendingOrder);
cdModel->setHeaderData(Cd_Title, Qt::Horizontal, tr("Title"));
cdModel->setHeaderData(Cd_ArtistId, Qt::Horizontal, tr("Artist")); ...
cdModel->setHeaderData(Cd_Year, Qt::Horizontal, tr("Year")); }
cdModel->select();
E&#%!/$3"%'*--#'"/*-%/3%2-232()%3/-'#%/-3"#(0%*!%'*--#'"/-4%(%,/04#"+%,#%'*--#'"%"*%(%3#)#'"/*-
E&#%'*-3"$2'"*$%.#4/-3%.7%3#""/-4%2:%"&# QSqlRelationalTableModel%"&("%&(-0)#3%"&# cd%"(.)#8%E&# H*0#)8%E&# QItemSelectionModel%')(33 /3%23#0%"*%I##:%"$('I%*!%3#)#'"/*-3%/-%1/#,38%A7%.#/-4
setRelation()%'())%"#))3%"&#%H*0#)%"&("%/"3 artistid%!/#)0%M,&*3#%!/#)0%/-0#5%/3%&#)0%.7 Cd_ArtistIdN '*--#'"#0%"*%"&#%"(.)#%1/#,D3%3#)#'"/*-%H*0#)+%*2$ currentCdChanged()%3)*"%,/))%.#%'())#0%,&#-#1#$
&*)03%"&# id%!*$#/4-%I#7%!$*H%"&# artist%"(.)#+%(-0%"&("%/"%3&*2)0 0/3:)(7%"&#%'*$$#3:*-0/-4 name "&#%23#$%-(1/4("#3%!$*H%*-#%$#'*$0%"*%(-*"&#$8
!/#)0D3%'*-"#-"3%/-3"#(0%*!%>S38%>!%"&#%23#$%'&**3#3%"*%#0/"%"&/3%!/#)0%M!*$%#5(H:)#+%.7%:$#33/-4%GYN+
"&#%H*0#)%,/))%(2"*H("/'())7%:$#3#-"%(%'*H.*.*5%,/"&%"&#%-(H#3%*!%())%"&#%($"/3"3+%(-0%/!%"&#%23#$
'&**3#3%(%0/!!#$#-"%($"/3"+%,/))%2:0("#%"&# cd%"(.)#8 void MainForm::currentCdChanged(const QModelIndex &index)
{
if (index.isValid()) {
cdTableView = new QTableView; QSqlRecord record = cdModel->record(index.row());
cdTableView->setModel(cdModel); int id = record.value("id").toInt();
cdTableView->setItemDelegate(new QSqlRelationalDelegate(this)); trackModel->setFilter(QString("cdid = %1").arg(id));
cdTableView->setSelectionMode(QAbstractItemView::SingleSelection); } else {
cdTableView->setSelectionBehavior(QAbstractItemView::SelectRows); trackModel->setFilter("cdid = -1");
cdTableView->setColumnHidden(Cd_Id, true); }
cdTableView->resizeColumnsToContents(); trackModel->select();
refreshTrackViewHeader();
}
<#""/-4%2:%"&#%1/#,%!*$%"&# cd%"(.)#%/3%(4(/-%3/H/)($%"*%,&("%,#%&(1#%()$#(07%3##-8%E&#%*-)7
3/4-/!/'(-"%0/!!#$#-'#%/3%"&("%/-3"#(0%*!%23/-4%"&#%1/#,D3%0#!(2)"%0#)#4("#%,#%23#
E&/3%3)*"%/3%'())#0%,&#-#1#$%"&#%'2$$#-"%=S%'&(-4#38%E&/3%*''2$3%,&#-%"&#%23#$%-(1/4("#3%"*%(-*"&#$
QSqlRelationalDelegate8%>"%/3%"&/3%0#)#4("#%"&("%0*#3%"&#%!*$#/4-%I#7%&(-0)/-48
=S%M.7%')/'I/-4%*$%.7%23/-4%"&#%C:%(-0%S*,-%I#73N8%>!%"&#%=S%/3%/-1()/0%M!*$%#5(H:)#+%/!%"&#$#%($#%-*
=S3%*$%(%-#,%*-#%/3%.#/-4%/-3#$"#0+%*$%"&#%'2$$#-"%*-#%&(3%F23"%.##-%0#)#"#0N+%,#%3#"%"&# TRack
trackModel = new QSqlTableModel(this); "(.)#D3 cdid%"* ;@%M(-%/-1()/0%>S%"&("%,#%I-*,%,/))%H("'&%-*%$#'*$03N8
trackModel->setTable("track");
trackModel->setHeaderData(Track_Title, Qt::Horizontal, tr("Title")); E&#-+%&(1/-4%3#"%"&#%!/)"#$+%,#%3#)#'"%"&#%H("'&/-4%"$('I%$#'*$038%E&# refresh-TrackViewHeader()
trackModel->setHeaderData(Track_Duration, Qt::Horizontal, !2-'"/*-%,/))%.#%#5:)(/-#0%/-%(%H*H#-"8
tr("Duration"));
trackTableView = new QTableView;
trackTableView->setModel(trackModel); void MainForm::addCd()
trackTableView->setItemDelegate( {
new TrackDelegate(Track_Duration, this)); int row = 0;
trackTableView->setSelectionMode( if (cdTableView->currentIndex().isValid())
QAbstractItemView::SingleSelection); row = cdTableView->currentIndex().row();
trackTableView->setSelectionBehavior(QAbstractItemView::SelectRows); cdModel->insertRow(row);
cdModel->setData(cdModel->index(row, Cd_Year),
QDate::currentDate().year());
G*$%"$('I3+%,#%($#%*-)7%4*/-4%"*%3&*,%"&#/$%-(H#3%(-0%02$("/*-3+%3*%( QSqlTableModel%/3%32!!/'/#-"8 QModelIndex index = cdModel->index(row, Cd_Title);
cdTableView->setCurrentIndex(index);
ME&# id%(-0 cdid%!/#)0D3%($#%&/00#-%/-%"&# currentCd-Changed()%3)*"%3&*,-%)("#$8N%E&#%*-)7%-*"(.)#
cdTableView->edit(index);
(3:#'"%*!%"&/3%:($"%*!%"&#%'*0#%/3%"&("%,#%23#%"&# trackDelegate%0#1#)*:#0%/- =&(:"#$%@X%"*%3&*, }
"$('I%"/H#3%(3%Z !"#$%&'&%()"*&Z%(-0%"*%())*,%"&#H%"*%.#%#0/"#0%23/-4%(%32/"(.)# QTimeEdit8
E&#%'$#("/*-+%'*--#'"/-4+%(-0%)(7/-4%*2"%*!%"&#%1/#,3%(-0%.2""*-3%&*)03%-*%32$:$/3#3+%3*%"&#%*-)7
K&#-%"&#%23#$%')/'I3%"&#% 00%=S%.2""*-+%(%-#,%.)(-I%$*,%/3%/-3#$"#0%/-%"&# cdTableView%(-0%,#
*"&#$%:($"%*!%"&#%'*-3"$2'"*$%"&("%,#%,/))%3&*,%($#%(%!#,%-*-;*.1/*23%'*--#'"/*-38
#-"#$%#0/"%H*0#8%K#%()3*%3#"%(%0#!(2)"%1()2#%!*$%"&# year%!/#)08% "%"&/3%:*/-"+%"&#%23#$%'(-%#0/"%"&#
$#'*$0+%!/))/-4%/-%"&#%.)(-I%!/#)03%(-0%3#)#'"/-4%(-%($"/3"%!$*H%"&#%($"/3"%'*H.*.*5%"&("%/3
... (2"*H("/'())7%:$*1/0#0%.7%"&# QSqlRelationalTableModel%.#'(23#%*!%"&# setRelation()%'())+%(-0%#0/"
connect(cdTableView->selectionModel(), "&#%7#($%/!%"&#%0#!(2)"%,(3%-*"%(::$*:$/("#8%>!%"&#%23#$%'*-!/$H3%"&#%/-3#$"/*-%.7%:$#33/-4%U-"#$+%"&#
SIGNAL(currentRowChanged(const QModelIndex &, $#'*$0%/3%/-3#$"#08%E&#%23#$%'(-%'(-'#)%.7%:$#33/-4%U3'8
const QModelIndex &)),
this, SLOT(currentCdChanged(const QModelIndex &)));
connect(cdModel, SIGNAL(beforeInsert(QSqlRecord &)), void MainForm::beforeInsertCd(QSqlRecord &record)
this, SLOT(beforeInsertCd(QSqlRecord &))); {
connect(trackModel, SIGNAL(beforeInsert(QSqlRecord &)), record.setValue("id", generateId("cd"));
this, SLOT(beforeInsertTrack(QSqlRecord &))); }
connect(trackModel, SIGNAL(rowsInserted(const QModelIndex &, int,
int)),
this, SLOT(refreshTrackViewHeader()));
E&/3%3)*"%/3%'())#0%,&#-%"&# cdModel%#H/"3%/"3 beforeInsert()%3/4-()8%K#%23#%/"%"*%:*:2)("#%"&# id%!/#)0
F23"%(3%,#%0/0%!*$%/-3#$"/-4%-#,%($"/3"3+%(-0%"&#%3(H#%'(1#("%(::)/#3J%>"%3&*2)0%.#%0*-#%,/"&/-%"&#
3'*:#%*!%(%"$(-3('"/*-+%(-0%/0#())7%"&#%0("(.(3#;3:#'/!/'%H#(-3%*!%'$#("/-4%>S3%M!*$%#5(H:)#+%(2"*;
4#-#$("#0%>S3N%3&*2)0%.#%23#0%/-3"#(08 E&/3%,*$I3%/-%"&#%3(H#%,(7%(3 addCd()+%,/"&%(%-#,%.)(-I%$*,%.#/-4%/-3#$"#0%/-"*%"&#%1/#,8
K#%,/))%3"($"%,/"&%(-%#5(H:)#%"&("%3&*,3%&*,%"*%$#"$/#1#%(%3/-4)#%!/)#%23/-4 get()8%E&#%#5(H:)#%/3%(
'*-3*)#%(::)/'("/*-%'())#0 ftpget%"&("%0*,-)*(03%"&#%$#H*"#%!/)#%3:#'/!/#0%*-%"&#%'*HH(-0%)/-#8%?#"D3
.#4/-%,/"&%"&# main()%!2-'"/*-J
E&#%GE9%'*HH(-03%($#%62#2#0%(-0%#5#'2"#0%/-%B"D3%#1#-"%)**:8%E&#%'*H:)#"/*-%*!%())%"&#
FtpGet%&(3%(%:$/1("#%3)*"+ ftpDone()+%"&("%/3%'())#0%,&#-%"&#%!/)#%"$(-3!#$%/3%'*H:)#"#0+%(-0%( done()
'*HH(-03%/3%/-0/'("#0%.7 QFtpD3 done(bool)%3/4-()+%,&/'&%,#%'*--#'"#0%"* ftpDone(bool)%/-%"&#
3/4-()%"&("%/"%#H/"3%,&#-%"&#%!/)#%&(3%.##-%0*,-)*(0#08%E&#%')(33%()3*%&(3%",*%:$/1("#%1($/(.)#3J%E&#
'*-3"$2'"*$8
ftp%1($/(.)#+%*!%"7:# QFtp+%#-'(:32)("#3%"&#%'*--#'"/*-%"*%(-%GE9%3#$1#$+%(-0 "&# file%1($/(.)#%"&("
/3%23#0%!*$%,$/"/-4%"&#%0*,-)*(0#0%!/)#%"*%0/3I8
void FtpGet::ftpDone(bool error)
{
FtpGet::FtpGet(QObject *parent) if (error) {
: QObject(parent) cerr << "Error: " << qPrintable(ftp.errorString()) << endl;
{ } else {
connect(&ftp, SIGNAL(done(bool)), this, SLOT(ftpDone(bool))); cerr << "File downloaded as " << qPrintable(file.fileName())
} << endl;
}
file.close();
>-%"&#%'*-3"$2'"*$+%,#%'*--#'"%"&# QFtp::done(bool)%3/4-()%"*%*2$ ftpDone(bool)%:$/1("#%3)*"8 QFtp emit done();
#H/"3 done(bool)%,&#-%/"%&(3%!/-/3�%:$*'#33/-4%())%$#62#3"38%E&# bool%:($(H#"#$%/-0/'("#3%,&#"&#$ }
(-%#$$*$%*''2$$#0%*$%-*"8
L-'#%"&#%GE9%'*HH(-03%&(1#%())%.##-%#5#'2"#0+%,#%')*3#%"&#%!/)#%(-0%#H/"%*2$%*,- done()%3/4-()8%>"
bool FtpGet::getFile(const QUrl &url) H(7%(::#($%3"$(-4#%"&("%,#%')*3#%"&#%!/)#%&#$#+%$("&#$%"&(-%(!"#$%"&# ftp.close()%'())%("%"&#%#-0%*!
{ "&# getFile()%!2-'"/*-+%.2"%$#H#H.#$%"&("%"&#%GE9%'*HH(-03%($#%#5#'2"#0%(37-'&$*-*23)7%(-0
if (!url.isValid()) { H(7%,#))%.#%/-%:$*4$#33%(!"#$%"&# getFile()%!2-'"/*-%&(3%$#"2$-#08%L-)7%,&#-%"&# QFtp%*.F#'"D3
cerr << "Error: Invalid URL" << endl;
done()%3/4-()%/3%#H/""#0%0*%,#%I-*,%"&("%"&#%0*,-)*(0%/3%!/-/3�%(-0%"&("%/"%/3%3(!#%"*%')*3#%"&#%!/)#8
return false;
}
if (url.scheme() != "ftp") { QFtp%:$*1/0#3%3#1#$()%GE9%'*HH(-03+%/-')20/-4 connectToHost()+ login()+ close()+ list()+ cd()+
cerr << "Error: URL must start with 'ftp:'" << endl; get()+ put()+ remove()+ mkdir()+ rmdir()+%(-0 rename()8% ))%*!%"#%!2-'"/*-3%3')#%(-%GE9
return false; '*HH(-0%(-0%$#"2$-%(-%>S%-2H.#$%"&("%/0#-"/!/#3%"&#%'*HH(-08%>"%/3%()3*%:*33/.)#%"* '*-"$*)%"&#
} "$(-3!#$%H*0#%M"&#%0#!(2)"%/3%:(33/1#N%(-0%"&#%"$(-3!#$%"7:#%M"&#%0#!(2)"%/3%./-($7N8
if (url.path().isEmpty()) {
cerr << "Error: URL has no path" << endl;
$./"$($7%GE9%'*HH(-03%'(-%.#%#5#'2"#0%23/-4 rawCommand()8%G*$%#5(H:)#+%&#$#D3%&*,%"*%#5#'2"#%(
return false;
} SITE CHMOD%'*HH(-0J
QString localFileName = QFileInfo(url.path()).fileName();
if (localFileName.isEmpty())
localFileName = "ftpget.out"; ftp.rawCommand("SITE CHMOD 755 fortune");
file.setFileName(localFileName);
if (!file.open(QIODevice::WriteOnly)) {
cerr << "Error: Cannot open " << qPrintable(file.fileName())
QFtp%#H/"3%"&# commandStarted(int)%3/4-()%,&#-%/"%3"($"3%#5#'2"/-4%(%'*HH(-0+%(-0%/"%#H/"3%"&#
commandFinished(int, bool)%3/4-()%,&#-%"&#%'*HH(-0%/3%!/-/3%E&# int%:($(H#"#$%/3%"&#%>S QFtp ftp;
-2H.#$%"&("%/0#-"/!/#3%"&#%'*HH(-08%>!%,#%($#%/-"#$#3"#0%/-%"&#%!("#%*!%/-0/1/02()%'*HH(-03+%,# QList<QFile *> openedFiles;
'(-%3"*$#%"&#%>S%-2H.#$3%,&#-%,#%3')#%"&#%'*HH(-038%^##:/-4%"$('I%*!%"&#%>S%-2H.#$3%())*,3 QString currentDir;
23%"*%:$*1/0#%0#"(/)#0%!##0.('I%"*%"&#%23#$8%G*$%#5(H:)#J QString currentLocalDir;
QStringList pendingDirs;
};
bool FtpGet::getFile(const QUrl &url)
{
... E&#%3"($"/-4%0/$#'"*$7%/3%3:#'/!/#0%(3%( QUrl%(-0%/3%3#"%23/-4%"&# getdirectory()%!2-'"/*-8
connectId = ftp.connectToHost(url.host(), url.port(21));
loginId = ftp.login();
getId = ftp.get(url.path(), &file); Spider::Spider(QObject *parent)
closeId = ftp.close(); : QObject(parent)
return true; {
} connect(&ftp, SIGNAL(done(bool)), this, SLOT(ftpDone(bool)));
void FtpGet::ftpCommandStarted(int id) connect(&ftp, SIGNAL(listInfo(const QUrlInfo &)),
{ this, SLOT(ftpListInfo(const QUrlInfo &)));
if (id == connectId) { }
cerr << "Connecting..." << endl;
} else if (id == loginId) {
cerr << "Logging in..." << endl;
... >-%"&#%'*-3"$2'"*$+%,#%#3"(.)/3&%",*%3/4-()3)*"%'*--#'"/*-38%E&# listInfo(const QUrlInfo &)%3/4-()%/3
} #H/""#0%.7 QFtp%,&#-%,#%$#62#3"%(%0/$#'"*$7%)/3"/-4%M/- getdirectory()N%!*$%#('&%!/)#%"&("%/"%$#"$/#1#38
E&/3%3/4-()%/3%'*--#'"#0%"*%(%3)*"%'())#0 ftpListInfo()+%,&/'&%0*,-)*(03%"&#%!/)#%(33*'/("#0%,/"&%"&#
CW?%/"%/3%4/1#-8
-*"&#$%,(7%*!%:$*1/0/-4%!##0.('I%/3%"*%'*--#'"%"* QFtpD3 stateChanged()%3/4-()+%,&/'&%/3%#H/""#0
,&#-#1#$%"&#%'*--#'"/*-%#-"#$3%(%-#,%3"("#%MQFtp::Connecting+ QFtp::Connected+ QFtp::LoggedIn+
bool Spider::getDirectory(const QUrl &url)
#"'8N8
{
if (!url.isValid()) {
>-%H*3"%(::)/'("/*-3+%,#%($#%*-)7%/-"#$#3"#0%/-%"&#%!("#%*!%"&#%3#62#-'#%*!%'*HH(-03%(3%(%,&*)# cerr << "Error: Invalid URL" << endl;
$("&#$%"&(-%/-%:($"/'2)($%'*HH(-038%>-%32'&%'(3#3+%,#%'(-%3/H:)7%'*--#'"%"*%"&# done(bool)%3/4-()+ return false;
,&/'&%/3%#H/""#0%,&#-#1#$%"&#%'*HH(-0%62#2#%.#'*H#3%#H:"78 }
if (url.scheme() != "ftp") {
K&#-%(-%#$$*$%*''2$3+ QFtp%(2"*H("/'())7%')#($3%"&#%'*HH(-0%62#2#8%E&/3%H#(-3%"&("%/!%"&# cerr << "Error: URL must start with 'ftp:'" << endl;
'*--#'"/*-%*$%"&#%)*4/-%!(/)3+%"&#%'*HH(-03%"&("%!*))*,%/-%"&#%62#2#%($#%-#1#$%#5#'2"#08%>!%,# return false;
}
3')#%-#,%'*HH(-03%(!"#$%"&#%#$$*$%&(3%*''2$$#0%23/-4%"&#%3(H# QFtp%*.F#'"+%"#%'*HH(-03
ftp.connectToHost(url.host(), url.port(21));
,/))%.#%62#2#0%(-0%#5#'2"#08 ftp.login();
QString path = url.path();
>-%"&#%(::)/'("/*-D3 .pro%!/)#+%,#%-##0%"&#%!*))*,/-4%)/-#%"*%)/-I%(4(/-3"%"&# +$0%$1)23%)/.$($7J if (path.isEmpty())
path = "/";
pendingDirs.append(path);
QT += network processNextDirectory();
return true;
}
K#%,/))%-*,%$#1/#,%(%H*$#%(01(-'#0%#5(H:)#8%E&# spider '*HH(-0;)/-#%:$*4$(H%0*,-)*(03%())%"&#
!/)#3%)*'("#0%/-%(-%GE9%0/$#'"*$7+%$#'2$3/1#)7%0*,-)*(0/-4%!$*H%())%"&#%0/$#'"*$7D3%32.0/$#'"*$/#38%E&#
-#",*$I%)*4/'%/3%)*'("#0%/-%"&# Spider%')(33J K&#-%"&# getdirectory()%!2-'"/*-%/3%'())#0+%/"%.#4/-3%.7%0*/-4%3*H#%3(-/"7%'&#'I3+%(-0%/!%())%/3%,#))+
(""#H:"3%"*%#3"(.)/3&%(-%GE9%'*--#'"/*-8%>"%I##:3%"$('I%*!%"&#%:("&3%"&("%/"%H23"%:$*'#33%(-0%'())3
processNextDirectory()%"*%3"($"%0*,-)*(0/-4%"&#%$**"%0/$#'"*$78
class Spider : public QObject
{
Q_OBJECT void Spider::processNextDirectory()
public: {
Spider(QObject *parent = 0); if (!pendingDirs.isEmpty()) {
bool getDirectory(const QUrl &url); currentDir = pendingDirs.takeFirst();
signals: currentLocalDir = "downloads/" + currentDir;
void done(); QDir(".").mkpath(currentLocalDir);
private slots: ftp.cd(currentDir);
void ftpDone(bool error); ftp.list();
void ftpListInfo(const QUrlInfo &urlInfo); } else {
private: emit done();
void processNextDirectory(); }
} -#5"%0/$#'"*$7%/-%"&#%)/3"]%*"&#$,/3#+%"&#%0*,-)*(0/-4%3"*:3%(-0 done()%/3%#H/""#08
>!%"&#$#%($#%-*%#$$*$3+%"&#%3#62#-'#%*!%GE9%'*HH(-03%(-0%3/4-()3%/3%(3%!*))*,3J
E&# processNextDirectory()%!2-'"/*-%"(I#3%"&#%!/$3"%$#H*"#%0/$#'"*$7%*2"%*!%"&# pendingDirs%)/3"%(-0
'$#("#3%(%'*$$#3:*-0/-4%0/$#'"*$7%/-%"&#%)*'()%!/)#%373"#H8%>"%"&#-%"#))3%"&# QFtp%*.F#'"%"*%'&(-4#
0/$#'"*$7%/-"*%"&#%"(I#-%0/$#'"*$7%(-0%"*%)/3"%/"3%!/)#38%G*$%#1#$7%!/)#%"&(" list()%:$*'#33#3+%/"%#H/"3%( connectToHost(host, port)
listInfo()%3/4-()%"&("%'(23#3%"&# ftpListInfo()%3)*"%"*%.#%'())#08 login()
cd(directory_1)
list()
>!%"&#$#%($#%-*%H*$#%0/$#'"*$/#3%"*%:$*'#33+%"&#%!2-'"/*-%#H/"3%"&# done()%3/4-()%"*%/-0/'("#%"&("%"&# emit listInfo(file_1_1)
0*,-)*(0/-4%/3%'*H:)#"#8 get(file_1_1)
emit listInfo(file_1_2)
get(file_1_2)
void Spider::ftpListInfo(const QUrlInfo &urlInfo) ...
{ emit done()
if (urlInfo.isFile()) { ...
if (urlInfo.isReadable()) { cd(directory_N)
QFile *file = new QFile(currentLocalDir + "/" list()
+ urlInfo.name()); emit listInfo(file_N_1)
if (!file->open(QIODevice::WriteOnly)) { get(file_N_1)
cerr << "Warning: Cannot open file " emit listInfo(file_N_2)
<< qPrintable( get(file_N_2)
QDir::convertSeparators(file->fileName())) ...
<< endl; emit done()
return;
}
ftp.get(urlInfo.name(), file);
openedFiles.append(file); >!%(%!/)#%/3%/-%!('"%(%0/$#'"*$7+%/"%/3%(00#0%"*%"&# pendingDirs%)/3"+%(-0%,&#-%"&#%)(3"%!/)#%*!%"&#%'2$$#-"
} list()%'*HH(-0%&(3%.##-%0*,-)*(0#0+%(%-#, cd()%'*HH(-0%/3%/332#0+%!*))*,#0%.7%(%-#, list()
} else if (urlInfo.isDir() && !urlInfo.isSymLink()) { '*HH(-0%,/"&%"&#%-#5"%:#-0/-4%0/$#'"*$7+%(-0%"&#%,&*)#%:$*'#33%.#4/-3%(4(/-%,/"&%"&#%-#,
pendingDirs.append(currentDir + "/" + urlInfo.name()); 0/$#'"*$78%E&/3%/3%$#:#("#0+%,/"&%-#,%!/)#3%.#/-4%0*,-)*(0#0+%(-0%-#,%0/$#'"*$/#3%(00#0%"*%"&#
} pendingDirs%)/3"+%2-"/)%#1#$7%!/)#%&(3%.##-%0*,-)*(0#0%!$*H%#1#$7%0/$#'"*$7+%("%,&/'&%:*/-"%"&#
} pendingDirs%)/3"%,/))%!/-())7%.#%#H:"78
>!%(%-#",*$I%#$$*$%*''2$3%,&/)#%0*,-)*(0/-4%"&#%!/!"&%*!+%3(7+%",#-"7%!/)#3%/-%(%0/$#'"*$7+%"&#
E&# ftpListInfo()%3)*"D3 urlInfo%:($(H#"#$%:$*1/0#3%0#"(/)#0%/-!*$H("/*-%(.*2"%(%$#H*"#%!/)#8%>!%"&# $#H(/-/-4%!/)#3%,/))%-*"%.#%0*,-)*(0#08%>!%,#%,(-"#0%"*%0*,-)*(0%(3%H(-7%!/)#3%(3%:*33/.)#+%*-#
!/)#%/3%(%-*$H()%!/)#%M-*"%(%0/$#'"*$7N%(-0%/3%$#(0(.)#+%,#%'()) get()%"*%0*,-)*(0%/"8%E&# QFile%*.F#'" 3*)2"/*-%,*2)0%.#%"*%3')#%"&# GET%*:#$("/*-3%*-#%("%(%"/H#%(-0%"*%,(/"%!*$%"&# done(bool)%3/4-()
23#0%!*$%0*,-)*(0/-4%/3%())*'("#0%23/-4 new%(-0%(%:*/-"#$%"*%/"%/3%3"*$#0%/-%"&# openedFiles%)/3"8 .#!*$#%3')/-4%(%-#, GET%*:#$("/*-8%>- listInfo()+%,#%,*2)0%3/H:)7%(::#-0%"&#%!/)#%-(H#%"*%(
QStringList+%/-3"#(0%*!%'())/-4 get()%$/4&"%(,(7+%(-0%/- done(bool)%,#%,*2)0%'()) get()%*-%"&#%-#5"
>!%"&# QUrlInfo%&*)03%"&#%0#"(/)3%*!%(%$#H*"#%0/$#'"*$7%"&("%/3%-*"%(%37H.*)/'%)/-I+%,#%(00%"&/3 !/)#%"*%0*,-)*(0%/-%"&# QStringList8%E&#%3#62#-'#%*!%#5#'2"/*-%,*2)0%"&#-%)**I%)/I#%"&/3J
0/$#'"*$7%"*%"&# pendingDirs%)/3"8%K#%3I/:%37H.*)/'%)/-I3%.#'(23#%"%'(-%#(3/)7%)#(0%"*%/-!/-/"#
$#'2$3/*-8
connectToHost(host, port)
login()
void Spider::ftpDone(bool error) cd(directory_1)
{ list()
if (error) { ...
cerr << "Error: " << qPrintable(ftp.errorString()) << endl; cd(directory_N)
} else { list()
cout << "Downloaded " << qPrintable(currentDir) << " to " emit listInfo(file_1_1)
<< qPrintable(QDir::convertSeparators( emit listInfo(file_1_2)
QDir(currentLocalDir).canonicalPath())); ...
} emit listInfo(file_N_1)
qDeleteAll(openedFiles); emit listInfo(file_N_2)
openedFiles.clear(); ...
processNextDirectory(); emit done()
} get(file_1_1)
emit done()
get(file_1_2)
emit done()
E&# ftpDone()%3)*"%/3%'())#0%,&#-%())%"&#%GE9%'*HH(-03%&(1#%!/-/3�%*$%/!%(-%#$$*$%*''2$$#08%K# ...
0#)#"#%"&# QFile%*.F#'"3%"* :$#1#-"%H#H*$7%)#(I3%(-0%()3*%"*%')*3#%#('&%!/)#8%G/-())7+%,#%'()) get(file_N_1)
processNextDirectory()8%>!%"&#$#%($#%(-7%0/$#'"*$/#3%)#!"+%"&#%,&*)#%:$*'#33%.#4/-3%(4(/-%,/"&%"&# emit done()
get(file_N_2)
emit done() !2-'"/*-()/"7%(-0%/H:)#H#-"("/*-+%3*%,#%,/))%-*"%3&*,%"&#%&#(0#$%!/)#8
...
HttpGet::HttpGet(QObject *parent)
-*"&#$%3*)2"/*-%,*2)0%.#%"*%23#%*-# QFtp%*.F#'"%:#$%!/)#8%E&/3%,*2)0%#-(.)#%23%"*%0*,-)*(0%"&#%!/)#3 : QObject(parent)
/-%:($())#)+%"&$*24&%3#:($("#%GE9%'*--#'"/*-38 {
connect(&http, SIGNAL(done(bool)), this, SLOT(httpDone(bool)));
}
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv); >-%"&#%'*-3"$2'"*$+%,#%'*--#'"%"&# QHttp%*.F#'"D3 done(bool)%3/4-()%"*%"&#%:$/1("# httpDone(bool)
QStringList args = app.arguments(); 3)*"8
if (args.count() != 2) {
cerr << "Usage: spider url" << endl
<< "Example:" << endl bool HttpGet::getFile(const QUrl &url)
<< " spider ftp://ftp.trolltech.com/freebies/leafnode" {
<< endl; if (!url.isValid()) {
return 1; cerr << "Error: Invalid URL" << endl;
} return false;
Spider spider; }
if (!spider.getDirectory(QUrl(args[1]))) if (url.scheme() != "http") {
return 1; cerr << "Error: URL must start with 'http:'" << endl;
QObject::connect(&spider, SIGNAL(done()), &app, SLOT(quit())); return false;
return app.exec(); }
} if (url.path().isEmpty()) {
cerr << "Error: URL has no path" << endl;
return false;
E&# main()%!2-'"/*-%'*H:)#"#3%"&#%:$*4$(H8%>!%"&#%23#$%0*#3 -*"%3:#'/!7%(%CW?%*-%"&#%'*HH(-0 }
)/-#+%,#%4/1#%(-%#$$*$%H#33(4#%(-0%"#$H/-("#%"&#%:$*4$(H8 QString localFileName = QFileInfo(url.path()).fileName();
if (localFileName.isEmpty())
localFileName = "httpget.out";
>-%.*"&%GE9%#5(H:)#3+%"&#%0("(%$#"$/#1#0%23/-4 get()%,(3%,$/""#-%"*%( QFile8%E&/3%-##0%-*"%.#%"&# file.setFileName(localFileName);
'(3#8%>!%,#%,(-"#0%"&#%0("(%/-%H#H*$7+%,#%'*2)0%23#%( QBuffer+%"&# QIODevice%32.')(33%"&("%,$(:3%( if (!file.open(QIODevice::WriteOnly)) {
QByteArray8%G*$%#5(H:)#J cerr << "Error: Cannot open " << qPrintable(file.fileName())
<< " for writing: " << qPrintable(file.errorString())
<< endl;
QBuffer *buffer = new QBuffer; return false;
buffer->open(QIODevice::WriteOnly); }
ftp.get(urlInfo.name(), buffer); http.setHost(url.host(), url.port(80));
http.get(url.path(), &file);
http.close();
return true;
K#%'*2)0%()3*%*H/"%"&#%>\L%0#1/'#%($42H#-"%"* get()%*$%:(33%(%-2))%:*/-"#$8%E&# QFtp%')(33%"&#- }
#H/"3%( readyRead()%3/4-()%#1#$7%"/H#%-#,%0("(%/3%(1(/)(.)#+%(-0%"&#%0("(%'(-%.#%$#(0%23/-4 read()
*$ readAll()8
E&# getFile()%!2-'"/*-%:#$!*$H3%"&#%3(H#%I/-0%*!%#$$*$%'&#'I3%(3%"&# FtpGet::getFile()%3&*,-
#($)/#$%(-0%23#3%"&#%3(H#%(::$*('&%"*%4/1/-4%"&#%!/)#%(%)*'()%-(H#8%K&#-%$#"$/#1/-4%!$*H%,#.%3/"#3+
Writing HTTP Clients -*%)*4/-%/3%-#'#33($7+%3*%,#%3/H:)7%3#"%"&#%&*3"%(-0%:*$"%M23/-4%"&#%0#!(2)"%QEE9 :*$"%_X%/!%-*-#%/3
3:#'/!/#0%/-%"&#%CW?N%(-0%0*,-)*(0%"&#%0("(%/-"*%"&#%!/)#+%3/-'#%"&#%3#'*-0%($42H#-"%"* QHttp::get()
3:#'/!/#3%"&#%*2":2"%>\L%0#1/'#8
E&# QHttp%')(33%/H:)#H#-"3%"&#%')/#-"%3/0#%*!%"&#%QEE9%:$*"*'*)%/-%B"8%>"%:$*1/0#3%1($/*23%!2-'"/*-3
"*%:#$!*$H%"&#%H*3"%'*HH*-%QEE9%*:#$("/*-3+%/-')20/-4 get()%(-0 post()+%(-0%:$*1/0#3%(%H#(-3%*!
E&#%QEE9%$#62#3"3%($#%62#2#0%(-0%#5#'2"#0%(37-'&$*-*23)7%/-%B"D3%#1#-"%)**:8%E&#%'*H:)#"/*-%*!
3#-0/-4%($./"$($7%QEE9%$#62#3"38%>!%7*2%&(1#%$#(0%"&#%:$#1/*23%3#'"/*-%(.*2" QFtp+%7*2%,/))%!/-0%"&(" "&#%$#62#3"3%/3%/-0/'("#0%.7 QHttpD3 done(bool)%3/4-()+%,&/'&%,#%'*--#'"#0%"* httpDone(bool)%/-%"&#
"&#$#%($#%H(-7%3/H/)($/"/#3%.#",##- QFtp%(-0 QHttp8 '*-3"$2'"*$8
QHttp%#H/"3%"&# requestStarted(int)%3/4-()%,&#-%/"%3"($"3%#5#'2"/-4%(%$#62#3"+%(-0%/"%#H/"3%"&#
requestFinished(int, bool)%3/4-()%,&#-%"&#%$#62#3"%&(3%!/-/3%E&# int%:($(H#"#$%/3%(-%>S
-2H.#$%"&("%/0#-"/!/#3%(%$#62#3"8%>!%,#%($#%/-"#$#3"#0%/-%"&#%!("#%*!%/-0/1/02()%$#62#3"3+%,#%'(-%3"*$#
"&#%>S%-2H.#$3%,&#-%,#%3')#%"&#%$#62#3"38%^##:/-4%"$('I%*!%"&#%>S%-2H.#$3%())*,3%23%"*
:$*1/0#%0#"(/)#0%!##0.('I%"*%"&#%23#$8
>-%H*3"%(::)/'("/*-3+%,#%*-)7%,(-"%"*%I-*,%,&#"&#$%"&#%#-"/$#%3#62#-'#%*! $#62#3"3%'*H:)#"#0
tableWidget->verticalHeader()->hide();
tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
connect(searchButton, SIGNAL(clicked()),
this, SLOT(connectToServer()));
connect(stopButton, SIGNAL(clicked()), this, SLOT(stopSearch()));
connect(&tcpSocket, SIGNAL(connected()), this, SLOT(sendRequest()));
connect(&tcpSocket, SIGNAL(disconnected()),
this, SLOT(connectionClosedByServer()));
connect(&tcpSocket, SIGNAL(readyRead()),
this, SLOT(updateTableWidget()));
connect(&tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)),
this, SLOT(error()));
}
>-%"&#%'*-3"$2'"*$+%,#%/-/"/()/V#%"&#%0("#%(-0%"/H#%#0/"*$3%.(3#0%*-%"&#%'2$$#-"%0("#%(-0%"/H#8%K#
()3*%&/0#%"&#%:$*4$#33%.($+%.#'(23#%,#%*-)7%,(-"%"*%3&*,%/"%,&#-%(%'*--#'"/*-%/3%('"/1#8%>- +$
7%&!8"%2+%"&#%:$*4$#33%.($D3 minimum%(-0 maximum%:$*:#$"/#3%,#$#%.*"&%3#"%"*%X8%E&/3%"#))3%"&#
QProgressBar%"*%.#&(1#%(3%(%.237%/-0/'("*$%/-3"#(0%*!%(3%(%3"(-0($0%:#$'#-"(4#;.(3#0%:$*4$#33%.($8
G/-())7+%,#%3#"%"&# nextBlockSize%1($/(.)#%"*%X8%E&/3%1($/(.)#%3"*$#3%"&#%)#-4"&%*!%"&#%-#5"%.)*'I
$#'#/1#0%!$*H%"&#%3#$1#$8%K#%&(1#%'&*3#-%"*%23#%"&#%1()2#%*!%X%"*%H#(-%"&("%,#%0*-D"%7#"%I-*,%"&#
E&# TRipPlanner%')(33%/-&#$/"3%!$*H Ui::TripPlanner%M,&/'&%/3%4#-#$("#0%.7 uic%!$*H 3/V#%*!%"&#%-#5"%.)*'I8
tripplanner.uiN%/-%(00/"/*-%"* QDialog8%E&# tcpSocket%H#H.#$%1($/(.)#%#-'(:32)("#3%"&#%E=9
'*--#'"/*-8%E&# nextBlockSize%1($/(.)#%/3%23#0%,&#-%:($3/-4%"&#%.)*'I3%$#'#/1#0%!$*H%"&#%3#$1#$8
void TripPlanner::sendRequest()
{
TripPlanner::TripPlanner(QWidget *parent) QByteArray block;
: QDialog(parent) QDataStream out(&block, QIODevice::WriteOnly);
{ out.setVersion(QDataStream::Qt_4_1);
setupUi(this); out << quint16(0) << quint8('S') << fromComboBox->currentText()
QDateTime dateTime = QDateTime::currentDateTime(); << toComboBox->currentText() << dateEdit->date()
dateEdit->setDate(dateTime.date()); << timeEdit->time();
timeEdit->setTime(QTime(dateTime.time().hour(), 0)); if (departureRadioButton->isChecked()) {
progressBar->hide(); out << quint8('D');
progressBar->setSizePolicy(QSizePolicy::Preferred, } else {
QSizePolicy::Ignored);
out << quint8('A'); quint16 duration;
} quint8 changes;
out.device()->seek(0); QString trainType;
out << quint16(block.size() - sizeof(quint16)); in >> date >> departureTime >> duration >> changes >> trainType;
tcpSocket.write(block); arrivalTime = departureTime.addSecs(duration * 60);
statusLabel->setText(tr("Sending request...")); tableWidget->setRowCount(row + 1);
} QStringList fields;
fields << date.toString(Qt::LocalDate)
<< departureTime.toString(tr("hh:mm"))
<< arrivalTime.toString(tr("hh:mm"))
E&# sendRequest()%3)*"%/3%#5#'2"#0%,&#-%"&# QTcpSocket%*.F#'"%#H/"3%"&# connected()%3/4-()+ << tr("%1 hr %2 min").arg(duration / 60)
/-0/'("/-4%"&("%(%'*--#'"/*-%&(3%.##-%#3"(.)/3%E&#%3)*"D3%"(3I%/3%"*%4#-#$("#%(%$#62#3"%"*%"&# .arg(duration % 60)
3#$1#$+%,/"&%())%"&#%/-!*$H("/*-%#-"#$#0%.7%"&#%23#$8 << QString::number(changes)
<< trainType;
E&#%$#62#3"%/3%(%./-($7%.)*'I%,/"&%"&#%!*))*,/-4%!*$H("J for (int i = 0; i < fields.count(); ++i)
tableWidget->setItem(row, i,
new QTableWidgetItem(fields[i]));
quint16 A)*'I%3/V#%/-%.7"#3%M#5')20/-4%"&/3%!/#)0N nextBlockSize = 0;
}
quint8 W#62#3"%"7:#%M(),(73%D<DN }
QString S#:($"2$#%'/"7
QString $$/1()%'/"7 E&# updateTableWidget()%3)*"%/3%'*--#'"#0%"*%"&# QTcpSocketD3 readyRead()%3/4-()+%,&/'&%/3%#H/""#0
,&#-#1#$%"&# QTcpSocket%&(3%$#'#/1#0%-#,%0("(%!$*H%"&#%3#$1#$8%E&#%3#$1#$%3#-03%23%(%)/3"%*!
QDate S("#%*!%"$(1#) :*33/.)#%"$(/-%"$/:3%"&("%H("'&%"&#%23#$D3%'$/"#$/(8%U('&%H("'&/-4%"$/:%/3%3#-"%(3%(%3/-4)#%.)*'I+%(-0
#('&%.)*'I%3"($"3%,/"&%(%3/V#8%E&# forever%)**:%/3%-#'#33($7%.#'(23#%,#%0*-D"%-#'#33($/)7%4#"%*-#
QTime ::$*5/H("#%"/H#%*!%"$(1#) .)*'I%*!%0("(%!$*H%"&#%3#$1#$%("%(%"/H#8cde%K#%H/4&"%&(1#%$#'#/1#0%(-%#-"/$#%.)*'I+%*$%F23"%:($"%*!%(
quint8 .)*'I+%*$%*-#%(-0%(%&()!%.)*'I3+%*$%#1#-%())%*!%"&#%.)*'I3%("%*-'#8
E/H#%/3%!*$%0#:($"2$#%MDSDN%*$%($$/1()%MD DN
[*]
The forever keyword is provided by Qt. It simply expands to for (;;).
K#%/-/"/())7%,$/"#%X%(3%"&#%.)*'I%3/V#+%!*))*,#0%.7%"&#%$#3"%*!%"&#%0("(8%E&#-%,#%'()) seek(0)%*-%"&#
>\L%0#1/'#%M( QBuffer%'$#("#0%.7 QDataStream%.#&/-0%"&#%3'#-#3N%"*%H*1#%.('I%"*%"&#%.#4/--/-4%*!
"&#%.7"#%($$(7+%(-0%*1#$,$/"#%"&#%/-/"/()%X%,/"&%"&#%3/V#%*!%"&#%.)*'ID3%0("(8%E&#%3/V#%/3%'()'2)("#0%.7
"(I/-4%"&#%.)*'ID3%3/V#%(-0%32."$('"/-4 sizeof(quint16)%M"&("%/3+%YN%"*%#5')20#%"&#%3/V#%!/#)0%!$*H%"&#
.7"#%'*2-"8% !"#$%"&("+%,#%'()) write()%*-%"&# QTcpSocket "*%3#-0%"&#%.)*'I%"*%"&#%3#$1#$8
<*%&*,%0*#3%"&# forever )**:%,*$If%>!%"&# nextBlockSize%1($/(.)#%/3%X+%"&/3%H#(-3%"&("%,#%&(1#%-*"
$#(0%"&#%3/V#%*!%"&#%-#5"%.)*'I8%K#%"$7%"*%$#(0%/"%M(332H/-4%"&#$#%($#%("%)#(3"%Y%.7"#3%(1(/)(.)#%!*$
void TripPlanner::updateTableWidget() $#(0/-4N8%E&#%3#$1#$%23#3%(%3/V#%1()2#%*! 0xFFFF%"*%3/4-/!7%"&("%"&#$#%/3%-*%H*$#%0("(%"*%$#'#/1#+%3*%/!
{ ,#%$#(0%"&/3%1()2#+%,#%I-*,%"&("%,#%&(1#%$#('�%"&#%#-08
QDataStream in(&tcpSocket);
in.setVersion(QDataStream::Qt_4_1); >!%"&#%.)*'I%3/V#%/3%-*" 0xFFFF+%,#%"$7%"*%$#(0%/-%"&#%-#5"%.)*'I8%G/$3"+%,#%'&#'I%"*%3##%/!%"&#$#%($#
forever {
.)*'I%3/V#%.7"#3%(1(/)(.)#%"*%$#(08%>!%"&#$#%($#%-*"+%,#%3"*:%"&#$#%!*$%-*,8%E&# readyRead()%3/4-()
int row = tableWidget->rowCount();
if (nextBlockSize == 0) { ,/))%.#%#H/""#0%(4(/-%,&#-%H*$#%0("(%/3%(1(/)(.)#+%(-0%,#%,/))%"$7%(4(/-%"&#-8
if (tcpSocket.bytesAvailable() < sizeof(quint16))
break; L-'#%,#%($#%32$#%"&("%(-%#-"/$#%.)*'I%&(3%($$/1#0+%,#%'(-%3(!#)7%23#%"&# >>%*:#$("*$%*-%"&#
in >> nextBlockSize; QDataStream%"*%#5"$('"%"&#%/-!*$H("/*-%$#)("#0%"*%(%"$/:+%(-0%,#%'$#("# QTableWidgetItem3%,/"&%"&("
} /-!*$H("/*-8% %.)*'I%$#'#/1#0%!$*H%"&#%3#$1#$%&(3%"&#%!*))*,/-4%!*$H("J
if (nextBlockSize == 0xFFFF) {
closeConnection();
statusLabel->setText(tr("Found %1 trip(s)").arg(row)); quint16 A)*'I%3/V#%/-%.7"#3%M#5')20/-4%"&/3%!/#)0N
break;
} QDate S#:($"2$#%0("#
if (tcpSocket.bytesAvailable() < nextBlockSize)
break; QTime S#:($"2$#%"/H#
QDate date;
QTime departureTime;
QTime arrivalTime;
quint8 ,#%,*2)0%#5:#'"J
R2H.#$%*!%'&(-4#3
QString E$(/-%"7:#
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
"%"&#%#-0+%,#%$#3#"%"&# nextBlockSize%1($/(.)#%"*%X%"*%/-0/'("#%"&("%"&#%-#5"%.)*'ID3%3/V#%/3%2-I-*,- TripPlanner tripPlanner;
(-0%-##03%"*%.#%$#(08 tripPlanner.show();
return app.exec();
}
void TripPlanner::closeConnection()
{
tcpSocket.close(); R*,%)#"D3%/H:)#H#-"%"&#%3#$1#$8%E&#%3#$1#$%'*-3/3"3%*!%",*%')(33#3J TRipServer%(-0 ClientSocket8
searchButton->setEnabled(true); E&# TRipServer%')(33%/-&#$/"3 QTcpServer+%(%')(33%"&("%())*,3%23%"*%(''#:"%/-'*H/-4%E=9%'*--#'"/*-38
stopButton->setEnabled(false); ClientSocket%$#/H:)#H#-"3 QTcpSocket%(-0%&(-0)#3%(%3/-4)#%'*--#'"/*-8% "%(-7%*-#%"/H#+%"&#$#%($#
progressBar->hide(); (3%H(-7 Client-Socket%*.F#'"3%/-%H#H*$7%(3%"&#$#%($#%')/#-"3%.#/-4%3#$1#08
}
E&# QUdpSocket%')(33%'(-%.#%23#0%"*%3#-0%(-0%$#'#/1#%CS9%0("(4$(H38%CS9%/3%(-%2-$#)/(.)#+
0("(4$(H;*$/#-"#0%:$*"*'*)8%<*H#%(::)/'("/*-;)#1#)%:$*"*'*)3%23#%CS9%.#'(23#%/"%/3%H*$#%)/4&",#/4&" void WeatherBalloon::sendDatagram()
"&(-%E=98%K/"&%CS9+%0("(%/3%3#-"%(3%:('I#"3%M0("(4$(H3N%!$*H%*-#%&*3"%"*%(-*"&#$8%E&#$#%/3%-* {
'*-'#:"%*!%'*--#'"/*-+%(-0%/!%(%CS9%:('I#"%0*#3-D"%4#"%0#)/1#$#0%32''#33!2))7+%-*%#$$*$%/3%$#:*$"#0%"* QByteArray datagram;
"&#%3#-0#$8 QDataStream out(&datagram, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_1);
out << QDateTime::currentDateTime() << temperature() << humidity()
!"#$%&':)()&*+%&?%31+%$&<131!.2&344/!031!.2 << altitude();
udpSocket.writeDatagram(datagram, QHostAddress::LocalHost, 5824);
}
>- sendDatagram()+%,#%4#-#$("#%(-0%3#-0%(%0("(4$(H%'*-"(/-/-4%"&#%'2$$#-"%0("#+%"/H#+
"#H:#$("2$#+%&2H/0/"7+%(-0%()"/"20#J
QDateTime S("#%(-0%"/H#%*!%H#(32$#H#-"
double E#H:#$("2$#%M/-%g=N
double Q2H/0/"7%M/-%hN
double )"/"20#%M/-%H#"#$3N
K#%,/))%3##%&*,%"*%23#%CS9%!$*H%(%B"%(::)/'("/*- "&$*24&%"&#%K#("&#$%A())**-%(-0%K#("&#$%<"("/*-
#5(H:)#8%E&#%K#("&#$%A())**-%(::)/'("/*-%H/H/'3%(%,#("&#$%.())**-%"&("%3#-03%(%CS9%0("(4$(H
E&#%0("(4$(H%/3%3#-"%23/-4 QUdpSocket::writeDatagram()8%E&#%3#'*-0%(-0%"&/$0%($42H#-"3%"*
M:$#32H(.)7%23/-4%(%,/$#)#33%'*--#'"/*-N%'*-"(/-/-4%"&#%'2$$#-"%("H*3:&#$/'%'*-0/"/*-3%#1#$7%Y
3#'*-038%E&#%K#("&#$ <"("/*-%(::)/'("/*-%$#'#/1#3%"#%0("(4$(H3%(-0%0/3:)(73%"&#H%*-%3'$##-8 writeDatagram()%($#%"&#%>9%(00$#33%(-0%"&#%:*$"%-2H.#$%*!%"&#%:##$%M"&#%K#("&#$%<"("/*-N8%G*$%"&/3
K#%,/))%3"($"%.7%$#1/#,/-4%"&#%'*0#%!*$%"&#%K#("&#$%A())**-8 #5(H:)#+%,#%(332H#%"&("%"&#%K#("&#$%<"("/*-%/3%$2--/-4%*-%"&#%3(H#%H('&/-#%(3%"&#%K#("&#$
A())**-+%3*%,#%23#%(-%>9%(00$#33%*!%@Yb8X8X8@%M QHostAddress::LocalHostN+%(%3:#'/()%(00$#33%"&("
0#3/4-("#3%"&#%)*'()%&*3"8
class WeatherBalloon : public QPushButton
{ C-)/I#%"&# QAbstractSocket%32.')(33#3+ QUdpSocket%0*#3%-*"%(''#:"%&*3"%-(H#3+%*-)7%&*3"%(00$#33#38
Q_OBJECT >!%,#%,(-"#0%"*%$#3*)1#%(%&*3"%-(H#%"*%/"3%>9%(00$#33%&#$#+%,#%&(1#%",*%'&*/'#3J%>!%,#%($#%:$#:($#0
public: "*%.)*'I%,&/)#%"&#%)**I2:%"(I#3%:)('#+%,#%'(-%23#%"&#%3"("/' QHostInfo::fromName()%!2-'"/*-8
WeatherBalloon(QWidget *parent = 0); L"&#$,/3#+%,#%'(-%23#%"&#%3"("/' QHostInfo::lookupHost()%!2-'"/*-+%,&/'&%$#"2$-3%/HH#0/("#)7%(-0
double temperature() const; '())3%"&#%3)*"%/"%/3%:(33#0%,/"&%( QHostInfo%*.F#'"%'*-"(/-/-4%"&#%'*$$#3:*-0/-4%(00$#33#3%,&#-%"&#
double humidity() const;
)**I2:%/3%'*H:)#"#8
double altitude() const;
private slots:
void sendDatagram();
private: int main(int argc, char *argv[])
QUdpSocket udpSocket; {
QTimer timer; QApplication app(argc, argv);
}; WeatherBalloon balloon;
balloon.show();
return app.exec();
}
E&# WeatherBalloon%')(33%/-&#$/"3%!$*H QPushButton8%>"%23#3%/"3 QUdpSocket%:$/1("# 1($/(.)#%!*$
'*HH2-/'("/-4%,/"&%"&#%K#("&#$%<"("/*-8
E&# main()%!2-'"/*-%3/H:)7%'$#("#3%( WeatherBalloon%*.F#'"+%,&/'&%3#$1#3%.*"&%(3%(%CS9%:##$%(-0%(3
( QPushButton%*-%3'$##-8%A7%')/'I/-4%"&# QPushButton+%"&#%23#$%'(-%62/"%"&#%(::)/'("/*-8
WeatherBalloon::WeatherBalloon(QWidget *parent)
: QPushButton(tr("Quit"), parent)
{ R*,%)#"D3%$#1/#,%"&#%3*2$'#%'*0#%!*$%"&#%K#("&#$%<"("/*-%')/#-"8
connect(this, SIGNAL(clicked()), this, SLOT(close()));
/-'*H/-4%0("(4$(H3%(-0%)#"3%23%(''#33%"&#H%*-#%("%(%"/H#8%R*$H())7+%"&#$#%3&*2)0%.#%*-)7%*-#
class WeatherStation : public QDialog 0("(4$(H+%.2"%,#%'(-D"%#5')20#%"&#%:*33/./)/"7%"&("%"&#%3#-0#$%,*2)0%3#-0%(%!#,%0("(4$(H3%/-%(%$*,
{ .#!*$#%"&# readyRead()%3/4-()%/3%#H/""#08%>-%"&("%'(3#+%,#%'(-%/4-*$#%())%"&#%0("(4$(H3%#5'#:"%"&#
Q_OBJECT )(3"%*-#+%3/-'#%"&#%#($)/#$%*-#3%'*-"(/-%*.3*)#"#%("H*3:&#$/'%'*-0/"/*-38
public:
WeatherStation(QWidget *parent = 0);
private slots: E&# pendingDatagramSize()%!2-'"/*-%$#"2$-3%"&#%3/V#%*!%"&#%!/$3"%:#-0/-4%0("(4$(H8%G$*H%"&#
void processPendingDatagrams(); (::)/'("/*-D3%:*/-"%*!%1/#,+%0("(4$(H3%($#%(),(73%3#-"%(-0%$#'#/1#0%(3%(%3/-4)#%2-/"%*!%0("(8%E&/3
private: H#(-3%"&("%/!%(-7%.7"#3%($#%(1(/)(.)#+%(-%#-"/$#%0("(4$(H%'(-%.#%$#(08%E&# readDatagram()%'())
QUdpSocket udpSocket; '*:/#3%"&#%'*-"#-"3%*!%"&#%!/$3"%:#-0/-4%0("(4$(H%/-"*%"&#%3:#'/!/#0 char *%.2!!#$%M"$2-'("/-4%0("(%/!
QLabel *dateLabel; "&#%.2!!#$%/3%"**%3H())N%(-0%(01(-'#3%"*%"&#%-#5"%:#-0/-4%0("(4$(H8%L-'#%,#%&(1#%$#(0%())%"&#
QLabel *timeLabel; 0("(4$(H3+%,#%0#'*H:*3#%"&#%)(3"%*-#%M"&#%*-#%,/"&%"&#%H*3"%$#'#-"%("H*3:&#$/'%H#(32$#H#-"3N
... /-"*%/"3%:($"3%(-0%:*:2)("#%"&# QLineEdit3%,/"&%"&#%-#,%0("(8
QLineEdit *altitudeLineEdit;
};
int main(int argc, char *argv[])
{
E&# WeatherStation%')(33%/-&#$/"3%!$*H QDialog8%>"%)/3"#-3%"*%(%:($"/'2)($%CS9%:*$"+%:($3#3%(-7 QApplication app(argc, argv);
/-'*H/-4%0("(4$(H3%M!$*H%"&#%K#("&#$%A())**-N+%(-0%0/3:)(73%"&#/$%'*-"#-"3%/-%!/1#%$#(0;*-)7 WeatherStation station;
QLineEdit38%E&#%*-)7%:$/1("#%1($/(.)#%*!%/-"#$#3"%&#$#%/3 udpSocket%*!%"7:# QUdpSocket+%,&/'&%,#%,/)) station.show();
23#%"*%$#'#/1#%0("(4$(H38 return app.exec();
}
WeatherStation::WeatherStation(QWidget *parent)
: QDialog(parent) G/-())7+%/- main()+%,#%'$#("#%(-0%3&*,%"&# WeatherStation8
{
udpSocket.bind(5824); K#%&(1#%-*,%!/-/3�%*2$%CS9%3#-0#$ (-0%$#'#/1#$8%E&#%(::)/'("/*-3%($#%(3%3/H:)#%(3%:*33/.)#+%,/"&
connect(&udpSocket, SIGNAL(readyRead()),
"&#%K#("&#$%A())**-%3#-0/-4%0("(4$(H3%(-0%"&#%K#("&#$%<"("/*-%$#'#/1/-4%"&#H8%>-%H*3"%$#();,*$)0
this, SLOT(processPendingDatagrams()));
(::)/'("/*-3+%.*"&%(::)/'("/*-3%,*2)0%-##0%"*%.*"&%$#(0%(-0%,$/"#%*-%"&#/$%3*'I#"8%E&#
...
} QUdpSocket::writeDatagram()%!2-'"/*-3%'(-%.#%:(33#0%(%&*3"%(00$#33%(-0%:*$"%-2H.#$+%3*%"&#
QUdpSocket%'(-%$#(0%!$*H%"&#%&*3"%(-0%:*$"%/"%/3%.*2-0%"*%,/"& bind()+%(-0%,$/"#%"*%3*H#%*"&#$%&*3"
(-0%:*$"8
>-%"&#%'*-3"$2'"*$+%,#%3"($"%.7%./-0/-4%"&# QUdpSocket%"*%"&#%:*$"%"&("%"&#%,#("&#$%.())**-%/3
"$(-3H/""/-4%"*8%</-'#%,#%&(1#%-*"%3:#'/!/#0%(%&*3"%(00$#33+%"&#%3*'I#"%,/))%(''#:"%0("(4$(H3%3#-"%"*
(-7%>9%(00$#33%"&("%.#)*-43%"*%"&#%H('&/-#%"&#%K#("&#$%<"("/*-%/3%$2--/-4%*-8%E&#-+%,#%'*--#'"%"&#
3*'I#"D3 readyRead()%3/4-()%"*%"&#%:$/1("# processPendingDatagrams()%"&("%#5"$('"3%(-0%0/3:)(73%"&#
0("(8
void WeatherStation::processPendingDatagrams()
{
QByteArray datagram;
do {
datagram.resize(udpSocket.pendingDatagramSize());
udpSocket.readDatagram(datagram.data(), datagram.size());
} while (udpSocket.hasPendingDatagrams());
QDateTime dateTime;
double temperature;
double humidity;
double altitude;
QDataStream in(&datagram, QIODevice::ReadOnly);
in.setVersion(QDataStream::Qt_4_1);
in >> dateTime >> temperature >> humidity >> altitude;
dateLineEdit->setText(dateTime.date().toString());
timeLineEdit->setText(dateTime.time().toString());
temperatureLineEdit->setText(tr("%1 ° C").arg(temperature));
humidityLineEdit->setText(tr("%1%").arg(humidity));
altitudeLineEdit->setText(tr("%1 m").arg(altitude));
}
• 7,46"$%&;<=&>"#?&/1; QXmlContentHandler%/3%F23"%*-#%*!%H(-7%&(-0)#$%')(33#3%"&("%'(-%.#%23#0%/-%'*-F2-'"/*-%,/"&
• 7,46"$%&;<=&>"#?&9@< QXmlSimpleReader8%E&#%*"&#$3%($# QXmlEntityResolver+ QXmlDTDHandler+ QXmlErrorHandler+
• !"#"$%&;<= QXmlDeclHandler+%(-0 QXmlLexicalHandler8%E#%')(33#3%*-)7%0#')($#%:2$#%1/$"2()%!2-'"/*-3%(-0%4/1#
/-!*$H("/*-%(.*2"%0/!!#$#-"%I/-03%*!%:($3/-4%#1#-"38%G*$%H*3"%(::)/'("/*-3+ QXmlContentHandler%(-0
iO?%MU5"#-3/.)#%O($I2:%?(-42(4#N%/3%(%4#-#$();:2$:*3#%"#5"%!/)#%!*$H("%"&("%/3%:*:2)($%!*$%0("( QXmlErrorHandler%($#%"&#%*-)7%",*%"&("%($#%-##0#08
/-"#$'&(-4#%(-0%0("(%3"*$(4#8%B"%:$*1/0#3%",*%0/3"/-'"% 9>3%!*$%$#(0/-4%iO?%0*'2H#-"3%(3%:($"%*!
"&# +$9 .%H*02)#J G*$%'*-1#-/#-'#+%B"%()3*%:$*1/0#3 QXmlDefaultHandler+%(%')(33%"&("%/-&#$/"3%!$*H%())%"&#%&(-0)#$
')(33#3%(-0%"&("%:$*1/0#3%"$/1/()%/H:)#H#-"("/*-3%!*$%())%"&#%!2-'"/*-38%E&/3%0#3/4-+%,/"&%H(-7
• < i%M</H:)#% 9>%!*$%iO?N%$#:*$"3%Z:($3/-4%#1#-"3Z%0/$#'")7%"*%"&#%(::)/'("/*-%"&$*24&%1/$"2() (.3"$('"%&(-0)#$%')(33#3%(-0%*-#%"$/1/()%32.')(33+%/3%2-232()%!*$%B"]%/"%,(3%(0*:"#0%"*%')*3#)7%!*))*,
!2-'"/*-38 "&#%H*0#)%j(1(%/H:)#H#-"("/*-8
• SLO%MS*'2H#-"%L.F#'"%O*0#)N%'*-1#$"3%(-%iO?%0*'2H#-"%/-"*%(%"$##%3"$2'"2$#+%,&/'&%"&#
(::)/'("/*-%'(-%"&#-%-(1/4("#8 K#%,/))%-*,%$#1/#,%(-%#5(H:)#%"&("%3&*,3%&*,%"*%23# QXmlSimpleReader%(-0 QXmlDefaultHandler%"*
:($3#%(-%(0%&*'%iO?%!/)#%!*$H("%(-0%$#-0#$%/"3%'*-"#-"3%/-%( QtreeWidget8%E&# QXmlDefaultHandler
E&#$#%($#%H(-7%!('"*$3%"*%"(I#%/-"*%(''*2-"%,&#-%'&**3/-4%.#",##-%SLO%(-0%< i%!*$%(%:($"/'2)($ 32.')(33 /3%'())#0 SaxHandler+%(-0%"&#%!*$H("%/"%&(-0)#3%/3%"&("%*!%(%.**I%/-0#5+%,/"&%/-0#5%#-"$/#3
(::)/'("/*-8%< i%/3%H*$#%)*,%)#1#)%(-0%232())7%!(3"#$+%,&/'&%H(I#3%/"%#3:#'/())7%(::$*:$/("#%.*"&%!*$ (-0%32.#-"$/#38
3/H:)#%"(3I3%M)/I#%!/-0/-4%())%"&#%*''2$$#-'#3%*!%(%4/1#-%"(4%/-%(-%iO?%0*'2H#-"N%(-0%!*$%$#(0/-4
1#$7%)($4#%!/)#3%"&("%H(7%-*"%!/"%/-%H#H*$78%A2"%!*$%H(-7%(::)/'("/*-3+%"&#%'*-1#-/#-'#%*!!#$#0%.7
!"#$%&'@)')&A2+%$!1320%&1$%%&B.$ SaxHandler
SLO%*2",#/4&3%"&#%:*"#-"/()%3:##0%(-0%H#H*$7%.#-#!/"3%*!%< i8
G*$%,$/"/-4%iO?%!/)#3+%",*%*:"/*-3%($#%(1(/)(.)#%(3%,#))J%K#%'(-%4#-#$("#%"&#%iO?%.7%&(-0+%*$%,#
'(-%$#:$#3#-"%"&#%0("(%(3%(%SLO%"$##%/-%H#H*$7%(-0%(3I%"&#%"$##%"*%,$/"#%/"3#)!%"*%(%!/)#8
startDocument()
startElement("doc")
startElement("quote")
!"#$%&'@)5)&C&8..>&!29%D&B!/%&9!74/3E%9&!2&3 QtreeWidget
characters("Ars longa vita brevis")
endElement("quote")
endElement("doc")
endDocument()
}
return true;
}
<doc>
!" fatalError()#$/-1(%*-#%'#1.,,"3#7!"-#(!"#&".3"&#$.%,'#(*#).&'"#(!"#89:#$%,"5#B$#(!%'#*11/&'4#7" <quote>Ars longa vita brevis</quote>
'%+),>#3%'),.>#.#+"''.;"#0*C4#;%H%-;#(!"#,%-"#-/+0"&4#(!"#1*,/+-#-/+0"&4#.-3#(!"#).&'"&<'#"&&*& <translation>Art is long, life is short</translation>
("C(5 </doc>
!%'#1*+),"("'#(!"#%+),"+"-(.(%*-#*$#(!" SaxHandler#1,.''5#O*7#,"(<'#'""#!*7#7"#1.-#+.F"#/'"#*$
%(2 B(#1*&&"')*-3'#(*#(!"#$*,,*7%-;#QE9#(&""2
Q%$$"&"-(#(>)"'#*$#-*3"'#1.-#!.H"#3%$$"&"-(#F%-3'#*$#1!%,3#-*3"'5#P*&#"C.+),"4#.- Element#-*3"#1.-
I"#'"(#/)#. QtreeWidget#7%(!#(7*#1*,/+-'5# !"-#7"#1&".("#. QFile#*0D"1(#$*&#(!"#$%,"#(!.(#%'#(* 0" 1*-(.%-#*(!"& Element#-*3"'4#.-3#.,'* EntityReference4 Text4 CDATASection4 ProcessingInstruction4
&".3#.-3#. QXmlSimpleReader#(*#).&'"#(!"#$%,"5#I"#3*-<(#-""3#(*#*)"-#(!" QFile#*/&'",H"'6 .-3 Comment#-*3"'5 P%;/&"#NW5T#'!*7'#7!%1!#-*3"'#1.-#!.H"#7!%1!#F%-3'#*$#1!%,3#-*3"'5# !"#-*3"'
QXmlInputSource#3*"'#(!.(#./(*+.(%1.,,>5 '!*7-#%-#;&.>#1.--*(#!.H"#.->#1!%,3#-*3"'#*$#(!"%&#*7-5
!" QDomNode#1,.''#1.-#'(*&"#.->#(>)"#*$#-*3"5#B$#7"#7.-(#(*#)&*1"''#.#-*3"#$/&(!"&4#7"#+/'(#$%&'(
1*-H"&(#%(#(*#(!"#&%;!(#3.(.#(>)"5#B-#(!%'#"C.+),"4#7"#*-,>#1.&"#.0*/( Element#-*3"'4#'*#7"#1.,,
toElement()#*-#(!" QDomNode#(*#1*-H"&(#%(#(*#. QDomElement#.-3#(!"-#1.,, tagName()#(*#&"(&%"H"#(!"
","+"-(<'#(.;#-.+"5#B$#(!"#-*3"#%' %&!#*$#(>)" Element4#(!" toElement()#$/-1(%*-#&"(/&-'#.#-/,,
QDomElement#*0D"1(4#7%(!#.-#"+)(>#(.;#-.+"5
!"#'"1*-3#.&;/+"-(#(* save()#%'#(!"#%-3"-(.(%*-#'%Y"#(*#/'"5#K#-*-GY"&*#H.,/"#+.F"'#(!"#$%,"#".'%"&
void parseFile(const QString &fileName) $*&#!/+.-'#(*#&".35#Z"&"<'#(!"#89:#$%,"#*/()/(2
{
QStringList labels;
labels << QObject::tr("Terms") << QObject::tr("Pages"); <doc>
QTreeWidget *treeWidget = new QTreeWidget; <quote>Ars longa vita brevis</quote>
treeWidget->setHeaderLabels(labels); <translation>Art is long, life is short</translation>
treeWidget->setWindowTitle(QObject::tr("DOM Parser")); </doc>
treeWidget->show();
QFile file(fileName);
DomParser(&file, treeWidget);
K-*(!"&#'1"-.&%*#*11/&'#%-#.)),%1.(%*-'#(!.(#/'"#(!"#QE9#(&""#.'#(!"%&#)&%+.&>#3.(.#'(&/1(/&"5# !"'"
}
.)),%1.(%*-'#7*/,3#-*&+.,,>#&".3#%-#89:#3*1/+"-('#/'%-;#QE94#(!"-#+*3%$>#(!"#QE9#(&""#%-
+"+*&>4#.-3#$%-.,,>#1.,, save()#(*#1*-H"&(#(!"#(&""#0.1F#(*#89:5
:%F"#(!"#)&"H%*/'#"C.+),"4#7"#-""3#(!"#$*,,*7%-;#,%-"#%-#(!"#.)),%1.(%*-<' .pro#$%,"#(*#,%-F#.;.%-'(#(!"
!"#$#,%0&.&>2 <?xml version="1.0" encoding="ISO-8859-1"?>
QT += xml
(*#(!"#QE9#(&""5# !"#$*,,*7%-;#1*3"#'-%))"(#'!*7'#!*7#(*#3*#(!%'2
9*'(#.)),%1.(%*-'#)&*H%3"#(!"%&#/'"&'#7%(!#*-,%-"#!",)5#L*+"#!",)#%'#'!*&(4#'/1!#.'#(**,(%)'4#'(.(/'
(%)'4#.-3#?I!.(<'# !%'c?#!",)5#O.(/&.,,>4#U(#'/))*&('#.,,#*$#(!"'"5#E(!"&#!",)#1.-#0"#+/1!#+*&"
"C("-'%H"4#%-H*,H%-;#+.->#).;"'#*$#("C(5#P*&#(!%'#F%-3#*$#!",)4#>*/#1.-#/'" QTextBrowser#.'#.#'%+),"
*-,%-"#!",)#0&*7'"&4#*&#>*/#1.-#%-H*F" !'-../.!)%!#*&#.-#Z 9:#0&*7'"&#$&*+#>*/&#.)),%1.(%*-5
I"#1.-#.33#(**,(%)'#(*#.&0%(&.&>#7%3;"('#%-#1*3"#/'%-; QWidget::setToolTip()5#P*&#"C.+),"2
findButton->setToolTip(tr("Find next"));
B-#'*+"#'%(/.(%*-'4#%(#%'#3"'%&.0,"#(*#)&*H%3"#+*&"#%-$*&+.(%*-#.0*/(#.#7%3;"(#(!.-#1.-#0"#;%H"-#0>
*#'"(#(!"#(**,(%)#*$#. QAction#(!.(#1*/,3#0"#.33"3#(*#.#+"-/#*&#.#(**,0.&4#7"#1.-#'%+),>#1.,, (**,(%)'#*&#'(.(/'#(%)'5#P*&#"C.+),"4#7"#+%;!(#7.-(#(*#)&*H%3"#.#1*+),"C#3%.,*;#7%(!#"C),.-.(*&>
setToolTip()#*-#(!"#.1(%*-5#P*&#"C.+),"2 ("C(#.0*/(#".1!#$%",3#7%(!*/(#$*&1%-;#(!"#/'"&#(*#%-H*F"#.#'").&.("#!",)#7%-3*75#?I!.(<'# !%'c?
+*3"#%'#.-#%3".,#'*,/(%*-#$*&#(!%'5#I!"-#.#7%-3*7#%'#%-#?I!.(<'# !%'c?#+*3"4#(!"#1/&'*!.-;"'#(*
.-3#(!"#/'".-#1,%1F#*-#.->#/'"&#%-("&$.1"#1*+)*-"-(#(*#*0(.%-#%('#!",)#("C(5# *#"-("&#?I!.(<'
newAction = new QAction(tr("&New"), this);
!%'c?#+*3"4#(!"#/'".-#"%(!",%1F#(!"#c#0/((*-#%-#(!"#3%.,*;<'#(%(,"#0.&#=*-#I%-3*7'#.-3#dQeA#*&
newAction->setToolTip(tr("New document"));
)&"'' Shift+F15
Z"&"#%'#.-#"C.+),"#*$#.#?I!.(<'# !%'c?#("C(#'"(#*-#.#3%.,*;2
B$#7"#3*-<(#"C),%1%(,>#'"(#.#(**,(%)4 QAction#7%,,#./(*+.(%1.,,>#/'"#(!"#.1(%*-#("C(5
!"#$%&';)=)&<&2!,13"&4037!-"&,&>?0,.@4&A0!4B>&0%15&.%C.
I"#0";%-#7%(!#(!"#!".3"&#$%,"2
I!"-#7"#'"(#.#?I!.(<'# !%'c?#("C(#*-#.-#.1(%*-4#(!"#("C(#7%,,#0"#'!*7-#7!"-#(!"#/'",%1F'#(!"
+"-/#%("+#*&#(**,0.�/((*-#*&#)&"''"'#(!"#'!*&(1/(#F">#7!%,"#%-#?I!.(<'# !%'c?#+*3"5#I!"-#(!"
/'"&#%-("&$.1"#1*+)*-"-('#*$#.-#.)),%1.(%*-<'#+.%-#7%-3*7#)&*H%3"#?I!.(<'# !%'c?#("C(4#%(#%' #include <QWidget>
1/'(*+.&>#(*#)&*H%3"#.#I!.(<'# !%'c#*)(%*-#%-#(!"#Z",)#+"-/#.-3#.#1*&&"')*-3%-;#(**,0.�/((*-5 class QPushButton;
!%'#1.-#0"#3*-"#0>#1&".(%-;#.#I!.(<'# !%'c#.1(%*-#7%(!#(!"#'(.(%1 QWhatsThis::createAction() class QTextBrowser;
$/-1(%*-#.-3#.33%-;#(!"#.1(%*-#%(#&"(/&-'#(*#.#Z",)#+"-/#.-3#(*#.#(**,0.&5# !" QWhatsThis#1,.''#.,'* class HelpBrowser : public QWidget
)&*H%3"'#'(.(%1#$/-1(%*-'#(*#)&*;&.++.(%1.,,>#"-("&#.-3#,".H"#?I!.(<'# !%'c?#+*3"5 {
Q_OBJECT
public:
HelpBrowser(const QString &path, const QString &page,
Using QTextBrowser as a Simple Help Engine QWidget *parent = 0);
static void showPage(const QString &page);
private slots:
:.&;"#.)),%1.(%*-'#+.>#&"@/%&"#+*&"#*-,%-"#!",)#(!.-#(**,(%)'4#'(.(/'#(%)'4#.-3#?I!.(<'# !%'c?#!",) void updateWindowTitle();
1.-#&".'*-.0,>#'!*75#K#'%+),"#'*,/(%*-#(*#(!%'#%'#(*#)&*H%3"#.#!",)#0&*7'"&5#K)),%1.(%*-'#(!.(#%-1,/3" private:
.#!",)#0&*7'"&#(>)%1.,,>#!.H"#.#Z",)#"-(&>#%-#(!"#+.%-#7%-3*7<'#Z",)#+"-/#.-3 .#Z",)#0/((*-#%- QTextBrowser *textBrowser;
"H"&>#3%.,*;5 QPushButton *homeButton;
QPushButton *backButton;
B-#(!%'#'"1(%*-4#7"#)&"'"-(#(!"#'%+),"#!",)#0&*7'"&#'!*7-#%- P%;/&"#Nf5T#.-3#"C),.%-#!*7#%(#1.-#0" QPushButton *closeButton;
};
/'"3#7%(!%-#.-#.)),%1.(%*-5# !"#7%-3*7#/'"'#. QTextBrowser#(*#3%'),.>#!",)#).;"'#(!.(#.&"#+.&F"3
/)#7%(!#.-#Z 9:G0.'"3#'>-(.C5 QTextBrowser#1.-#!.-3,"#.#,*(#*$#Z 9:#(.;'4#'*#%(#%'#%3".,#$*&#(!%'
)/&)*'"5
!" HelpBrowser#)&*H%3"'#.#'(.(%1#$/-1(%*-#(!.(#1.-#0"#1.,,"3#$&*+#.->7!"&"#%-#(!"#.)),%1.(%*-5# !%'
$/-1(%*-#1&".("'#. HelpBrowser#7%-3*7#.-3#'!*7'#(!"#;%H"-#).;"5
!"#$%&';)*)&A0% HelpBrowser&7!2"%.
[View full size image] Z"&"<'#(!"#0";%--%-;#*$#(!"#%+),"+"-(.(%*-2
#include <QtGui>
#include "helpbrowser.h"
HelpBrowser::HelpBrowser(const QString &path, const QString &page,
QWidget *parent)
: QWidget(parent)
{
setAttribute(Qt::WA_DeleteOnClose);
setAttribute(Qt::WA_GroupLeader); P*&#(!%'#"C.+),"4#7"#.''/+"#(!.(#(!"#3*1/+"-(.(%*-#%'#,*1.("3#%-#(!" doc#'/03%&"1(*&>#*$#(!"
textBrowser = new QTextBrowser; 3%&"1(*&>#1*-(.%-%-;#(!"#.)),%1.(%*-<'#"C"1/(.0,"5#K,,#(!"#).;"'#).''"3#(*#(!" showPage()#$/-1(%*-#7%,,
homeButton = new QPushButton(tr("&Home")); 0"#(.F"-#$&*+#(!%'#'/03%&"1(*&>5
backButton = new QPushButton(tr("&Back"));
closeButton = new QPushButton(tr("Close"));
closeButton->setShortcut(tr("Esc")); O*7#7"#.&"#&".3>#(* %-H*F"#(!"#!",)#0&*7'"&#$&*+#(!"#.)),%1.(%*-5#B-#(!"#.)),%1.(%*-<'#+.%-#7%-3*74
QHBoxLayout *buttonLayout = new QHBoxLayout; 7"#7*/,3#1&".("#.#Z",)#.1(%*-#.-3#1*--"1(#%(#(*#. help()#',*(#(!.(#1*/,3#,**F#,%F"#(!%'2
buttonLayout->addWidget(homeButton);
buttonLayout->addWidget(backButton);
buttonLayout->addStretch(); void MainWindow::help()
buttonLayout->addWidget(closeButton); {
QVBoxLayout *mainLayout = new QVBoxLayout; HelpBrowser::showPage("index.html");
mainLayout->addLayout(buttonLayout); }
mainLayout->addWidget(textBrowser);
setLayout(mainLayout);
connect(homeButton, SIGNAL(clicked()), textBrowser, SLOT(home()));
connect(backButton, SIGNAL(clicked()), !%'#.''/+"'#(!.(#(!"#+.%-#!",)#$%,"#%'#1.,,"3 index.html5#P*%.,*;'4#7"#7*/,3#1*--"1(#(!"#Z",)
textBrowser, SLOT(backward())); 0/((*-#(*#. help()#',*(#(!.(#+%;!(#,**F#,%F"#(!%'2
connect(closeButton, SIGNAL(clicked()), this, SLOT(close()));
connect(textBrowser, SIGNAL(sourceChanged(const QUrl &)),
this, SLOT(updateWindowTitle())); void EntryDialog::help()
textBrowser->setSearchPaths(QStringList() << path << ":/images"); {
textBrowser->setSource(page); HelpBrowser::showPage("forms.html#editing");
} }
CONFIG += assistant
I!"-"H"&#(!"#'*/&1"#).;"#1!.-;"'4#(!" updateWindowTitle()#',*(#%'#1.,,"35# !" documentTitle()
$/-1(%*-#&"(/&-'#(!"#("C(#')"1%$%"3#%-#(!"#).;"<' <title>#(.;5
I"#7%,,#-*7#&"H%"7#(!"#1*3"#*$#.#-"7 HelpBrowser#1,.''#(!.(#/'"' !'-../.!)%!5
void HelpBrowser::showPage(const QString &page)
{
#ifndef HELPBROWSER_H
QString path = QApplication::applicationDirPath() + "/doc";
#define HELPBROWSER_H
HelpBrowser *browser = new HelpBrowser(path, page);
class QAssistantClient;
browser->resize(500, 400);
class QString;
browser->show();
class HelpBrowser
}
{
public:
static void showPage(const QString &page);
B-#(!" showPage()#'(.(%1#$/-1(%*-4#7"#1&".("#(!" HelpBrowser#7%-3*7#.-3#(!"-#'!*7#%(5# !"#7%-3*7 private:
7%,,#0"#3"'(&*>"3#./(*+.(%1.,,>#7!"-#(!"#/'",*'"'#%(4#'%-1"#7"#'"(#(!" Qt::WA_DeleteOnClose static QAssistantClient *assistant;
.((&%0/("#%-#(!" HelpBrowser#1*-'(&/1(*&5 };
#endif
Z"&"<'#(!"#-"7 helpbrowser.cpp#$%,"2
Part III: Advanced Qt
#include <QApplication>
#include <QAssistantClient>
#include "helpbrowser.h"
QAssistantClient *HelpBrowser::assistant = 0; S!.)("&#Ni5 #B-("&-.(%*-.,%Y.(%*-
void HelpBrowser::showPage(const QString &page)
{
QString path = QApplication::applicationDirPath() + "/doc/" + page; S!.)("&#N]5 #9/,(%(!&".3%-;
if (!assistant)
assistant = new QAssistantClient(""); S!.)("&#Nj5 #S&".(%-;#R,/;%-'
assistant->showPage(path);
} S!.)("&#VJ5 #R,.($*&+GL)"1%$%1#P".(/&"'
S!.)("&#VN5 #e+0"33"3#R&*;&.++%-;
!" QAssistantClient#1*-'(&/1(*&#.11")('#.#).(!#'(&%-;#.'#%('#$%&'(#.&;/+"-(4#7!%1!#%(#/'"'#(*#,*1.("
(!" !'-../.!)%!#"C"1/(.0,"5#[>#).''%-;#.-#"+)(>#).(!4#7"#'%;-%$>#(!.( QAssistantClient#'!*/,3
,**F#$*&#(!"#"C"1/(.0,"#%-#(!" PATH#"-H%&*-+"-(#H.&%.0,"5 QAssistantClient#!.'#. showPage()#$/-1(%*-
(!.(#.11")('#.#).;"#-.+"#7%(!#.-#*)(%*-.,#Z 9:#.-1!*&5
!"#-"C(#'(")#%'#(*#)&").&"#.#(.0,"#*$#1*-("-('#.-3#.-#%-3"C#$*&#(!"#3*1/+"-(.(%*-5# !%'#%'#3*-"#0>
1&".(%-;#. !'-../.!)%!#)&*$%,"#.-3#7&%(%-;#. .dcf#$%,"#(!.(#)&*H%3"'#%-$*&+.(%*-#.0*/(#(!"
3*1/+"-(.(%*-5#K,,#(!%'#%'#"C),.%-"3#%- !'-../.!)%!<'#*-,%-"#3*1/+"-(.(%*-4#'*#7"#7%,,#-*(#3/),%1.("
(!.(#%-$*&+.(%*-#!"&"5
E$("-4#%(#%'-<(#"-*/;!#(*#.,,*7#/'"&'#(*#"-("&#("C(#%-#(!"%&#-.(%H"#,.-;/.;"6#(!"#"-(%&"#/'"&#%-("&$.1"<' !$Q"#$!*I!$*,-+,*$#?BB()!#$!2*$;(&&(9+,-$9)+!+,-$#:#!*D#$(,$'&&$B&'!;()D#=$<)'6+%A$R2+,*#*A$R:)+&&+%A
+/'(#0"#(&.-',.("3#.'#7",,5#U(#+.F"'#(!%'#".'>2#L%+),>#7&.)#.,,#/'"&GH%'%0,"#'(&%-;' 7%(!#(!" tr() J)**FA$8*6)*9A$S'B',*#*A$T()*',A$@'(A$@'!+,A$N2'+A$',/$U+*!,'D*#*0$>!$'&#($#?BB()!#$'&&$!2*$.,+%(/*
$/-1(%*-#=.'#7"#!.H"#3*-"#%-#".&,%"!.)("&'A#.-3#/'"#U(<'#'/))*&(%-;#(**,'#(*#)&").&"#(&.-',.(%*- Q03$#%)+B!#$!2'!$/(,"!$)*V?+)*$',:$#B*%+'&$B)(%*##+,-0$>,$'//+!+(,A$!2*$;(&&(9+,-$9)+!+,-$#:#!*D#$')*
$%,"'#%-#(!"#&"@/%&"3#,.-;/.;"'5#U(#)&*H%3"'#.#^\B#(**,#1.,,"3 !'0/%1(/.!#$*&#/'"#0>#(&.-',.(*&'5 ! #?BB()!*/$(,$W33$9+!2$H(,!%(,;+-$',/$(,$)*%*,!$E*)#+(,#$(;$G+,/(9#=$X*,-'&+A$Y*E','-')+A$J?C')'!+A
0/%1(/.!#%'#1*+),"+"-("3#0>#(7*#1*++.-3G,%-"#)&*;&.+'4 lupdate#.-3 lrelease4#7!%1!#.&" J?)D?F2+A$T',,'/'A$T2D*)A$Z'&':'&'DA$[:)+'%A$N'D+&A$N*&?-?A$N2'','$KY2+E*2+LA$',/$N+6*!',0
(>)%1.,,>#&/-#0>#(!"#.)),%1.(%*-<'#3"H",*)"&'5 H+,'&&:A$\)+:'$+#$#?BB()!*/$(,$W33A$',/$Z(,-(&+',$',/$[+,2'&'$')*$#?BB()!*/$(,$G+,/(9#$W]0
<##?D+,-$!2'!$!2*$B)(B*)$;(,!#$')*$+,#!'&&*/$(,$!2*$#:#!*DA$ !$%',$)*,/*)$!*I!$?#+,-$',:$(;$!2*#*
9)+!+,-$#:#!*D#0$<,/$'##?D+,-$!2'!$!2*$B)(B*)$+,B?!$D*!2(/#$')*$+,#!'&&*/A$?#*)#$9+&&$6*$'6&*$!(
P*&#+*'(#.)),%1.(%*-'4#.#(&.-',.(%*-#$%,"#%'#,*.3"3#.(#'(.&(/)4#0.'"3#*-#(!"#/'"&<'#,*1.,"#'"((%-;'5#[/(
*,!*)$!*I!$!2'!$?#*#$!2*#*$9)+!+,-$#:#!*D#$+,$!2*+)$ !$'BB&+%'!+(,#0
%-#.#$"7#1.'"'4#%(#%'#.,'*#-"1"''.&>#$*&#/'"&'#(*#0"#.0," (*#'7%(1!#,.-;/.;"#.(#&/-G(%+"5# !%'#%'
)"&$"1(,>#)*''%0,"#7%(!#U(4#.,(!*/;!#%(#3*"'#&"@/%&"#.#0%(#*$#"C(&.#7*&F5#K-3#(!.-F'#(*#U(<'#,.>*/(
'>'("+4#(!"#H.&%*/'#/'"&#%-("&$.1"#1*+)*-"-('#7%,,#./(*+.(%1.,,>#.3D/'(#(*#+.F"#&**+#$*&#(!" ])(-)'DD+,-$9+!2 QChar$+#$#&+-2!&:$/+;;*)*,!$;)(D$B)(-)'DD+,-$9+!2 char0$N($(6!'+,$!2*$,?D*)+%
(&.-',.("3#("C('#7!"-#(!">#.&"#,*-;"&#(!.-#(!"#*&%;%-.,#("C('5 E'&?*$(;$' QCharA$%'&& unicode()$(,$+!0$N($(6!'+,$!2*$<[R>>$()$@'!+,53$E'&?*$(;$' QChar$K'#$' charLA$%'&&
toLatin1()0$H()$,(,5@'!+,53$%2')'%!*)#A toLatin1()$)*!?),#$"^_"0
>;$!2*$#(?)%*$;+&*$+#$*,%(/*/$+,$@'!+,53A$#B*%+;:+,-$@'!+,53$%2')'%!*)#$+#$C?#!$'#$*'#:= [B*%+'&$%')*$+#$,**/*/$92*,$9*$)*'/$',/$9)+!*$!*I!$;+&*#0$N*I!$;+&*#$%',$?#*$'$E')+*!:$(;$*,%(/+,-#A
',/$+!$+#$(;!*,$+DB(##+6&*$!($-?*##$'$!*I!$;+&*"#$*,%(/+,-$;)(D$+!#$%(,!*,!#0$X:$/*;'?&!A QTextStream
?#*#$!2*$#:#!*D"#$&(%'&$756+!$*,%(/+,-$K'E'+&'6&*$'# QTextCodec::codecForLocale()L$;()$6(!2$)*'/+,-
str[0] = 'Ñ'; ',/$9)+!+,-0$H()$<D*)+%',$',/$G*#!$1?)(B*',$&(%'&*#A$!2+#$?#?'&&:$D*',#$@'!+,530
>;$9*$/*#+-,$(?)$(9,$;+&*$;()D'!$',/$9',!$!($6*$'6&*$!($)*'/$',/$9)+!*$')6+!)'):$.,+%(/*$%2')'%!*)#A
9*$%',$#'E* !2*$/'!'$'#$.,+%(/*$6:$%'&&+,- */+!()$!2'!$?#*#$',$*,%(/+,-$#?%2$'#$1.R5S]$()$[2+;!5S>[0$[?%2$',$*/+!()$'&&(9#$!2*D$!($!:B*$+,
S'B',*#*$%2')'%!*)#$#*'D&*##&:A$#($!2'!$!2*:$%',$9)+!*$%(/*$&+F*$!2+#=
stream.setCodec("UTF-16");
stream.setGenerateByteOrderMark(true); QPushButton *button = new QPushButton(tr(" "));
<,(!2*)$*,%(/+,-$!2'!$#?BB()!#$!2*$92(&*$(;$.,+%(/*$+#$.NH570$>!#$D'+,$'/E',!'-*$(E*)$.NH534$+#
!2'!$+!$+#$'$#?B*)#*!$(;$<[R>>0$<,:$%2')'%!*)$+,$!2*$)',-* 0x00$!( 0x7F$+#$)*B)*#*,!*/$'#$'$#+,-&* <&!*),'!+E*&:A$!2*:$%',$!*&&$ !$!($?#*$'$#B*%+;+%$%(/*%$92*,$%(,E*)!+,-$6*!9**, const char *$',/
6:!*0$\!2*)$%2')'%!*)#A$+,%&?/+,-$@'!+,53$%2')'%!*)#$'6(E* 0x7FA$')*$)*B)*#*,!*/$6:$D?&!+56:!* QString$6:$%'&&+,- QTextCodec::setCodecForCStrings()=
#*V?*,%*#0$H()$!*I!$!2'!$+#$D(#!&:$<[R>>A$.NH57$!'F*#$?B$'6(?!$2'&;$!2*$#B'%*$%(,#?D*/$6:$.NH5340
N($?#*$.NH57$9+!2 QTextStreamA$%'&& setCodec()$9+!2$`.NH57`$'#$!2*$%(/*%$,'D*$6*;()*$)*'/+,-$',/
9)+!+,-0 QTextCodec::setCodecForCStrings(QTextCodec::codecForName("EUC-JP"));
>;$9*$'&9':#$9',!$!($)*'/$',/$9)+!*$@'!+,53$)*-')/&*##$(;$!2*$?#*)"#$&(%'&*A$9*$%',$#*!$!2*$`>[\
77ab53`$%(/*%$(,$!2* QTextStream0$H()$*I'DB&*= N2*$!*%2,+V?*#$/*#%)+6*/$'6(E*$%',$6*$'BB&+*/$!($',:$,(,5@'!+,53$&',-?'-*A$+,%&?/+,-$R2+,*#*A
J)**FA$T()*',A$',/$c?##+',0
g*+!2*)$(;$!2*#*$+#$,*%*##'):$;()$'BB&+%'!+(,#$!2'!$9+&&$,*E*)$6*$!)',#&'!*/0$8(9*E*)A$?#+,- TR()
)*V?+)*#$'&D(#!$,($*;;()!$',/$&*'E*#$!2*$/(()$(B*,$;()$/(+,-$!)',#&'!+(,#$'!$'$&'!*)$/'!*0 >,$*E*):$*I'DB&*$#($;')A$!2*$%(,!*I!$2'#$6**,$'$%&'##$,'D*0$N2+#$+#$%(,E*,+*,!A$6*%'?#*$9*$%',
'&D(#!$'&9':#$(D+!$+!A$6?!$!2+#$/(*#,"!$2'E*$!($6*$!2*$%'#*0$N2*$D(#!$-*,*)'&$9':$(;$!)',#&'!+,-$'
N2* tr()$;?,%!+(,$+#$'$#!'!+%$;?,%!+(,$/*;+,*/$+, QObject$',/$(E*))+//*,$+,$*E*):$#?6%&'##$/*;+,*/ #!)+,-$+,$ !$+#$!($?#*$!2* QApplication::translate()$;?,%!+(,A$92+%2$'%%*B!#$?B$!($!2)**$')-?D*,!#=
9+!2$!2* Q_OBJECT$D'%)(0$G2*,$9)+!+,-$%(/*$+,#+/*$' QObject$#?6%&'##A$9*$%',$%'&& tr()$9+!2(?! !2*$%(,!*I!A$!2*$#(?)%*$!*I!A$',/$!2*$(B!+(,'&$%(DD*,!0$H()$*I'DB&*A$2*)*"#$',(!2*)$9':$!(
;()D'&+!:0$<$%'&&$!( TR()$)*!?),#$'$!)',#&'!+(,$+; (,*$+#$'E'+&'6&*P$(!2*)9+#*A$!2*$()+-+,'&$!*I!$+# !)',#&'!*$`8*&&($ !i`=
)*!?),*/0
N2*$B)(6&*D$2*)*$+#$!2'! lupdate$9+&&$,(!$6*$'6&*$!($*I!)'%!$!2*$`\B*,Y)'9*)$fY`$#!)+,-$&+!*)'&A$'#$+!
N2*$%(,!*I!$')-?D*,!$D?#!$6*$!2*$#'D*$'#$!2*$%(,!*I!$-+E*,$!( TR()$() translate()$&'!*)$(,0
/(*#,"!$'BB*')$+,#+/*$' tr()$%'&&0$N2+#$D*',#$!2'!$!2*$!)',#&'!()$9+&&$,(!$2'E*$!2*$(BB()!?,+!:$!(
!)',#&'!*$!2*$#!)+,-0$N2+#$+##?*$(;!*,$')+#*#$+,$%(,C?,%!+(,$9+!2$/:,'D+%$#!)+,-#=
G2*,$9*$#!')!$?#+,- TR()$+,$',$'BB&+%'!+(,A$+!"#$*'#:$!($;()-*!$!($#?))(?,/$#(D*$?#*)5E+#+6&*$#!)+,-#
9+!2$' tr()$%'&&A$*#B*%+'&&:$92*,$9*$')*$C?#!$6*-+,,+,-$!($?#*$+!0$N2*#*$D+##+,- TR()$%'&&#$')*
// WRONG *E*,!?'&&:$/+#%(E*)*/$6:$!2*$!)',#&'!()$()A$9()#*A$6:$?#*)#$(;$!2*$!)',#&'!*/$'BB&+%'!+(,A$92*,$#(D*
statusBar()->showMessage(tr("Host " + hostName + " found")); #!)+,-#$'BB*')$+,$!2*$()+-+,'&$&',-?'-*0$N($'E(+/$!2+#$B)(6&*DA$9*$%',$!*&&$ !$!($;()6+/$+DB&+%+!
%(,E*)#+(,#$;)(D const char *$!( QString0$G*$/($!2+#$6:$/*;+,+,-$!2* QT_NO_CAST_FROM_ASCII
B)*B)(%*##()$#:D6(&$6*;()*$+,%&?/+,-$',:$ !$2*'/*)0$N2*$*'#+*#!$9':$!($*,#?)*$!2+#$#:D6(&$+#$#*!$+#
!($'//$!2*$;(&&(9+,-$&+,*$!($!2*$'BB&+%'!+(,"# .pro$;+&*=
8*)*A$!2*$#!)+,-$9*$B'##$!( tr()$E')+*#$/*B*,/+,-$(,$!2*$E'&?*$(; hostNameA$#($9*$%',"!$)*'#(,'6&:
*IB*%! TR()$!($!)',#&'!*$+!$%())*%!&:0
DEFINES += QT_NO_CAST_FROM_ASCII
N2*$#(&?!+(,$+#$!($?#* QString::arg()=
>!$D':$B)(E*$D()*$%(,E*,+*,!$;()$(?)$?#*)#$+;$9*$#?BB&:$(?)$'BB&+%'!+(,#$9+!2$!2*$!)',#&'!+(,$;+&*# >%(,#$!2'!$%(,!'+,$'&B2'6*!+%$%2')'%!*)#$E*):$%(DD(,&:$,**/$!($6*$!)',#&'!*/0$H()$*I'DB&*A$!2*
*D6*//*/$+,$!2*$*I*%?!'6&*A$?#+,-$ !"#$)*#(?)%*$#:#!*D0$g(!$(,&:$/(*#$!2+#$)*/?%*$!2*$,?D6*)$(; &*!!*)$">"$(,$'$!((&6')$6?!!(,$'##(%+'!*/$9+!2$'$9()/$B)(%*##()"#$>!'&+%$(B!+(,$#2(?&/$6*$)*B&'%*/$6:$'
;+&*#$/+#!)+6?!*/$'#$B')!$(;$!2*$B)(/?%!A$+!$'&#($'E(+/#$!2*$)+#F$(;$!)',#&'!+(,$;+&*#$-*!!+,-$&(#!$() "R"$+,$[B',+#2$KR?)#+E(L$',/$6:$'$"T"$+,$Y',+#2A$Y?!%2A$J*)D',A$g()9*-+',A$',/$[9*/+#2$KT?)#+EL0
/*&*!*/$6:$'%%+/*,!0 8*)*"#$'$#+DB&*$9':$!($/($+!=
void MainWindow::createMenus()
{
fileMenu = new QMenu(this);
fileMenu->addAction(newAction);
fileMenu->addAction(openAction);
fileMenu->addAction(saveAction);
fileMenu->addAction(exitAction);
...
createLanguageMenu();
helpMenu = new QMenu(this);
helpMenu->addAction(aboutAction);
helpMenu->addAction(aboutQtAction);
menuBar()->addMenu(fileMenu);
[+,%*$9*$/(,"!$F,(9$92+%2$&',-?'-*$!2*$?#*)$9+&&$9',!$!($?#*$92*,$!2*$'BB&+%'!+(,$+#$#!')!*/A$9*$,( menuBar()->addMenu(editMenu);
&(,-*)$&('/$!)',#&'!+(,#$+,$!2* main()$;?,%!+(,0$>,#!*'/A$9*$9+&&$&('/$!2*D$/:,'D+%'&&:$92*,$!2*:$')* menuBar()->addMenu(reportsMenu);
,**/*/A$#($'&&$!2*$%(/*$!2'!$9*$,**/$!($2',/&*$!)',#&'!+(,#$D?#!$-($+,$!2*$D'+,$9+,/(9$',/$/+'&(- menuBar()->addMenu(languageMenu);
%&'##*#0 menuBar()->addMenu(helpMenu);
}
@*!"#$2'E*$'$&((F$'!$!2*$'BB&+%'!+(,"# QMainWindow$#?6%&'##0
N2* createMenus()$;?,%!+(,$%)*'!*#$D*,?#A$6?!$/(*#$,(!$-+E*$!2*D$',:$!+!&*#0$<-'+,A$!2+#$9+&&$6*
MainWindow::MainWindow() /(,*$+, retranslateUi()0
{
journalView = new JournalView; >,$!2*$D+//&*$(;$!2*$;?,%!+(,A$9*$%'&& createLanguageMenu()$!($;+&&$!2*$@',-?'-*$D*,?$9+!2$!2*$&+#!$(;
setCentralWidget(journalView); #?BB()!*/$&',-?'-*#0$G*$9+&&$)*E+*9$+!#$#(?)%*$%(/*$+,$'$D(D*,!0 H+)#!A$&*!"#$&((F$'!
qApp->installTranslator(&appTranslator);
retranslateUi()=
qApp->installTranslator(&qtTranslator);
qmPath = qApp->applicationDirPath() + "/translations";
createActions();
createMenus(); void MainWindow::retranslateUi()
retranslateUi(); {
} newAction->setText(tr("&New"));
newAction->setShortcut(tr("Ctrl+N"));
newAction->setStatusTip(tr("Create a new journal"));
...
>,$!2*$%(,#!)?%!()A$9*$#*!$!2*$%*,!)'&$9+/-*!$!($6*$' JournalViewA$' QTableWidget$#?6%&'##0$N2*,$9* aboutQtAction->setText(tr("About &Qt"));
#*!$?B$'$;*9$B)+E'!*$D*D6*)$E')+'6&*#$)*&'!*/ !($!)',#&'!+(,= aboutQtAction->setStatusTip(tr("Show the Qt library's About box"));
fileMenu->setTitle(tr("&File"));
• N2* appTranslator$E')+'6&*$+#$' QTRanslator$(6C*%!$?#*/$;()$#!()+,-$!2*$%?))*,!$'BB&+%'!+(,"# editMenu->setTitle(tr("&Edit"));
!)',#&'!+(,0 reportsMenu->setTitle(tr("&Reports"));
languageMenu->setTitle(tr("&Language"));
helpMenu->setTitle(tr("&Help")); void MainWindow::switchLanguage(QAction *action)
setWindowTitle(tr("Call Center")); {
} QString locale = action->data().toString();
appTranslator.load("callcenter_" + locale, qmPath);
qtTranslator.load("qt_" + locale, qmPath);
retranslateUi();
N2* retranslateUi()$;?,%!+(,$+#$92*)*$'&&$!2* TR()$%'&&#$;()$!2* MainWindow$%&'##$(%%?)0$>!$+#$%'&&*/$'! }
!2*$*,/$(;$!2* MainWindow$%(,#!)?%!()$',/$'&#($*E*):$!+D*$'$?#*)$%2',-*#$!2*$'BB&+%'!+(,"#$&',-?'-*
?#+,-$!2*$@',-?'-*$D*,?0
N2* switchLanguage()$#&(!$+#$%'&&*/$92*,$!2*$?#*)$%2((#*#$'$&',-?'-*$;)(D$!2*$@',-?'-*$D*,?0$G*
G*$#*!$*'%2 QAction"#$!*I!A$#2()!%?!$F*:A$',/$#!'!?#$!+B0$G*$'&#($#*!$*'%2 QMenu"#$!+!&*A$'#$9*&&$'#$!2*
&('/$!2*$!)',#&'!+(,$;+&*#$;()$!2*$'BB&+%'!+(,$',/$;()$ !A$',/$9*$%'&& retranslateUi()$!($)*!)',#&'!*$'&&
9+,/(9$!+!&*0
!2*$#!)+,-#$;()$!2*$D'+,$9+,/(90
\,*$B')!+%?&')$/+;;+%?&!:$+#$!($B)*#*,!$'$,+%*$,'D*$;()$!2*$&',-?'-*$B)(E+/*/$6:$*'%2 .qm$;+&*0$S?#!
#2(9+,-$`*,`$;()$`1,-&+#2`$()$`/*`$;()$`Y*?!#%2`A$6'#*/$(,$!2*$,'D*$(;$!2* .qm$;+&*A$&((F#$%)?/*$',/ N2* JournalView$%&'##$+#$' QTableWidget$#?6%&'##0$<!$!2*$*,/$(;$!2*$%(,#!)?%!()A$9*$%'&&$!2*$B)+E'!*
9+&&$%(,;?#*$#(D*$?#*)#0$N2*$#(&?!+(,$?#*/$+, createLanguageMenu()$+#$!($%2*%F$!2*$!)',#&'!+(,$(;$!2* ;?,%!+(, retranslateUi()$!($#*!$!2*$9+/-*!"#$#!)+,-#0$N2+#$+#$#+D+&')$!($92'!$9*$/+/$;() MainWindow0
#!)+,-$`1,-&+#2`$+,$!2*$`Z'+,G+,/(9`$%(,!*I!0$N2'!$#!)+,-$#2(?&/$6*$!)',#&'!*/$!($`Y*?!#%2`$+,$'
J*)D',$!)',#&'!+(,A$!($`H)',q'+#`$+,$'$H)*,%2$!)',#&'!+(,A$',/$!($` `$+,$'$S'B',*#*$!)',#&'!+(,0
void JournalView::changeEvent(QEvent *event)
{
G*$%)*'!*$(,*$%2*%F'6&* QAction$;()$*'%2$&',-?'-*$',/$#!()*$!2*$&(%'&*$,'D*$+,$!2*$'%!+(,"#$`/'!'` if (event->type() == QEvent::LanguageChange)
+!*D0$G*$'//$!2*D$!($' QActionGroup$(6C*%!$!($*,#?)*$!2'!$(,&:$(,*$@',-?'-*$D*,?$+!*D$+#$%2*%F*/ retranslateUi();
'!$'$!+D*0$G2*,$',$'%!+(,$;)(D$!2*$-)(?B$+#$%2(#*,$6:$!2*$?#*)A$!2* QActionGroup$*D+!#$!2* QTableWidget::changeEvent(event);
triggered(QAction *)$#+-,'&A$92+%2$+#$%(,,*%!*/$!( switchLanguage()0 }
!2*$;+)#!$!+D*$9*$)?, lupdate$',/$')*$?B/'!*/$*E*):$!+D*$9*$#?6#*V?*,!&:$)?, lupdate0
G*$'&#($)*+DB&*D*,!$!2* changeEvent()$;?,%!+(,$!($%'&& retranslateUi()$(, LanguageChange$*E*,!#0
!$-*,*)'!*#$' LanguageChange$*E*,!$92*,$!2*$%(,!*,!#$(;$' QTRanslator$%?))*,!&:$+,#!'&&*/$(, N2*#*$;+&*#$,()D'&&:$2'E*$' .ts$*I!*,#+(,0$N2*:$')*$+,$'$#!)'+-2!;()9')/$WZ@$;()D'!$',/$')*$,(!$'#
QApplication$%2',-*#0$>,$(?)$'BB&+%'!+(,A$!2+#$(%%?)#$92*,$9*$%'&& load()$(, appTranslator$() %(DB'%!$'#$!2*$6+,'): .qm$;+&*#$?,/*)#!((/$6: Qtranslator0$>!$+# lrelease"#$C(6$!($%(,E*)!$2?D',5
qttranslatorA$*+!2*)$;)(D MainWindow::switchLanguage()$()$;)(D MainWindow::changeEvent()0 )*'/'6&* .ts$;+&*#$+,!($D'%2+,*5*;;+%+*,! .qm$;+&*#0$H()$!2*$%?)+(?#A .ts$#!',/#$;()$`!)',#&'!+(,$#(?)%*`
',/ .qm$;()$` ! D*##'-*`$;+&*0
LanguageChange$*E*,!#$#2(?&/$,(!$6*$%(,;?#*/$9+!2 LocaleChange$*E*,!#0 Locale-Change$*E*,!#$')*
-*,*)'!*/$6:$!2*$#:#!*D$',/$!*&&$!2*$'BB&+%'!+(,A$`Z':6*$:(?$#2(?&/$&('/$'$,*9$!)',#&'!+(,0` <##?D+,-$!2'!$9*$')*$&(%'!*/$+,$!2*$/+)*%!():$!2'!$%(,!'+,#$!2*$[B)*'/#2**!$'BB&+%'!+(,"#$#(?)%*
LanguageChange$*E*,!#$')*$-*,*)'!*/$6:$ !$',/$!*&&$!2*$'BB&+%'!+(,"#$9+/-*!#A$`Z':6*$:(?$#2(?&/ %(/*A$9*$%',$)?, lupdate$(, spreadsheet.pro$;)(D$!2*$%(DD',/$&+,*$'#$;(&&(9#=
)*!)',#&'!*$'&&$:(?)$#!)+,-#0`
Translating Applications
CODECFORTR = EUC-JP
N)',#&'!+,-$'$ !$'BB&+%'!+(,$!2'!$%(,!'+,# tr()$%'&&#$+#$'$!2)**5#!*B$B)(%*##=
R(,E*,!+(,'&$J.>$'BB&+%'!+(,#$2'E*$(,*$!2)*'/$(;$*I*%?!+(,$',/$B*);()D$(,*$(B*)'!+(,$'!$'$!+D*0$>;
!2*$?#*)$+,E(F*#$'$!+D*5%(,#?D+,-$(B*)'!+(,$;)(D$!2*$?#*)$+,!*);'%*A$!2*$+,!*);'%*$!:B+%'&&:$;)**h*#
92+&*$!2*$(B*)'!+(,$+#$+,$B)(-)*##0 R2'B!*)$e$K1E*,!$])(%*##+,-L$B)*#*,!#$#(D*$#(&?!+(,#$!($!2+#
B)(6&*D0$Z?&!+5!2)*'/+,-$+#$',(!2*)$#(&?!+(,0
>,$'$D?&!+!2)*'/*/$'BB&+%'!+(,A$!2*$J.>$)?,#$+,$+!#$(9,$!2)*'/$',/$!2*$B)(%*##+,-$!'F*#$B&'%*$+,$(,*
()$D()*$(!2*)$!2)*'/#0$N2+#$)*#?&!# +,$'BB&+%'!+(,#$!2'!$2'E*$)*#B(,#+E*$J.>#$*E*,$/?)+,-$+,!*,#+E*
B)(%*##+,-0$<,(!2*)$6*,*;+!$(;$D?&!+!2)*'/+,-$+#$!2'!$D?&!+B)(%*##()$#:#!*D#$%',$*I*%?!*$#*E*)'&
!2)*'/#$#+D?&!',*(?#&:$(,$/+;;*)*,!$B)(%*##()#A$)*#?&!+,-$+,$6*!!*)$B*);()D',%*0
Updating 'spreadsheet_de.qm'...
Creating Threads
Generated 0 translations (0 finished and 0 unfinished)
Ignored 98 untranslated source texts ])(E+/+,-$D?&!+B&*$!2)*'/#$+,$'$ !$'BB&+%'!+(,$+#$#!)'+-2!;()9')/=$G*$C?#!$#?6%&'## QThread$',/
Updating 'spreadsheet_fr.qm'... )*+DB&*D*,!$+!# run()$;?,%!+(,0$N($#2(9$2(9$!2+#$9()F#A$9*$9+&&$#!')!$6:$)*E+*9+,-$!2*$%(/*$;()$'
Generated 19 translations (17 finished and 2 unfinished) E*):$#+DB&* QThread$#?6%&'##$!2'!$)*B*'!*/&:$B)+,!#$'$-+E*,$#!)+,-$(,$'$%(,#(&*0
Ignored 79 untranslated source texts
ThreadDialog::ThreadDialog(QWidget *parent)
: QDialog(parent)
N2* run()$;?,%!+(,$+#$%'&&*/$!($#!')!$*I*%?!+,-$!2*$!2)*'/0$<#$&(,-$'#$!2* stopped$E')+'6&*$+# falseA
{
!2*$;?,%!+(,$F**B#$B)+,!+,-$!2*$-+E*,$D*##'-*$!($!2*$%(,#(&*0$N2*$!2)*'/$!*)D+,'!*#$92*,$%(,!)(& threadA.setMessage("A");
&*'E*#$!2* run()$;?,%!+(,0 threadB.setMessage("B");
threadAButton = new QPushButton(tr("Start A"));
threadBButton = new QPushButton(tr("Start B"));
void Thread::stop() quitButton = new QPushButton(tr("Quit"));
{ quitButton->setDefault(true);
stopped = true; connect(threadAButton, SIGNAL(clicked()),
} this, SLOT(startOrStopThreadA()));
connect(threadBButton, SIGNAL(clicked()),
this, SLOT(startOrStopThreadB()));
...
N2* stop()$;?,%!+(,$#*!#$!2* stopped$E')+'6&*$!( trueA$!2*)*6:$!*&&+,- run()$!($#!(B$B)+,!+,-$!*I!$!(
}
!2*$%(,#(&*0$N2+#$;?,%!+(,$%',$6*$%'&&*/$;)(D$',:$!2)*'/$'!$',:$!+D*0$H()$!2*$B?)B(#*#$(;$!2+#
*I'DB&*A$9*$'##?D*$!2'!$'##+-,D*,!$!($' bool$+#$',$'!(D+%$(B*)'!+(,0$N2+#$+#$'$)*'#(,'6&*
'##?DB!+(,A$%(,#+/*)+,-$!2'!$' bool$%',$(,&:$2'E*$!9($#!'!*#0$G*$9+&&$#**$&'!*)$+,$!2+#$#*%!+(,$2(9
!($?#* QMutex$!($-?')',!**$!2'!$'##+-,+,-$!($'$E')+'6&*$+#$',$'!(D+%$(B*)'!+(,0 >,$!2*$%(,#!)?%!()A$9*$%'&& setMessage()$!($D'F*$!2*$;+)#!$!2)*'/$)*B*'!*/&:$B)+,!$"<"#$',/$!2*$#*%(,/
!2)*'/$"X"#0
QThread$B)(E+/*#$' terminate()$;?,%!+(,$!2'!$!*)D+,'!*#$!2*$*I*%?!+(,$(;$'$!2)*'/$92+&*$+!$+#$#!+&&
)?,,+,-0$.#+,- terminate()$+#$,(!$)*%(DD*,/*/A$#+,%*$+!$%',$#!(B$!2*$!2)*'/$'!$',:$B(+,!$',/$/(*# void ThreadDialog::startOrStopThreadA()
,(!$-+E*$!2*$!2)*'/$',:$%2',%*$!($%&*',$?B$';!*)$+!#*&;0$>!$+#$'&9':#$#';*)$!($?#*$' stopped$E')+'6&* {
',/$' stop()$;?,%!+(,$'#$9*$/+/$2*)*0 if (threadA.isRunning()) {
threadA.stop();
!"#$%&'6)')&78%&78$%.+9&.::;!0.4!5- threadAButton->setText(tr("Start A"));
} else {
threadA.start();
threadAButton->setText(tr("Stop A"));
}
}
G2*,$!2*$?#*)$%&+%F#$!2*$6?!!(,$;()$!2)*'/$<A startOrStopThreadA()$#!(B#$!2*$!2)*'/$+;$+!$9'#
)?,,+,-$',/$#!')!#$+!$(!2*)9+#*0$>!$'&#($?B/'!*#$!2*$6?!!(,"#$!*I!0
void Thread::run()
{
forever {
Synchronizing Threads {
QMutexLocker locker(&mutex);
<$%(DD(,$)*V?+)*D*,!$;()$D?&!+!2)*'/*/$'BB&+%'!+(,#$+#$!2'!$(;$#:,%2)(,+h+,-$#*E*)'&$!2)*'/#0$ ! if (stopped) {
B)(E+/*#$!2*$;(&&(9+,-$#:,%2)(,+h'!+(,$%&'##*#= QMutexA QReadWriteLockA QSemaphoreA$',/ stopped = false;
QWaitCondition0 break;
}
}
N2* QMutex$%&'##$B)(E+/*#$'$D*',#$(;$B)(!*%!+,-$'$E')+'6&*$()$'$B+*%*$(;$%(/*$#($!2'!$(,&:$(,*$!2)*'/ cerr << qPrintable(messageStr);
%',$'%%*##$+!$'!$'$!+D*0$N2*$%&'##$B)(E+/*#$' lock()$;?,%!+(,$!2'!$&(%F#$!2*$D?!*I0$>;$!2*$D?!*I$+# }
?,&(%F*/A$!2*$%?))*,!$!2)*'/$#*+h*#$+!$+DD*/+'!*&:$',/$&(%F#$+!P$(!2*)9+#*A$!2*$%?))*,!$!2)*'/$+# cerr << endl;
6&(%F*/$?,!+&$!2*$!2)*'/$!2'!$2(&/#$!2*$D?!*I$?,&(%F#$+!0$1+!2*)$9':A$92*,$!2*$%'&&$!( lock()$)*!?),#A }
!2*$%?))*,!$!2)*'/$2(&/#$!2*$D?!*I$?,!+&$+!$%'&&# unlock()0$N2* QMutex$%&'##$'&#($B)(E+/*#$' tryLock() void Thread::stop()
;?,%!+(,$!2'!$)*!?),#$+DD*/+'!*&:$+;$!2*$D?!*I$+#$'&)*'/:$&(%F*/0 {
QMutexLocker locker(&mutex);
stopped = true;
H()$*I'DB&*A$&*!"#$#?BB(#*$!2'!$9*$9',!*/$!($B)(!*%!$!2* stopped$E')+'6&*$(;$!2* Thread$%&'##$;)(D
}
!2*$B)*E+(?#$#*%!+(,$9+!2$' QMutex0$G*$9(?&/$!2*,$'//$!2*$;(&&(9+,-$/'!'$D*D6*)$!( Thread=
private: \,*$+##?*$9+!2$?#+,-$D?!*I*#$+#$!2'!$(,&:$(,*$!2)*'/$%',$'%%*##$!2*$#'D*$E')+'6&*$'!$'$!+D*0$>,
... B)(-)'D#$9+!2$&(!#$(;$!2)*'/#$!):+,-$!($)*'/$!2*$#'D*$E')+'6&*$#+D?&!',*(?#&:$K9+!2(?!$D(/+;:$+!LA
QMutex mutex; !2*$D?!*I$%',$6*$'$#*)+(?#$B*);()D',%*$6(!!&*,*%F0$>,$!2*#*$%'#*#A$9*$%',$?#* QReadWriteLockA$'
}; #:,%2)(,+h'!+(,$%&'##$!2'!$'&&(9#$#+D?&!',*(?#$)*'/5(,&:$'%%*##$9+!2(?!$%(DB)(D+#+,-$B*);()D',%*0
>,$!2*$%(,#?D*)A$9*$#!')!$6:$'%V?+)+,-$(,*$`?#*/`$6:!*0$>;$!2*$6?;;*)$%(,!'+,#$,($/'!'$!($)*'/A$!2*
%'&&$!( acquire()$9+&&$6&(%F$?,!+&$!2*$B)(/?%*)$2'#$B)(/?%*/$#(D*0$\,%*$9*$2'E*$'%V?+)*/$!2*$6:!*A
9*$B)+,!$+!$',/$)*&*'#*$!2*$6:!*$'#$`;)**`A$D'F+,-$+!$B(##+6&*$;()$!2*$B)(/?%*)$!($;+&&$+!$9+!2$/'!'
'-'+,0
>,$'//+!+(,$!($%'%2+,-A QTHReadStorage<T>$%',$6*$?#*/$;()$-&(6'&$*))()5#!'!*$E')+'6&*#$K#+D+&')$!(
errnoL$!($*,#?)*$!2'!$D(/+;+%'!+(,#$+,$(,*$!2)*'/$/(,"!$';;*%!$(!2*)$!2)*'/#0
N2*$D'+,$!2)*'/$%',$#!')!$,*9$!2)*'/#$6:$%)*'!+,-$(6C*%!#$(;$' QThread$#?6%&'##A$'#$9*$/+/$+,$!2*
B)*E+(?#$#*%!+(,0$>;$!2*#*$,*9$!2)*'/#$,**/$!($%(DD?,+%'!*$'D(,-$!2*D#*&E*#A$!2*:$%',$?#*
#2')*/$E')+'6&*#$!(-*!2*)$9+!2$D?!*I*#A$)*'/O9)+!*$&(%F#A$#*D'B2()*#A$()$9'+!$%(,/+!+(,#0$X?!$,(,*
(;$!2*#*$!*%2,+V?*#$%',$6*$?#*/$!($%(DD?,+%'!*$9+!2$!2*$D'+,$!2)*'/A$#+,%*$!2*:$9(?&/$&(%F$!2*
*E*,!$&((B$',/$;)**h*$!2*$?#*)$+,!*);'%*0 N($+&&?#!)'!*$2(9$#+-,'&#&(!$%(,,*%!+(,#$'%)(##$!2)*'/#$9()FA$9*$9+&&$)*E+*9$!2*$%(/*$(;$!2*$>D'-*
])($'BB&+%'!+(,A'$6'#+%$+D'-*$B)(%*##+,-$'BB&+%'!+(,$!2'!$'&&(9#$!2*$?#*)$!($)(!'!*A$)*#+h*A$',/
N2*$#(&?!+(,$;()$%(DD?,+%'!+,-$;)(D$'$#*%(,/'):$!2)*'/$!($!2*$D'+,$!2)*'/$+#$!($?#*$#+-,'&#&(! %2',-*$!2*$%(&()$/*B!2$(;$',$+D'-*0$N2*$'BB&+%'!+(,$?#*#$(,*$#*%(,/'):$!2)*'/$!($B*);()D
%(,,*%!+(,#$'%)(##$!2)*'/#0$g()D'&&:A$!2*$#+-,'&#$',/$#&(!#$D*%2',+#D$(B*)'!*#$#:,%2)(,(?#&:A (B*)'!+(,#$(,$+D'-*#$9+!2(?!$&(%F+,-$!2*$*E*,!$&((B0$N2+#$D'F*#$'$#+-,+;+%',!$/+;;*)*,%*$92*,
D*',+,-$!2'!$!2*$#&(!#$%(,,*%!*/$!($'$#+-,'&$')*$+,E(F*/$+DD*/+'!*&:$92*,$!2*$#+-,'&$+#$*D+!!*/A B)(%*##+,-$E*):$&')-*$+D'-*#0$N2*$#*%(,/'):$!2)*'/$2'#$'$&+#!$(;$!'#F#A$()$`!)',#'%!+(,#`A$!(
?#+,-$'$/+)*%!$;?,%!+(,$%'&&0 '%%(DB&+#2$',/$#*,/#$*E*,!#$!($!2*$D'+,$9+,/(9$!($)*B()!$B)(-)*##0
8(9*E*)A$92*,$9*$%(,,*%!$(6C*%!#$!2'!$`&+E*`$+,$/+;;*)*,!$!2)*'/#A$!2*$D*%2',+#D$6*%(D*#
ImageWindow::ImageWindow()
'#:,%2)(,(?#0$KN2+#$6*2'E+()$%',$6*$%2',-*/$!2)(?-2$',$(B!+(,'&$;+;!2$B')'D*!*)$!(
{
QObject::connect()0L$X*2+,/$!2*$#%*,*#A$!2*#*$%(,,*%!+(,#$')*$+DB&*D*,!*/$6:$B(#!+,-$',$*E*,!0 imageLabel = new QLabel;
N2*$#&(!$+#$!2*,$%'&&*/$6:$!2*$*E*,!$&((B$(;$!2*$!2)*'/$+,$92+%2$!2*$)*%*+E*)$(6C*%!$*I+#!#0$X:$/*;'?&!A imageLabel->setBackgroundRole(QPalette::Dark);
' QObject$*I+#!#$+,$!2*$!2)*'/$+,$92+%2$+!$9'#$%)*'!*/P$!2+#$%',$6*$%2',-*/$'!$',:$!+D*$6:$%'&&+,- imageLabel->setAutoFillBackground(true);
QObject::moveToThread()0 imageLabel->setAlignment(Qt::AlignLeft | Qt::AlignTop);
setCentralWidget(imageLabel);
createActions();
!"#$%&'6)3)&78%&</."%&=$5&.::;!0.4!5-
createMenus();
statusBar()->showMessage(tr("Ready"), 2000);
connect(&thread, SIGNAL(transactionStarted(const QString &)),
statusBar(), SLOT(showMessage(const QString &)));
connect(&thread, SIGNAL(finished()),
this, SLOT(allTransactionsDone()));
setCurrentFile("");
}
N2*$+,!*)*#!+,-$B')!$(;$!2* ImageWindow$%(,#!)?%!()$+#$!2*$!9($#+-,'&#&(!$%(,,*%!+(,#0$X(!2$(;$!2*D
+,E(&E*$#+-,'&#$*D+!!*/$6:$!2* transactionThread$(6C*%!A$92+%2$9*$9+&&$%(E*)$+,$'$D(D*,!0
void ImageWindow::flipHorizontally()
{
addTransaction(new FlipTransaction(Qt::Horizontal));
} QMutexLocker locker(&mutex);
transactions.enqueue(transact);
if (!isRunning())
start();
N2* flipHorizontally()$#&(!$%)*'!*#$'$`;&+B`$!)',#'%!+(,$',/$)*-+#!*)#$+!$?#+,-$!2*$B)+E'!*$;?,%!+(, }
addTransaction()0$N2* flipVertically()A resizeImage()A convertTo32Bit()A convertTo8Bit()A$',/
convertTo1Bit()$;?,%!+(,#$')*$#+D+&')0
N2* addTransaction()$;?,%!+(,$'//#$'$!)',#'%!+(,$!($!2*$!)',#'%!+(,$V?*?*$',/$#!')!#$!2*$!)',#'%!+(,
void ImageWindow::addTransaction(Transaction *transact) !2)*'/$+;$+!$+#,"!$'&)*'/:$)?,,+,-0$<&&$'%%*##*#$!($!2* TRansactions$D*D6*)$E')+'6&*$')*$B)(!*%!*/$6:
{ '$D?!*IA$6*%'?#*$!2*$D'+,$!2)*'/$D+-2!$D(/+;:$!2*D$!2)(?-2 addTransaction()$'!$!2*$#'D*$!+D*
thread.addTransaction(transact); '#$!2*$#*%(,/'):$!2)*'/$+#$+!*)'!+,-$(E*) transactions0
openAction->setEnabled(false);
saveAction->setEnabled(false);
saveAsAction->setEnabled(false); void TransactionThread::setImage(const QImage &image)
} {
QMutexLocker locker(&mutex);
currentImage = image;
}
N2* addTransaction()$;?,%!+(,$'//#$'$!)',#'%!+(,$!($!2*$#*%(,/'):$!2)*'/"#$!)',#'%!+(,$V?*?*$',/
QImage TransactionThread::image()
/+#'6&*#$!2*$\B*,A$['E*A$',/$['E*$<#$'%!+(,#$92+&*$!)',#'%!+(,#$')*$6*+,-$B)(%*##*/0 {
QMutexLocker locker(&mutex);
return currentImage;
void ImageWindow::allTransactionsDone() }
{
openAction->setEnabled(true);
saveAction->setEnabled(true);
saveAsAction->setEnabled(true); N2* setImage()$',/ image()$;?,%!+(,#$&*!$!2*$D'+,$!2)*'/$#*!$!2*$+D'-*$(,$92+%2$!($B*);()D$!2*
imageLabel->setPixmap(QPixmap::fromImage(thread.image())); !)',#'%!+(,#$',/$)*!)+*E*$!2*$)*#?&!+,-$+D'-*$(,%*$'&&$!)',#'%!+(,#$')*$/(,*0$<-'+,A$9*$B)(!*%!
setWindowModified(true); '%%*##*#$!($'$D*D6*)$E')+'6&*$?#+,-$'$D?!*I0
statusBar()->showMessage(tr("Ready"), 2000);
}
void TransactionThread::run()
{
N2* allTransactionsDone()$#&(!$+#$%'&&*/$92*,$!2* transactionThread"#$!)',#'%!+(,$V?*?*$6*%(D*# Transaction *transact;
forever {
*DB!:0
mutex.lock();
if (transactions.isEmpty()) {
g(9A$&*!"#$!?),$!($!2* TRansactionThread$%&'##= mutex.unlock();
break;
}
class TransactionThread : public QThread QImage oldImage = currentImage;
{ transact = transactions.dequeue();
Q_OBJECT mutex.unlock();
public: emit transactionStarted(transact->message());
void addTransaction(Transaction *transact); QImage newImage = transact->apply(oldImage);
void setImage(const QImage &image); delete transact;
QImage image(); mutex.lock();
signals: currentImage = newImage;
void transactionStarted(const QString &message); mutex.unlock();
protected: }
void run(); }
private:
QMutex mutex;
QImage currentImage;
N2* run()$;?,%!+(,$-(*#$!2)(?-2$!2*$!)',#'%!+(,$V?*?*$',/$*I*%?!*#$*'%2$!)',#'%!+(,$+,$!?),$6:
QQueue<Transaction *> transactions;
}; %'&&+,- apply()$(,$!2*D0
G2*,$'$!)',#'%!+(,$+#$#!')!*/A$9*$*D+!$!2* transactionStarted()$#+-,'&$9+!2$'$D*##'-*$!($/+#B&':$+,
N2* transactionThread$%&'##$D'+,!'+,#$'$&+#!$(;$!)',#'%!+(,#$!($B)(%*##$',/$*I*%?!*#$!2*D$(,*$';!*) !2*$'BB&+%'!+(,"#$#!'!?#$6')0$G2*,$'&&$!2*$!)',#'%!+(,#$2'E*$;+,+#2*/$B)(%*##+,-A$!2* run()$;?,%!+(,
!2*$(!2*)$+,$!2*$6'%F-)(?,/0 )*!?),#$',/ QThread$*D+!#$!2* finished()$#+-,'&0
!"#$%&'$()$*+')$(,$%-)&."'/$.!)$+(0)%.#$+'$.!)$#.&%1$"' QTHRead::run()2
QImage FlipTransaction::apply(const QImage &image)
{
return image.mirrored(orientation == Qt::Horizontal, • !"#$%&'()*'&("$(+$,$&$+(-.(&/$(&/0$1+(&/1&(%0$1&$+(&/$)2
orientation == Qt::Vertical);
} 34$5)$'))*$.+$*)6).)$& QObject$.!&.$)7"#.#$"'$&$*"44)-)'.$.!-)&*8$5)$9:#.$%&66$.!)$.!-)&*;#&4)
QObject::deleteLater()$4:'%."+'$"'#.)&*8$5!"%!$<+#.#$&$=*)4)--)*$*)6).)=$)>)'.2
void MyThread::run()
{
N2* message()$;?,%!+(,$)*!?),#$!2*$D*##'-*$!($/+#B&':$+,$!2*$#!'!?#$6')$92+&*$!2*$(B*)'!+(,$+#$+, ...
B)(-)*##0$N2+#$;?,%!+(,$+#$%'&&*/$+, transactionThread::run()$92*,$*D+!!+,-$!2* QMetaObject::invokeMethod(label, SLOT(setText(const QString &)),
transactionStarted()$#+-,'&0 Q_ARG(QString, "Hello"));
...
}
O,'&9"%$6"(-&-")#$P&6#+$%&66)*$#!&-)*$6"(-&-")#$+-$OQQ#R$&-)$"'*)<)'*)'.$9+*:6)#$.!&.$&-)$#.+-)*$"'$&
#)<&-&.)$4"6)$+'$*"#1$&'*$%&'$()$&%%)##)*$(,$9:6."<6)$&<<6"%&."+'#2$S-+/-&9#$:#:&66,$#<)%"4,$5!"%!
*,'&9"%$6"(-&-")#$.!),$'))*$&.$6"'1$."9)8$"' 5!"%!$%&#)$.!)$6"(-&-")#$&-)$&:.+9&."%&66,$6+&*)*$5!)'
.!)$&<<6"%&."+'$#.&-.#2$ !"#$&<<-+&%!$:#:&66,$"'>+6>)#$&**"'/$.!)$6"(-&-,$&'*$<+##"(6,$".#$"'%6:*)$<&.!
.+$.!)$&<<6"%&."+'F# .pro$4"6)$&'*$"'%6:*"'/$.!)$-)6)>&'.$!)&*)-#$"'$.!)$#+:-%)$4"6)#2$C+-$)7&9<6)I
LIBS += -ldb_cxx
INCLUDEPATH += /usr/local/BerkeleyDB.4.2/include
!)$&6.)-'&.">)$"#$.+$*,'&9"%&66,$6+&*$.!)$6"(-&-,$5!)'$".$"#$-)H:"-)*8$&'*$.!)'$-)#+6>)$.!)$#,9(+6#
.!&.$5)$5&'.$.+$:#)$4-+9$".2$E.$<-+>"*)#$.!) QLibrary$%6&##$.+$&%!")>)$.!"#$"'$&$<6&.4+-9;"'*)<)'*)'.
9&'')-2$@">)'$.!)$#.)9$+4$&$6"(-&-,F#$'&9)8 QLibrary$#)&-%!)#$.!)$<6&.4+-9F#$#.&'*&-*$6+%&."+'#$4+-
.!)$6"(-&-,$6++1"'/$4+-$&'$&<<-+<-"&.)$4"6)2$C+-$)7&9<6)8$/">)'$.!)$'&9) mimetype8$".$5"66$6++1$4+-
mimetype.dll$+'$B"'*+5#8 mimetype.so$+'$Q"':78$&'* mimetype.dylib$+'$J&%$GT$U2
J+*)-'$@A3$&<<6"%&."+'#$%&'$+4.)'$()$)7.)'*)*$(,$.!)$:#)$+4$<6:/"'#2$V$<6:/"'$"#$&$*,'&9"%$6"(-&-,
.!&.$"9<6)9)'.#$&$<&-."%:6&-$"'.)-4&%)$.+$<-+>"*)$+<."+'&6$)7.-&$4:'%."+'&6".,2$C+-$)7&9<6)8$"'
W!&<.)-$X8$5)$%-)&.)*$&$<6:/"'$.+$"'.)/-&.)$&$%:#.+9$5"*/).$5".! !%&'()*+',$P<2$NNYR2
E.$-)%+/'"K)#$".#$+5'$#).$+4$<6:/"'$"'.)-4&%)#$4+-$>&-"+:#$*+9&"'#8$"'%6:*"'/$"9&/)$4+-9&.#8
*&.&(&#)$*-">)-#8$5"*/).$#.,6)#8$.)7.$)'%+*"'/#8$&'*$&%%)##"("6".,2$ !"#$%!&<.)-F#$4"-#.$#)%."+'
)7<6&"'#$!+5$.+$)7.)'*$E.$5".!$&$E.$<6:/"'2
3.$"#$&6#+$<+##"(6)$.+$%-)&.)$&<<6"%&."+';#<)%"4"%$<6:/"'#$4+-$<&-."%:6&-$E.$&<<6"%&."+'#2$E.$9&1)#
5-"."'/$#:%!$<6:/"'#$)&#,$.!-+:/!$".#$<6:/"'$4-&9)5+-18$5!"%!$&**#$%-&#!$#&4).,$&'*$%+'>)'")'%)$.+
QLibrary2$3'$.!)$6&#.$.5+$#)%."+'#$+4$.!"#$%!&<.)-8$5)$#!+5$!+5$.+$9&1)$&'$&<<6"%&."+'$#:<<+-.
<6:/"'#$&'*$!+5$.+$%-)&.)$&$%:#.+9$<6:/"'$4+-$&'$&<<6"%&."+'2
=,*4-.(;,1'' >1.+,$0(?1'$(;,1''
EV%%)##"(6)D-"*/)S6:/"' EV%%)##"(6)D-"*/)
EV%%)##"(6)S6:/"' EV%%)##"(6)3'.)-4&%)
E3%+'Z'/"')S6:/"' E3%+'Z'/"')
E39&/)3GS6:/"' E39&/)3G[&'*6)-
return CanRead;
E3'<:.W+'.)7.S6:/"' E3'<:.W+'.)7. }
return 0;
ES"%.:-)C+-9&.S6:/"' ?LV }
ETH6O-">)-S6:/"' ETH6O-">)-
ET.,6)S6:/"' ET.,6) !) capabilities()$4:'%."+'$-).:-'#$5!&.$.!)$"9&/)$!&'*6)-$"#$%&<&(6)$+4$*+"'/$5".!$.!)$/">)'
"9&/)$4+-9&.2$ !)-)$&-)$.!-))$%&<&("6".")#$PCanRead8 CanWrite8$&'* CanReadIncrementalR8$&'*$.!)
E )7.W+*)%S6:/"' E )7.W+*)% -).:-'$>&6:)$"#$&$(".5"#)$G]$+4$.!+#)$.!&.$&<<6,2
34$.!)$4+-9&.$"#$=%:-=8$+:-$"9<6)9)'.&."+'$-).:-'# CanRead2$34$'+$4+-9&.$"#$/">)'8$5)$%-)&.)$&$%:-#+-
!&'*6)-$&'*$%!)%1$5!).!)-$".$"#$%&<&(6)$+4$-)&*"'/$.!)$*&.&$4-+9$.!)$/">)'$*)>"%)2$ !) canRead()
+$*)9+'#.-&.)$.!"#8$5)$5"66$"9<6)9)'.$&$<6:/"'$.!&.$%&'$-)&*$9+'+%!-+9)$B"'*+5#$%:-#+-$4"6)# 4:'%."+'$+'6,$<))1#$&.$.!)$*&.&8$#))"'/$"4$".$-)%+/'"K)#$.!)$4"6)8$5".!+:.$%!&'/"'/$.!)$4"6)$<+"'.)-2$V
P.cur$4"6)#R2$ !)#)$4"6)#$%&'$!+6*$#)>)-&6$"9&/)#$+4$.!)$#&9)$%:-#+-$&.$*"44)-)'.$#"K)#2$G'%)$.!) %&<&("6".,$+4$^$9)&'#$.!&.$.!)$4"6)$%&''+.$()$-)&*$+-$5-"..)'$(,$.!"#$!&'*6)-2
%:-#+-$<6:/"'$"#$(:"6.$&'*$"'#.&66)*8$E.$5"66$()$&(6)$.+$-)&* .cur$4"6)#$&'*$&%%)##$"'*">"*:&6$%:-#+-#$P4+-
)7&9<6)8$.!-+:/! QImage8 QImageReader8$+- QMovieR8$&'*$5"66$()$&(6)$.+$5-".)$.!)$%:-#+-#$+:.$"'$&',$+4
QImageIOHandler *CursorPlugin::create(QIODevice *device,
E.F#$+.!)-$"9&/)$4"6)$4+-9&.#8$#:%!$&#$DJS8$\SZ@8$&'*$S?@2$ !)$<6:/"'$%+:6*$&6#+$()$*)<6+,)*$5".!
const QByteArray &format) const
E.$&<<6"%&."+'#$#"'%)$.!),$&:.+9&."%&66,$%!)%1$.!)$#.&'*&-*$6+%&."+'#$4+-$E.$<6:/"'#$&'*$6+&*$&',
{
.!&.$.!),$4"'*2 CursorHandler *handler = new CursorHandler;
handler->setDevice(device);
?)5$"9&/)$4+-9&.$<6:/"'$5-&<<)-#$9:#.$#:(%6&## QImageIOPlugin$&'*$-)"9<6)9)'.$&$4)5$>"-.:&6 handler->setFormat(format);
4:'%."+'#I return handler;
}
!) keys()$4:'%."+'$-).:-'#$&$6"#.$+4$.!)$"9&/)$4+-9&.#$.!)$<6:/"'$#:<<+-.#2$ !) format$<&-&9).)-$+4
.!) capabilities()$&'* create()$4:'%."+'#$%&'$()$&##:9)*$.+$!&>)$&$>&6:)$4-+9$.!&.$6"#.2 V.$.!)$)'*$+4$.!) .cpp$4"6)8$5)$:#)$.!) Q_EXPORT_PLUGIN2()$9&%-+$.+$)'#:-)$.!&.$.!)$<6:/"'$"#
-)%+/'"K)*$(,$E.2$ !)$4"-#.$<&-&9).)-$"#$&'$&-(".-&-,$'&9)$.!&.$5)$5&'.$.+$/">)$.+$.!)$<6:/"'2$ !)
#)%+'*$<&-&9).)-$"#$.!)$<6:/"'$%6&##$'&9)2
QStringList CursorPlugin::keys() const
{ T:(%6&##"'/ QImageIOPlugin$"#$#.-&"/!.4+-5&-*2$ !)$-)&6$5+-1$+4$.!)$<6:/"'$"#$*+')$"'$.!)$!&'*6)-2
return QStringList() << "cur"; 39&/)$4+-9&.$!&'*6)-#$9:#.$#:(%6&## QImageIOHandler$&'*$-)"9<6)9)'.$#+9)$+-$&66$+4$".#$<:(6"%
} 4:'%."+'#2$Q).F#$#.&-.$5".!$.!)$!)&*)-I
CursorHandler::CursorHandler()
{
state = BeforeHeader;
currentImageNo = 0;
numImages = 0;
}
B!)'$.!)$!&'*6)-$"#$%+'#.-:%.)*8 5)$()/"'$(,$#).."'/$".#$#.&.)2$B)$#).$.!)$%:--)'.$%:-#+-$"9&/)
':9()-$.+$.!)$4"-#.$%:-#+-8$(:.$#"'%)$5)$#). numImages$.+$^$".$"#$%6)&-$.!&.$5)$!&>)$'+$"9&/)#$,).2
!)$')7.$4:'%."+'$"#$H:".)$"'>+6>)*8$#+$5)$5"66$-)>")5$".$"'$<")%)#I
bool CursorHandler::canRead() const
{
if (state == BeforeHeader) {
bool CursorHandler::read(QImage *image)
return device()->peek(4) == QByteArray("\0\0\2\0", 4);
{
} else {
readHeaderIfNecessary();
return state != Error;
if (state != BeforeImage)
}
return false;
}
!) read()$4:'%."+'$-)&*#$.!)$*&.&$4+-$5!"%!)>)-$"9&/)$()/"'#$&.$.!)$%:--)'.$*)>"%)$<+"'.)-
!) canRead()$4:'%."+'$%&'$()$%&66)*$&.$&',$."9)$.+$*).)-9"')$5!).!)-$.!)$"9&/)$!&'*6)-$%&'$-)&*
<+#"."+'2$34$.!)$4"6)F#$!)&*)-$"#$-)&*$#:%%)##4:66,8$+-$&4.)-$&'$"9&/)$!&#$())'$-)&*$&'*$.!)$*)>"%)
9+-)$*&.&$4-+9$.!)$*)>"%)2$34$.!)$4:'%."+'$"#$%&66)*$()4+-)$5)$!&>)$-)&*$&',$*&.&8$5!"6)$5)$&-)$#."66
<+"'.)-$"#$&.$.!)$#.&-.$+4$&'+.!)-$"9&/)8$5)$%&'$-)&*$.!)$')7.$"9&/)2
"'$.!) BeforeHeader$#.&.)8$5)$%!)%1$4+-$.!)$<&-."%:6&-$#"/'&.:-)$.!&.$"*)'."4")#$B"'*+5#$%:-#+-$4"6)#2
!) QIODevice::peek()$%&66$-)&*#$.!)$4"-#.$4+:-$(,.)# -)!./0!$%!&'/"'/$.!)$*)>"%)F#$4"6)$<+"'.)-2$34
canRead()$"#$%&66)*$6&.)-$+'8$5)$-).:-' true$:'6)##$&'$)--+-$!&#$+%%:--)*2 quint32 size;
quint32 width;
quint32 height;
int CursorHandler::currentImageNumber() const quint16 numPlanes;
{ quint16 bitsPerPixel;
return currentImageNo; quint32 compression;
} QDataStream in(device());
in.setByteOrder(QDataStream::LittleEndian);
in >> size;
!"#$.-">"&6$4:'%."+'$-).:-'#$.!)$':9()-$+4$.!)$%:-#+-$&.$5!"%!$.!)$*)>"%)$4"6)$<+"'.)-$"#$<+#"."+')*2 if (size != 40) {
enterErrorState();
return false;
G'%)$.!)$!&'*6)-$"#$%+'#.-:%.)*8$".$"#$<+##"(6)$4+-$.!)$:#)-$.+$%&66$&',$+4$".#$<:(6"%$4:'%."+'#8$"'$&', }
+-*)-2$ !"#$"#$&$<+.)'."&6$<-+(6)9$#"'%)$5)$9:#.$&##:9)$.!&.$5)$%&'$+'6,$-)&*$#)-"&66,8$#+$5)$'))* in >> width >> height >> numPlanes >> bitsPerPixel >> compression;
.+$-)&*$.!)$4"6)$!)&*)-$+'%)$()4+-)$*+"'/$&',.!"'/$)6#)2$B)$#+6>)$.!)$<-+(6)9$(,$%&66"'/$.!) height /= 2;
readHeaderIfNecessary()$4:'%."+'$"'$.!+#)$4:'%."+'#$.!&.$*)<)'*$+'$.!)$!)&*)-$!&>"'/$())'$-)&*2 if (numPlanes != 1 || bitsPerPixel != 1 || compression != 0) {
enterErrorState();
return false;
int CursorHandler::imageCount() const }
{ in.skipRawData((size - 20) + 8);
readHeaderIfNecessary();
return numImages;
} B)$%-)&.)$& QDataStream$.+$-)&*$.!)$*)>"%)2$B)$9:#.$#).$.!)$(,.)$+-*)-$.+$9&.%!$.!&.$#<)%"4")*$(,
.!) .cur$4"6)$4+-9&.$#<)%"4"%&."+'2$ !)-)$"#$'+$'))*$.+$#).$& QDataStream$>)-#"+'$':9()-$#"'%)$.!)
4+-9&.$+4$"'.)/)-#$&'*$46+&."'/;<+"'.$':9()-#$*+)#$'+.$>&-,$().5))'$*&.&$#.-)&9$>)-#"+'#2$?)7.8
!"#$4:'%."+'$-).:-'#$.!)$':9()-$+4$"9&/)#$"'$.!)$4"6)2$C+-$&$>&6"*$4"6)$5!)-)$'+$-)&*"'/$)--+-#$!&>) 5)$-)&*$"'$>&-"+:#$".)9#$+4$%:-#+-$!)&*)-$*&.&8$&'*$5)$#1"<$.!)$"--)6)>&'.$<&-.#$+4$.!)$!)&*)-$&'*
+%%:--)*8$".$5"66$-).:-'$&$%+:'.$+4$&.$6)&#.$N2 .!)$_;(,.)$%+6+-$.&(6)$:#"'/ QDataStream::skipRawData()2
B)$9:#.$&%%+:'.$4+-$&66$.!)$4+-9&.F#$"*"+#,'%-&#")#4+-$)7&9<6)8$!&6>"'/$.!)$!)"/!.$()%&:#)$.!) .cur
4+-9&.$/">)# &$!)"/!.$.!&.$"#$.5"%)$&#$!"/!$&#$.!)$&%.:&6$"9&/)F#$!)"/!.2$ !) bitsPerPixel$&'* D6&%18$5!".)8$&'*$.-&'#<&-)'.$<"7)6#$&-)$'+$<-+(6)98$(:.$.!)-)F# '+$5&,$+4$+(.&"'"'/$&'$"'>)-.)*
compression$>&6:)#$&-)$&65&,#$N$&'*$^$"'$&$9+'+%!-+9) .cur$4"6)2$34$5)$!&>)$&',$<-+(6)9#8$5)$%&66 (&%1/-+:'*$<"7)6$:#"'/$&'$V]@D$%+6+-$#<)%"4"%&."+'$5".!+:.$1'+5"'/$.!)$%+6+-$+4$.!)$+-"/"'&6
enterErrorState()$&'*$-).:-' false2 (&%1/-+:'*$<"7)62$V#$&$#:(#.".:.)8$5)$:#)$&$#)9";.-&'#<&-)'.$/-&,$%+6+-$P0x7F7F7F7FR2
G'%)$5)$!&>)$4"'"#!)*$-)&*"'/$.!)$"9&/)8$5)$:<*&.)$.!)$%:--)'.$"9&/)$':9()-$&'*$:<*&.)$.!)
!)$')7.$".)9#$"'$.!)$4"6)$&-)$.5+$(".9&<#8$+')$&'$UG]$9$&'*$.!)$+.!)-$&'$V?O$9$B)$-)&* #.&.)$"4$5)$!&>)$-)&%!)*$.!)$6&#.$"9&/)2$V.$.!)$)'*$+4$.!)$4:'%."+'8$.!)$*)>"%)$5"66$()$<+#"."+')*$&.
.!)#)$"'.+ QBitArray#$-&.!)-$.!&'$"'.+ QBitmap#2$V QBitmap$"#$&$%6&##$*)#"/')*$.+$()$*-&5'$+'$&'* .!)$')7.$"9&/)$+-$&.$.!)$)'*$+4$.!)$4"6)2
<&"'.)*$+';#%-))'8$(:.$5!&.$5)$'))*$!)-)$"#$&$<6&"'$&--&,$+4$(".#2
!"#$%+9<6).)#$.!)$"9<6)9)'.&."+'$+4$.!) CursorHandler$"9&/)$4+-9&.$<6:/"'2$S6:/"'#$4+-$+.!)-
"9&/)$4+-9&.#$5+:6*$4+66+5$.!)$#&9)$<&..)-'8$&6.!+:/!$#+9)$9"/!.$"9<6)9)'.$9+-)$+4$.!)
QImageIOHandler$VS38$"'$<&-."%:6&-$.!)$4:'%."+'#$:#)*$4+-$5-"."'/$"9&/)#2$S6:/"'#$+4$+.!)-$1"'*#8$4+-
)7&9<6)8$.)7.$%+*)%#$+-$*&.&(&#)$*-">)-#8$4+66+5$.!)$#&9)$<&..)-'$+4$!&>"'/$&$<6:/"'$5-&<<)-$.+
<-+>"*)$&$/)')-"%$VS3$.!&.$&<<6"%&."+'#$%&'$:#)8$&'*$&$!&'*6)-$.+$<-+>"*)$.!)$:'*)-6,"'/
4:'%."+'&6".,2
!) .pro$4"6)$"#$*"44)-)'.$4+-$<6:/"'#$.!&'$4+-$&<<6"%&."+'#8$#+$5)$5"66$)'*$5".!$.!&.I
TEMPLATE = lib
CONFIG += plugin
HEADERS = cursorhandler.h \
cursorplugin.h
SOURCES = cursorhandler.cpp \
cursorplugin.cpp
DESTDIR = $(QTDIR)/plugins/imageformats
V'$"'.)-4&%)$%6&##$'+-9&66,$*)%6&-)#$&$>"-.:&6$*)#.-:%.+-8$&$>"-.:&6$4:'%."+'$.!&.$-).:-'#$&
3' loadPlugins()8$5)$&..)9<.$.+$6+&*$&66$.!)$4"6)#$"'$.!)$&<<6"%&."+'F# plugins$*"-)%.+-,2$PG'
QStringList8$&'*$+')$+-$9+-)$+.!)-$>"-.:&6$4:'%."+'#2$ !)$*)#.-:%.+-$"#$.!)-)$<-"9&-"6,$.+$#"6)'%)$.!)
B"'*+5#8$.!)$&<<6"%&."+'F#$)7)%:.&(6)$:#:&66,$6">)#$"'$& debug$+- release$#:(*"-)%.+-,8$#+$5)$9+>)
%+9<"6)-8$5!"%!$9"/!.$+.!)-5"#)$%+9<6&"'$&(+:.$.!)$6&%1$+4$&$>"-.:&6$*)#.-:%.+-$"'$&$%6&##$.!&.$!&#
+')$*"-)%.+-,$:<2$G'$J&%$GT$U8$5)$.&1)$.!)$(:'*6)$*"-)%.+-,$#.-:%.:-)$"'.+$&%%+:'.2R
>"-.:&6$4:'%."+'#2$3'$.!"#$)7&9<6)8$.!) effects()$4:'%."+'$-).:-'#$&$6"#.$+4$.!)$.)7.$)44)%.#$.!)$<6:/"'
%&'$<-+>"*)2$B)$%&'$.!"'1$+4$.!"#$6"#.$&#$&$6"#.$+4$1),#2$Z>)-,$."9)$5)$%&66$+')$+4$.!)$+.!)-$4:'%."+'#8
34$.!)$4"6)$5)$.-,$.+$6+&*$"#$&$E.$<6:/"'$.!&.$:#)#$.!)$#&9)$>)-#"+'$+4$E.$&#$.!)$&<<6"%&."+'8
5)$<&##$+')$+4$.!)#)$1),#$&#$4"-#.$&-/:9)'.8$9&1"'/$".$<+##"(6)$.+$"9<6)9)'.$9:6."<6)$)44)%.#$"'$+')
QPluginLoader::instance()$5"66$-).:-'$& QObject *$.!&.$<+"'.#$.+$&$E.$<6:/"'2$B)$:#)
<6:/"'2
qobject_cast<T>()$.+$%!)%1$5!).!)-$.!)$<6:/"'$"9<6)9)'.#$.!) TextArtInterface2$Z&%!$."9)$.!)$%&#.
"#$#:%%)##4:68$5)$&**$.!)$"'.)-4&%)$.+$.!) TextArtDialogF#$6"#.$+4$"'.)-4&%)#$P+4$.,<)
V.$.!)$)'*8$5)$:#)$.!) Q_DECLARE_INTERFACE()$9&%-+$.+$&##+%"&.)$&'$"*)'."4")-$.+$.!)$"'.)-4&%)2$ !)
QList<TextArtInterface *>R2
"*)'."4")-$'+-9&66,$!&#$4+:-$%+9<+')'.#I$&'$"'>)-.)*$*+9&"'$'&9)$#<)%"4,"'/$.!)$%-)&.+-$+4$.!)
"'.)-4&%)8$.!)$'&9)$+4$.!)$&<<6"%&."+'8$.!)$'&9)$+4$.!)$"'.)-4&%)8$&'*$&$>)-#"+'$':9()-2$B!)')>)-
5)$&6.)-$.!)$"'.)-4&%)$P4+-$)7&9<6)8$(,$&**"'/$&$>"-.:&6$4:'%."+'$+-$%!&'/"'/$.!)$#"/'&.:-)$+4$&' T+9)$&<<6"%&."+'#$9&,$5&'.$.+$6+&*$.5+$+-$9+-)$*"44)-)'.$"'.)-4&%)#8$"'$5!"%!$%&#)$.!)$%+*)$4+-
)7"#."'/$4:'%."+'R8$5)$9:#.$-)9)9()-$.+$"'%-)&#)$.!)$>)-#"+'$':9()-b$+.!)-5"#)8$.!)$&<<6"%&."+' +(.&"'"'/$.!)$"'.)-4&%)#$5+:6*$6++1$9+-)$6"1)$.!&.$#!+5'$()6+5I
9"/!.$%-&#!$.-,"'/$.+$&%%)##$&'$+:.*&.)*$<6:/"'2
QPixmap pixmap(size);
QPainter painter(&pixmap);
Writing Application Plugins painter.setFont(myFont);
painter.setPen(pen);
V'$&<<6"%&."+'$<6:/"'$"#$&$#:(%6&##$+4 QObject$&'*$+4$.!)$"'.)-4&%)#$".$5&'.#$.+$<-+>"*)2$ !)$WO$.!&. painter.setBrush(brush);
&%%+9<&'")#$.!"#$(++1$"'%6:*)#$.5+$<6:/"'#$4+-$.!)$ )7.$V-.$&<<6"%&."+'$<-)#)'.)*$"'$.!)$<-)>"+:# painter.setRenderHint(QPainter::Antialiasing, true);
painter.setRenderHint(QPainter::TextAntialiasing, true);
#)%."+'8$.+$#!+5$.!&.$.!)$&<<6"%&."+'$%+--)%.6,$!&'*6)#$9:6."<6)$<6:/"'#2
painter.setRenderHint(QPainter::SmoothPixmapTransform, true);
painter.eraseRect(pixmap.rect());
[)-)8$5)$5"66$+'6,$-)>")5$.!)$%+*)$4+-$+')$+4$.!)98$.!)$D&#"%$Z44)%.#$S6:/"'2$B)$5"66$&##:9)$.!&.$.!)
<6:/"'F#$#+:-%)$%+*)$"#$6+%&.)*$"'$&$*"-)%.+-,$%&66)* basiceffectsplugin$&'*$.!&.$.!)$ )7.$V-.
&<<6"%&."+'$"#$6+%&.)*$"'$&$<&-&66)6$*"-)%.+-,$%&66)* textart2$[)-)F#$.!)$*)%6&-&."+'$+4$.!)$<6:/"'$%6&##I
B)$%-)&.)$&$<"79&<$+4$.!)$-)H:"-)*$#"K)$&'*$&$<&"'.)-$.+$<&"'.$+'.+$.!)$<"79&<2$B)$&6#+$#).$#+9)
-)'*)-$!"'.#$.+$)'#:-)$.!)$#9++.!)#.$<+##"(6)$-)#:6.#2$ !)$%&66$.+ eraseRect()$%6)&-#$.!)$<"79&<$5".!
.!)$(&%1/-+:'*$%+6+-2
class BasicEffectsPlugin : public QObject, public TextArtInterface
{
Q_OBJECT
Q_INTERFACES(TextArtInterface) if (effect == "Plain") {
public: painter.setPen(Qt::NoPen);
QStringList effects() const; } else if (effect == "Outline") {
QPixmap applyEffect(const QString &effect, const QString &text, QPen pen(Qt::black);
const QFont &font, const QSize &size, pen.setWidthF(2.5);
const QPen &pen, const QBrush &brush); painter.setPen(pen);
}; } else if (effect == "Shadow") {
QPainterPath path;
painter.setBrush(Qt::darkGray);
path.addText(((size.width() - metrics.width(text)) / 2) + 3,
!)$<6:/"'$"9<6)9)'.#$+'6,$+')$"'.)-4&%)8 TextArtInterface2$3'$&**"."+'$.+ Q_OBJECT8$5)$9:#.$:#) (size.height() - metrics.descent()) + 3, myFont,
.!) Q_INTERFACES()$9&%-+$4+-$)&%!$+4$.!)$"'.)-4&%)#$.!&.$&-)$#:(%6&##)*$.+$)'#:-)$#9++.! text);
%++<)-&."+'$().5))' moc$&'* qobject_cast<T>()2 painter.drawPath(path);
painter.setBrush(brush);
}
QStringList BasicEffectsPlugin::effects() const
{
return QStringList() << "Plain" << "Outline" << "Shadow"; C+-$.!)$=S6&"'=$)44)%.8$'+$+:.6"')$"#$-)H:"-)*2$C+-$.!)$=G:.6"')=$)44)%.8$5)$"/'+-)$.!)$+-"/"'&6$<)'$&'*
} %-)&.)$+:-$+5'$(6&%1$<)'$5".!$&$`2X;<"7)6$5"*.!2$C+-$.!)$=T!&*+5=$)44)%.8$5)$'))*$.+$*-&5$.!)
#!&*+5$4"-#.8$#+$.!&.$.!)$.)7.$%&'$()$<&"'.)*$+'$.+<$+4$".2
!) effects()$4:'%."+'$-).:-'#$&$6"#.$+4$.)7.$)44)%.#$#:<<+-.)*$(,$.!)$<6:/"'2$ !"#$<6:/"'$#:<<+-.#
.!-))$)44)%.#8$#+$5)$0:#.$-).:-'$&$6"#.$%+'.&"'"'/$.!)$'&9)$+4$)&%!$+')2 QPainterPath path;
path.addText((size.width() - metrics.width(text)) / 2,
size.height() - metrics.descent(), myFont, text);
!) applyEffect()$4:'%."+'$<-+>"*)#$.!)$<6:/"'F#$4:'%."+'&6".,$&'*$"#$#6"/!.6,$"'>+6>)*8$#+$5)$5"66
painter.drawPath(path);
return pixmap;
} Chapter 20. Platform-Specific Features
• :$"#8;15&$'(*&"+(<1"&=#(3,:/
B)$'+5$!&>)$.!)$<)'$&'*$(-:#!)#$#).$&<<-+<-"&.)6,$4+-$)&%!$.)7.$)44)%.8$&'*$"'$.!)$=T!&*+5=$)44)%.
• >/&$'(35"&=#?(6$(9&$%6*/
%&#)$!&>)$*-&5'$.!)$#!&*+52$B)$&-)$'+5$-)&*,$.+$-)'*)-$.!)$.)7.2$ !)$.)7.$"#$!+-"K+'.&66,$%)'.)-)*
• @1$%-&$'(?AA(B#//&6$(01$1'#C#$"
&'*$*-&5'$4&-$)'+:/!$&(+>)$.!)$(+..+9$+4$.!)$<"79&<$.+$&66+5$-++9$4+-$*)#%)'*)-#2
3'$.!"#$%!&<.)-8$5)$5"66$-)>")5$#+9)$+4$.!)$<6&.4+-9;#<)%"4"%$+<."+'#$&>&"6&(6)$.+$E.$<-+/-&99)-#2
Q_EXPORT_PLUGIN2(basiceffectsplugin, BasicEffectsPlugin) B)$()/"'$(,$6++1"'/$&.$!+5$.+$&%%)##$'&.">)$VS3#$#:%!$&#$.!)$B"'Y`$VS3$+'$B"'*+5#8$W&-(+'$+'
J&%$GT$U8$&'*$U6"($+'$UNN2$B)$.!)'$9+>)$+'$.+$)7<6+-)$.!)$V%.">)E.$)7.)'#"+'8$#!+5"'/$!+5$.+$:#)
V%.">)U$%+'.-+6#$5".!"'$E.LB"'*+5#$&<<6"%&."+'#$&'*$!+5$.+$%-)&.)$&<<6"%&."+'#$.!&.$&%.$&#$V%.">)U
#)->)-#2$3'$.!)$6&#.$#)%."+'8$5)$)7<6&"'$!+5$.+$9&1)$E.$&<<6"%&."+'#$%++<)-&.)$5".!$.!)$#)##"+'
V.$.!)$)'*$+4$.!) .cpp$4"6)8$5)$:#)$.!) Q_EXPORT_PLUGIN2()$9&%-+$.+$9&1)$.!)$<6:/"'$&>&"6&(6)$.+$E.2 9&'&/)-$:'*)-$UNN2
#ifdef Q_WS_MAC
ChangeWindowAttributes(HIViewGetWindow(HIViewRef(toolWin.winId())),
kWindowSideTitlebarAttribute,
kWindowNoAttributes);
#endif
3-4*0$(@I252(C(J1%(!K(F(&::,(L-.+:L(L-&/(&/$(&-&,$("10(:.(&/$('-+$
QPaintEngineF# getdC()$&'* releaseDC()$4:'%."+'#I
J"7"'/ QPainter$&'*$@O3$%&66#$6"1)$.!"#$%&'$#+9)."9)#$6)&*$.+$#.-&'/)$-)#:6.#8$)#<)%"&66,$5!)'
QPainter$%&66#$+%%:-$&4.)-$@O3$%&66#8$()%&:#) QPainter$9&1)#$#+9)$&##:9<."+'# &(+:.$.!)$#.&.)$+4
.!)$:'*)-6,"'/$*-&5"'/$6&,)-2
• Q_OS_AIX
• Q_OS_BSD4
G'$UNN8$!)-)F#$!+5$5)$5+:6*$9+*"4,$&$5"'*+5$<-+<)-.,I • Q_OS_BSDI
• Q_OS_CYGWIN
• Q_OS_DGUX
#ifdef Q_WS_X11 • Q_OS_DYNIX
Atom atom = XInternAtom(QX11Info::display(), "MY_PROPERTY", False); • Q_OS_FREEBSD
long data = 1; • Q_OS_HPUX
XChangeProperty(QX11Info::display(), window->winId(), atom, atom, • Q_OS_HURD
32, PropModeReplace,
• Q_OS_IRIX
reinterpret_cast<uchar *>(&data), 1);
#endif • Q_OS_LINUX
• Q_OS_LYNX
• Q_OS_MAC
• Q_OS_NETBSD
!) #ifdef$&'* #endif$*"-)%.">)#$&-+:'*$.!)$<6&.4+-9;#<)%"4"%$%+*)$)'#:-)$.!&.$.!)$&<<6"%&."+'$5"66
• Q_OS_OPENBSD
#."66$%+9<"6)$+'$+.!)-$<6&.4+-9#2
• Q_OS_OS2EMX
• Q_OS_OSF
C+-$&$B"'*+5#;+'6,$&<<6"%&."+'8$!)-)F#$&'$)7&9<6)$+4$!+5$5)$%&'$:#)$@O3$%&66#$.+$*-&5$+'$&$E.
• Q_OS_QNX6
5"*/).I
• Q_OS_QNX
• Q_OS_RELIANT
void GdiControl::paintEvent(QPaintEvent * /* event */) • Q_OS_SCO
{ • Q_OS_SOLARIS
RECT rect; • Q_OS_ULTRIX
GetClientRect(winId(), &rect); • Q_OS_UNIXWARE
HDC hdc = GetDC(winId()); • Q_OS_WIN32
FillRect(hdc, &rect, HBRUSH(COLOR_WINDOW + 1)); • Q_OS_WIN64
SetTextAlign(hdc, TA_CENTER | TA_BASELINE);
TextOutW(hdc, width() / 2, height() / 2, text.utf16(), text.size());
ReleaseDC(winId(), hdc); B)$%&'$&##:9)$.!&.$&.$9+#.$+')$+4$.!)#)$5"66$()$*)4"')*2$C+-$%+'>)'")'%)8$E.$&6#+$*)4"')# Q_OS_WIN
} 5!)'$)".!)-$B"'Y`$+-$B"'fM$"#$*).)%.)*8$&'* Q_OS_UNIX$5!)'$&',$A'"7;(&#)*$+<)-&."'/$#,#.)9
P"'%6:*"'/$Q"':7$&'*$J&%$GT$UR$"#$*).)%.)*2$V.$-:';."9)8$5)$%&'$%!)%1 QSysInfo::WindowsVersion$+-
QSysInfo:: MacintoshVersion$.+$*"#."'/:"#!$().5))'$*"44)-)'.$>)-#"+'#$+4$B"'*+5#$P`^^^8$JZ8$).%2R
+-$J&%$GT$U$PN^2`8$N^2Y8$).%2R2
C+-$.!"#$.+$5+-18$5)$9:#.$&6#+$-)"9<6)9)'. QPaintDevice::paintEngine()$.+$-).:-'$&$':66$<+"'.)-$&'*
#).$.!) Qt::WA_PaintOnScreen$&..-"(:.)$"'$.!)$5"*/).F#$%+'#.-:%.+-2
3'$&**"."+'$.+$.!)$+<)-&."'/$#,#.)9$&'*$5"'*+5$#,#.)9$9&%-+#8$.!)-)$"#$&6#+$&$#).$+4$%+9<"6)-
9&%-+#2$C+-$)7&9<6)8 Q_CC_MSVC$"#$*)4"')*$"4$.!)$%+9<"6)-$"#$J"%-+#+4.$g"#:&6$Whh2$ !)#)$%&'$()
!)$')7.$)7&9<6)$#!+5#$!+5$.+$%+9("') QPainter$&'*$@O3$%&66#$"'$&$<&"'.$)>)'.$!&'*6)-$:#"'/
:#)4:6$4+-$5+-1"'/$&-+:'*$%+9<"6)-$(:/#2
T)>)-&6$+4$E.F#$@A3;-)6&.)*$%6&##)#$<-+>"*)$<6&.4+-9;#<)%"4"%$4:'%."+'#$.!&.$-).:-'$6+5;6)>)6$!&'*6)#
.+$.!)$:'*)-6,"'/$+(0)%.2$ !)#)$&-)$6"#.)*$"' C"/:-)$`^2`2 G'$UNN8 QPixmap::x11Info()$&'* QWidget::x11Info()$-).:-'$& QX11Info$+(0)%.$.!&.$<-+>"*)#$>&-"+:#
<+"'.)-#$+-$!&'*6)#8$#:%!$&# display()8 screen()8 colormap()8$&'* visual()2$B)$%&'$:#)$.!)#)$.+$#).
3-4*0$(@I2@2(=,1&B:0)M'7$%-B-%(B*.%&-:.'(&:(1%%$''(,:LM,$N$,(/1.+,$' :<$&'$UNN$/-&<!"%#$%+'.)7.$+'$& QPixmap$+- QWidget8$4+-$)7&9<6)2
E.$&<<6"%&."+'#$.!&.$'))*$.+$"'.)-4&%)$5".!$+.!)-$.++61".#$+-$6"(-&-")#$4-)H:)'.6,$'))*$.+$&%%)##$.!)
J&%$GT$U 6+5;6)>)6$)>)'.#$PXEvent#$+'$UNN8 MSG#$+'$B"'*+5#8 Eventref$+'$J&%$GT$U8 QWSEvent#$+'$E.+<"&R
V TC+'.C+-9&.])4 EC+'.II!&'*6)PR ()4+-)$.!),$&-)$%+'>)-.)*$"'.+ QEvent#2$B)$%&'$*+$.!"#$(,$#:(%6&##"'/ QApplication$&'*
-)"9<6)9)'."'/$.!)$-)6)>&'.$<6&.4+-9;#<)%"4"%$)>)'.$4"6.)-8$+')$+4 x11EventFilter()8
W@39&/)])4 ES"79&<II9&%W@[&'*6)PR winEventFilter()8 macEventFilter()8$&'* qwsEventFilter()2$V6.)-'&.">)6,8$5)$%&'$&%%)##$.!)
<6&.4+-9;#<)%"4"%$)>)'.#$.!&.$&-)$#)'.$.+$&$/">)' QWidget$(,$-)"9<6)9)'."'/$+')$+4 x11Event()8
@B+-6*S.- ES"79&<II9&%EOV6<!&[&'*6)PR winEvent()8 macEvent()8$&'* qwsEvent()2$ !"#$%&'$()$:#)4:6$4+-$!&'*6"'/$%)-.&"'$.,<)#$+4$)>)'.#$.!&.
E.$'+-9&66,$"/'+-)#8$#:%!$&#$0+,#."%1$)>)'.#2
@B+-6*S.- ES"79&<II9&%EO[&'*6)PR
]/'[&'*6) E])/"+'II!&'*6)PR C+-$9+-)$"'4+-9&."+'$&(+:.$<6&.4+-9;#<)%"4"%$"##:)#8$"'%6:*"'/$!+5$.+$*)<6+,$E.$&<<6"%&."+'#$+'
*"44)-)'.$<6&.4+-9#8$#)) !..<ILL*+%2.-+66.)%!2%+9LM2NL5"'#,#.)92!.962
[3g")5])4 EB"*/).II5"'3*PR
)07B/2@+6756A02>57;27;0 PlayerWindow2@+6/71A@7+1F
wmp->setProperty("ShowControls", false);
wmp->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
connect(wmp, SIGNAL(PlayStateChange(int, int)),
this, SLOT(onPlayStateChange(int, int))); :1<AC067/27+27;02C07;+32:/2:33575+6:,29:1:C0701/E2T+120K:C9,0F
connect(wmp, SIGNAL(ReadyStateChange(ReadyStateConstants)),
this, SLOT(onReadyStateChange(ReadyStateConstants)));
connect(wmp, SIGNAL(PositionChange(double, double)), wmp->dynamicCall("TitlePlay(uint)", 6);
this, SLOT(onPositionChange(double, double)));
*+,-.'#/0121#34' AxBouncer#5+6,'$#+7#87$'.7'$#9:&;<.'.
CONFIG += qaxcontainer
(602410SA067260032>;06230:,56<2>57;2J(H2+*N0@7/25/27+2*02:*,027+2@:,,2:2J(H2C07;+323510@7,82O:/
+99+/0327+2@+660@756<25727+2:2?72/5<6:,PE2%;020:/50/72>:827+23+27;5/25/27+256=+L0
QAxBase::dynamicCall()2>57;27;026:C02:632/5<6:7A102+427;02C07;+32:/2451/729:1:C07012:6327;0
7;5/2/5<6:7A10E
protected:
void paintEvent(QPaintEvent *event);
void timerEvent(QTimerEvent *event);
private:
int intervalInMilliseconds() const;
QColor ballColor;
SpeedValue ballSpeed;
int ballRadius;
int myTimerId;
int x;
int delta;
};
%;0291+70@7032:632915=:702/0@75+6/2+427;02@,://2:1027;02/:C02:/27;+/02>02>+A,32;:=025427;5/2>:/2:
/7:63:132?72>53<07E
AxBouncer::AxBouncer(QWidget *parent)
: QWidget(parent)
{
ballColor = Qt::blue;
ballSpeed = Normal;
ballRadius = 15;
myTimerId = 0;
x = 20;
delta = 2;
}
G;0623+56<2CA,759,0256;0157:6@0256=+,=56<2: QObjectD3015=032@,://-2>02CA/72:,>:8/29A727;0 QObjectD
3015=032@,://2451/72/+27;:7 moc2@:6295@L2572A9E
%;0 AxBouncer2@+6/71A@7+1256575:,5X0/27;02@,://B/2915=:702=:15:*,0/E
G0230@,:1027;100210:3D>1570291+901750/2:632+60210:3D+6,8291+90178E2%;0 Q_ENUMS()2C:@1+25/
60@0//:1827+270,, moc27;:727;0 SpeedValue2789025/2:6206AC27890E2%;0206AC25/230@,:10325627;029A*,5@
/0@75+62+427;02@,://F void AxBouncer::setColor(const QColor &newColor)
{
if (newColor != ballColor && requestPropertyChange("color")) {
public: ballColor = newColor;
enum SpeedValue { Slow, Normal, Fast }; update();
AxBouncer(QWidget *parent = 0); propertyChanged("color");
void setSpeed(SpeedValue newSpeed); }
SpeedValue speed() const { return ballSpeed; } }
void setRadius(int newRadius);
int radius() const { return ballRadius; }
void setColor(const QColor &newColor); %;0 setColor()24A6@75+62/07/27;02=:,A02+427;0 color291+90178E2#72@:,,/ update()27+2109:56727;02>53<07E
QColor color() const { return ballColor; }
bool isRunning() const { return myTimerId != 0; }
QSize sizeHint() const; %;02A6A/A:,29:1725/27;0 requestPropertyChange()2:63 propertyChanged()2@:,,/E2%;0/024A6@75+6/2:10
QAxAggregated *createAggregate(); 56;015703241+C QAxBindable2:632/;+A,32530:,,82*02@:,,032>;060=012>02@;:6<02:291+90178E2%;0
public slots: requestPropertyChange()2:/L/27;02@,5067B/2901C5//5+627+2@;:6<02:291+90178-2:632107A16/ true25427;0
void start(); @,50672:,,+>/27;02@;:6<0E2%;0 propertyChanged()24A6@75+626+75450/27;02@,506727;:727;0291+901782;:/
void stop(); *0062@;:6<03E
signals:
void bouncing(); %;0 setSpeed()2:63 setRadius()291+901782/07701/2:,/+24+,,+>27;5/29:77016-2:632/+23+27;0 start()2:63
stop()2/,+7/-2/56@027;082@;:6<027;02=:,A02+427;0 running291+90178E
W010B/27;0 .pro245,024+12+A1256D91+@0//2!@75=0M2/01=01F
long ObjectSafetyImpl::queryInterface(const QUuid &iid, void **iface)
{
*iface = 0; TEMPLATE = lib
if (iid == IID_IObjectSafety) { CONFIG += dll qaxserver
*iface = static_cast<IObjectSafety *>(this); HEADERS = axbouncer.h \
} else { objectsafetyimpl.h
return E_NOINTERFACE; SOURCES = axbouncer.cpp \
} main.cpp \
AddRef(); objectsafetyimpl.cpp
return S_OK; RC_FILE = qaxserver.rc
} DEF_FILE = qaxserver.def
#6 main()-2>02@;0@L2>;07;0127;02:99,5@:75+625/2*056<21A62/7:63D:,+602+12:/2:2/01=01E2%;0 -activex
@+CC:63D,5602+975+625/210@+<65X032*8 QApplication2:632C:L0/27;02:99,5@:75+621A62:/2:2/01=01E2#427;0
%;0 AddressBook2>53<0725/27;02:99,5@:75+6B/2C:562>563+>E2%;0291+901782:6327;02/,+7/257291+=530/2>5,,
:99,5@:75+625/6B721A62:/2:2/01=01-2>02@10:7027;02C:562>53<072:632/;+>2572:/2>02>+A,326+1C:,,823+256
*02:=:5,:*,024+12/@159756<E2%;0 Q_CLASSINFO()2C:@1+25/2A/0327+2/90@54827;02@,://2:632567014:@02#R/
:682/7:63D:,+602?72:99,5@:75+6E
://+@5:7032>57;27;02@,://E2%;0/02>0102<0601:7032A/56<2:27++,2/A@;2:/ guid2+1 uuidE
#62:33575+627+ -activex-2!@75=0M2/01=01/2A6301/7:6327;024+,,+>56<2@+CC:63D,5602+975+6/F
#627;02910=5+A/20K:C9,0-2>02/90@5450327;02@,://2:632567014:@02#R/2>;06 >020K9+170327;0 QAxBouncer
@,://2A/56<27;0 QAXFACTORY_DEFAULT()2C:@1+E2#627;5/20K:C9,0-2>02>:6727+20K9+172/0=01:,2@,://0/-2/+
• -regserver210<5/701/27;02/01=0125627;02/8/70C210<5/718E
>02@:66+72A/0 QAXFACTORY_DEFAULT()E %;0102:1027>+2+975+6/2:=:5,:*,027+2A/F
• -unregserver2A610<5/701/27;02/01=01241+C27;02/8/70C210<5/718E
• -dumpidl file2>1570/27;02/01=01B/2#R)27+27;02/90@54503245,0E
• G02@:62/A*@,:// QAxFactory-2105C9,0C067257/2=517A:,24A6@75+6/27+291+=5302564+1C:75+62:*+A7
7;027890/2>02>:6727+20K9+17-2:632A/027;0 QAXFACTORY_EXPORT()2C:@1+27+210<5/70127;024:@7+18E
G;0627;02:99,5@:75+625/21A62:/2:2/01=01-2>02CA/720K9+1727;0 AddressBook2:63 ABItem2@,://0/2:/2J(H
@+C9+6067/F
QAXFACTORY_BEGIN("{2b2b6f3e-86cf-4c49-9df5-80483b47f17b}",
"{8e827b25-148b-4307-ba7d-23f275244818}")
QAXCLASS(AddressBook)
QAXTYPE(ABItem)
QAXFACTORY_END()
%;02:*+=02C:@1+/20K9+172:24:@7+1824+12@10:756<2J(H2+*N0@7/E2Q56@02>02>:6727+20K9+1727>+27890/2+4
J(H2+*N0@7/-2>02@:66+72/5C9,82A/0 QAXFACTORY_DEFAULT()2:/2>0235325627;02910=5+A/20K:C9,0E
%;02451/72:1<AC06727+ QAXFACTORY_BEGIN()25/27;0278902,5*1:182#RU27;02/0@+632:1<AC06725/27;0
:99,5@:75+62#RE2'07>006 QAXFACTORY_BEGIN()2:63 QAXFACTORY_END()-2>02/90@5482:,,27;02@,://0/27;:7
@:62*0256/7:675:7032:632:,,27;023:7:27890/27;:72>02>:6727+2C:L02:@@0//5*,02:/2J(H2+*N0@7/E
%;5/25/27;0 .pro245,024+12+A12+A7D+4D91+@0//2!@75=0M2/01=01F
'0@:A/02+42,5C57:75+6/25620K5/756<2/0//5+62C:6:<01/-2>02CA/7206/A1027;:727;02:99,5@:75+6B/23510@7+18
5/25627;0 PATH206=51+6C0672=:15:*,02542>02>:6727;02:99,5@:75+627+210/7:172@+110@7,8E2#629:175@A,:1-254
8+A2>:6727+27182+A727;02%5@D%:@%+020K:C9,024+128+A1/0,4-28+A2CA/7256/7:,,257256-2/:8- /usr/bin2:63
56=+L02572:/ tictactoeE
W010B/27;0230456575+62+427;0 Application2@,://F
T+12/5C9,02:99,5@:75+6/-256@,A356<2%5@D%:@D%+0-2>02@+A,32/:=027;02/7:702:/2:62:33575+6:,2@+CC:63D
,5602:1<AC06727+27;0210/7:172@+CC:63E2T+120K:C9,0F
class Application : public QApplication
{
Q_OBJECT tictactoe -state OX-XO-X-O
public:
Application(int &argc, char *argv[]);
void setTicTacToe(TicTacToe *tic); %;5/2>+A,32/:=02A/241+C2/7+156<27;023:7:2562:245,02:63291+=5356<2:235/@:132@+CC:6327+210C+=027;0
void saveState(QSessionManager &sessionManager); 45,0E
void commitData(QSessionManager &sessionManager);
private:
TicTacToe *ticTacToe; void Application::commitData(QSessionManager &sessionManager)
}; {
if (ticTacToe->gameInProgress()
&& sessionManager.allowsInteraction()) {
%;0 Application2@,://2L009/2:29+5670127+27;0 TicTacToe2>53<072:/2:2915=:702=:15:*,0E int r = QMessageBox::warning(ticTacToe, tr("Tic-Tac-Toe"),
tr("The game hasn't finished.\n"
"Do you really want to quit?"),
void Application::saveState(QSessionManager &sessionManager) QMessageBox::Yes | QMessageBox::Default,
{ QMessageBox::No | QMessageBox::Escape);
QString fileName = ticTacToe->saveState(); if (r == QMessageBox::Yes) {
QStringList discardCommand; sessionManager.release();
discardCommand << "rm" << fileName; } else {
sessionManager.setDiscardCommand(discardCommand); sessionManager.cancel();
} }
}
}
(62M]]-27;0 saveState()24A6@75+625/2@:,,032>;0627;02/0//5+62C:6:<012>:67/27;02:99,5@:75+627+2/:=0
57/2/7:70E2%;024A6@75+625/2:=:5,:*,0 +62+7;0129,:74+1C/2:/2>0,,-2*A725725/260=012@:,,03E2%;0
%;0 commitData()24A6@75+625/2@:,,032>;0627;02A/012,+</2+A7E2G02@:62105C9,0C06725727+29+92A9 :
QSessionManager29:1:C07012:,,+>/2A/27+2@+CCA65@:702>57;27;02/0//5+62C:6:<01E
C0//:<02*+K2>:1656<27;02A/012:*+A729+70675:,23:7:2,+//E2%;02304:A,725C9,0C067:75+62@,+/0/2:,,27+9D
,0=0,2>53<07/-2>;5@;210/A,7/25627;02/:C02*0;:=5+12:/2>;0627;02A/012@,+/0/27;02>563+>/2+602:4701
G02/7:172*82:/L56<27;0 TicTacToe2>53<0727+2/:=0257/2/7:7027+2:245,0E2%;062>02/0727;02/0//5+6 :6+7;012*82@,5@L56<27;02@,+/02*A77+625627;0512757,02*:1/E2#6 J;:97012`-2>02/:>2;+>27+2105C9,0C067
C:6:<01B/235/@:132@+CC:63E2! 0(-1'*021$..'%025/2:2@+CC:6327;:727;02/0//5+62C:6:<012CA/7 closeEvent()27+2@:7@;27;5/2:6329+92A92:2C0//:<02*+KE
0K0@A7027+230,0702:682/7+1032564+1C:75+6210<:1356<27;02@A110672/7:70E2T+127;5/20K:C9,0-2>02/0725727+
T+127;029A19+/0/2+427;5/20K:C9,0-2>02105C9,0C067 commitData()2:6329+92A92:2C0//:<02*+K2:/L56<
7;02A/0127+2@+6451C27;02,+<2+A7254 :2<:C025/256291+<10//2:6325427;02/0//5+62C:6:<012:,,+>/2A/27+
rm sessionfile
56701:@72>57;27;02A/01E2#427;02A/012@,5@L/2a0/-2>02@:,, release()27+270,,27;02/0//5+62C:6:<0127+
@+6756A02,+<<56<2+A7U25427;02A/012@,5@L/2$+-2>02@:,, cancel()27+2@:6@0,27;02,+<2+A7E
%;02/0//5+62C:6:<012:,/+2;:/2: *)-&'*&21$..'%0E2%;5/25/27;02@+CC:6327;:727;02/0//5+62C:6:<01
board[row][column] = Empty;
}
}
turnNumber = 0;
}
#6 clearBoard()-2>02@,0:12:,,27;02@0,,/2:632/07 turnNumber27+2_E
?7+95:2J+102O910=5+A/,82@:,,032?7\VC*03303P25/2:2=01/5+62+42?72+975C5X0324+120C*033032)56AKE
?7+95:2J+10291+=530/27;02/:C02!I#2:6327++,/2:/27;0230/L7+92=01/5+6/2+42?72O?7\G563+>/-2?7\M]]-
:632?7\H:@P-2:632:33/27;02@,://0/2:6327++,/260@0//:1824+120C*03303291+<1:CC56<E2%;1+A<;23A:,
,5@06/56<-25725/2:=:5,:*,024+12*+7;2+9062/+A1@02:632@+CC01@5:,230=0,+9C067E
?7+95:2J+102@:621A62+62:682;:13>:1027;:721A6/2)56AK2O56@,A356<2#670,2Kcd-2H#IQ-2!"H-2Q71+6<!"H-
H+7+1+,:2dc___-2:632I+>01IJ2:1@;570@7A10/PE2#72;:/2:2C0C+18DC:9903241:C02*A44012:632/A99+17/2:
JZZ2@+C95,01E2.6,5L02?7\M]]-25723+0/26+72600327;02M2G563+>2Q8/70CU256/70:3-25725C9,0C067/257/2+>6
>563+>2/8/70C2O?GQP-206:*,56<2/5<6545@:672/7+1:<02:632C0C+182/:=56</E2%+2103A@0257/2C0C+18
4++79156720=062C+10-2?7+95:2J+102@:62*0210@+C95,0327+20K@,A302A6A/03240:7A10/E2#427;02:99,5@:75+6/
:632@+C9+6067/2A/032+62:230=5@02:102L6+>62562:3=:6@0-27;082@:62*02@+C95,0327+<07;012567+2+60
0K0@A7:*,027;:72,56L/2/7:75@:,,82:<:56/727;02?7+95:2J+102,5*1:150/E
?7+95:2J+102:,/+2*060457/241+C2=:15+A/240:7A10/27;:72:10 :,/+29:172+427;0230/L7+92=01/5+6/2+42?7-
56@,A356<27;020K706/5=02A/02+425C9,5@5723:7:2/;:156<2OY@+982+62>1570YP2:/2:2C0C+18D/:=56<270@;65SA0-
/A99+1724+12@A/7+C2>53<072/78,0/27;1+A<; QStyle-2:632:2,:8+A72/8/70C27;:72:3:97/27+2C:L027;02*0/7
A/02+427;02:=:5,:*,02/@10062/9:@0E
?7+95:2J+1024+1C/27;02*:/5/2+42%1+,,70@;B/20C*033032+440156<-2>;5@;2:,/+256@,A30/2?7+95:2I,:74+1C-
?7+95:2IR!-2:632?7+95:2I;+60E2%;0/0291+=5302@,://0/2:632:99,5@:75+6/230/5<6032/90@545@:,,824+1
9+17:*,0230=5@0/2:632@:62*025670<1:7032>57;2/0=01:,27;513D9:1782[:=:2=517A:,2C:@;560/E
?7+95:2J+10B/2@+645<A1:75+62/8/70C2/A99+17/2@1+//D@+C95,01/-27;1+A<;27;0 configure2/@1597B/ -
embedded2+975+6E2T+120K:C9,0-27+2*A5,324+127;02!"H2:1@;570@7A102>02>+A,327890
G02@:62@10:702@A/7+C2@+645<A1:75+6/2*82:3356<260>245,0/27+2?7B/ mkspecs/qws23510@7+18E
?7+95:2J+10231:>/23510@7,827+27;02)56AK241:C02*A44012O7;02C0C+182:10:2://+@5:7032>57;27;02=530+
35/9,:8PE2%+2:@@0//27;0241:C02*A4401-28+A2C5<;72600327+2<1:672>15702901C5//5+6/27+27;0 /dev/fb0
30=5@0E
%+21A62?7+95:2J+102:99,5@:75+6/-2>02CA/72451/72/7:172+60291+@0//27+2:@72:/2:2/01=01E2%;02/01=0125/
10/9+6/5*,024+12:,,+@:756<2/@1006210<5+6/27+2@,5067/2:6324+12<0601:756<2C+A/02:632L08*+:1320=067/E
!682?7+95:2J+102:99,5@:75+62@:62*0@+C02:2/01=012*82/90@54856< -qws2+6257/2@+CC:632,5602+12*8
9://56< QApplication:: GuiServer2:/27;027;51329:1:C070127+27;0 QApplication2@+6/71A@7+1E src/corelib/qfeatures.txtE
'0@:A/02?IT25/2:21:/70124+1C:7- 5725/24:/7012:632A/A:,,82C+102@+C9:@727;:62=0@7+124+1C:7/2/A@;2:/
Installing Qt/Windows
%%T2:632%8902]2542>0260032572+6,82:72+602+127>+23544010672/5X0/E2%;0 makeqpf27++,2,07/2A/2910D1063012:
%%T2+12:2%8902]245,02:632/:=027;0210/A,72562?IT24+1C:7E2!62:,7016:75=025/27+21A62+A12:99,5@:75+6/2>57; G;0628+A256/01727;02JR2+62:2G563+>/2C:@;560-27;0256/7:,,:75+6291+<1:C2/;+A,32/7:172:A7+C:75@:,,8E
7;0 -savefonts2@+CC:63D,5602+975+6E #427;5/23+0/26+72+@@A1-2A/02T5,02VK9,+10127+26:=5<:7027+27;02JRB/21++724+,3012:6323+A*,0D@,5@L
install.exeE2O%;5/291+<1:C2C:82:990:12:/ install230906356<2+62;+>28+A12/8/70C25/2@+645<A103EP
!727;0275C02+42>15756<-2%1+,,70@;25/230=0,+956<2:62:33575+6:,2,:8012+627+92+42?7+95:2J+1027+2C:L0
0C*033032:99,5@:75+6230=0,+9C06720=0624:/7012:632C+102@+6=065067E2#725/2;+90327;:72:2,:701203575+6 #428+A2:,10:382;:=027;02H56eG2JZZ2@+C95,0128+A2CA/72/90@54827;023510@7+182>;01025725/2,+@:703U
+427;5/2*++L2>5,,256@,A302C+102564+1C:75+62+627;5/27+95@E +7;01>5/0-2/0727;02@;0@L2*+K2:632;:=027;0256/7:,,01256/7:,,2H56eG24+128+AE2%;02eI)2=01/5+62+42?7
/A99,5032+627;02JR2>5,,26+72>+1L2>57;2 5/A:,2JZZ-2/+25428+A23+26+72;:=02H56eG2:,10:38256/7:,,0328+A
>5,,2600327+256/7:,,257E2%;0256/7:,,012:,/+2<5=0/28+A27;02+975+627+256/7:,,27;020K:C9,0/27;:72:@@+C9:68
7;02*++LE2?7B/2/7:63:1320K:C9,0/2:102:A7+C:75@:,,8256/7:,,03-2:,+6<2>57;27;023+@AC067:75+6E
Appendix A. Installing Qt #428+A2@;++/027+256/7:,,27;02H56eG2@+C95,01-27;0102C:82*02:2/C:,,230,:82*07>00627;02@+C9,075+62+4
7;02H56eG256/7:,,:75+62:6327;02/7:172+427;02?7256/7:,,:75+6E
• 5&6."!&.$&7#8!$2#$%
• 9$2"(::#$%&-";<#$*.+2 !4701256/7:,,:75+628+A2>5,,2;:=02:260>24+,30125627;02Q7:172C06A2@:,,032Y?72*82%1+,,70@;2=bE]E]
• 9$2"(::#$%&-";=(8 O+906/+A1@0PYE2%;5/24+,3012;:/2/;+17@A7/27+ &2!--(-&'%&2:63 &27)-(/%)*-2:632:,/+2+602@:,,032Y?7
• 9$2"(::#$%&-";>?? bE]E]2J+CC:632I1+C97Y27;:72/7:17/2:2@+6/+,02>563+>E2G;0628+A2/7:1727;5/2>563+>2572>5,,2/0727;0
06=51+6C0672=:15:*,0/24+12@+C95,56<2?7291+<1:C/2>57;2H56eGE2#725/25627;5/2>563+>27;:728+A2@:621A6
%;5/2:990635K20K9,:56/2;+>27+256/7:,, ?7241+C27;02JR27;:72:@@+C9:650/27;5/2*++L2+67+28+A12/8/70CE qmake2:63 make27+2*A5,32?72:99,5@:75+6/E
%;02JR2;:/203575+6/2+42?72bE]E]24+12G563+>/-2H:@2(Q2M-2:632M]]2O4+12)56AK2:632C+/72=01/5+6/2+4
.65KPE2%;082:,,256@,A302Q?)570-2:29A*,5@23+C:56256D91+@0//23:7:*:/0-27+<07;012>57;2:2Q?)5702315=01E
%;0203575+6/2+42?72+627;02JR2:10291+=530324+128+A12@+6=06506@0E2T+12/015+A/2/+47>:10230=0,+9C067-
5725/2*0/727+23+>6,+:327;02,:70/72=01/5+62+42?7241+C ;779F\\>>>E71+,,70@;E@+C\3+>6,+:3\2+127+2*A82: Installing Qt/Mac
@+CC01@5:,2=01/5+6E
'04+102?72@:62*0256/7:,,032+62H:@2(Q2M-2!99,0B/2M@+302%++,/2CA/72:,10:382*0256/7:,,03E2%;02JR2O+1
%1+,,70@;2:,/+291+=530/2?7+95:2J+1024+12*A5,356<2:99,5@:75+6/24+12)56AKD*:/0320C*03303230=5@0/2/A@; R RP2@+67:5656<27;0/027++,/25/2A/A:,,82/A99,5032>57;2H:@2(Q2MU27;082@:62:,/+2*023+>6,+:303241+C
:/2IR!/2:632C+*5,029;+60/E2#428+A2:102567010/7032562@10:756<20C*033032:99,5@:75+6/-28+A2@:62+*7:56 7;02!99,02R0=0,+9012J+660@75+6- ;779F\\30=0,+901E:99,0E@+CE
?7+95:2J+10241+C2%1+,,70@;B/23+>6,+:32>0*29:<0E
#428+A2;:=02H:@2(Q2M2]_Eb2O%5<01P2:632M@+302%++,/2^EK2O>57;2eJJ2bE_EKP-28+A2@:62A/027;0256/7:,,01
%;020K:C9,02:99,5@:75+6/2A/0325627;02*++L2:102+627;02JR25627;0 examples23510@7+18E2#62:33575+6-2?7 30/@15*032*0,+>E2#428+A2;:=02:620:1,5012=01/5+62+42H:@2(Q2M-2+12:62+,3012=01/5+62+42eJJ-28+A2>5,,
91+=530/2C:682/C:,,20K:C9,02:99,5@:75+6/2,+@:70325627;0 examples2/A*3510@7+18E 600327+256/7:,,27;02/+A1@029:@L:<02C:6A:,,8E2%;5/29:@L:<025/2@:,,03 qt-mac-opensource-4.1.1.tar.gz
:6325/2,+@:70325627;0 mac24+,3012+627;02JRE2#428+A 56/7:,,27;5/29:@L:<0-24+,,+>27;0256/71A@75+6/25627;0
A Note on Licensing 60K72/0@75+624+1256/7:,,56<2?72+62M]]E
%+2A/027;0256/7:,,01-256/01727;02JR2:6323+A*,0D@,5@L27;029:@L:<02@:,,03 Qt.mpkgE2%;5/2>5,,2,:A6@;27;0
?725/291+3A@0325627>+24+1C/F2+9062/+A1@0 :632@+CC01@5:,E2%;02+9062/+A1@0203575+6/2:102:=:5,:*,0
56/7:,,01- Installer.app-2:632?72>5,,2*0256/7:,,032>57;27;02/7:63:1320K:C9,0/-23+@AC067:75+6-2:63
41002+42@;:1<0U27;02@+CC01@5:,203575+6/2CA/72*029:5324+1E
7;020K:C9,0/27;:72:@@+C9:6827;5/2*++LE2?72>5,,2*0256/7:,,03256 /Developer-2>57;27;02*++LB/20K:C9,0/
56 /Developer/Examples/Qt4BookE
%;02/+47>:102+627;02JR25/2/A57:*,024+12@10:756<2:99,5@:75+6/24+128+A12+>6203A@:75+6:,2:632901/+6:,
A/0E
%+21A62@+CC:63/2,5L0 qmake2:63 make-28+A2>5,,2600327+2A/02:2701C56:,2>563+>-24+120K:C9,0-
Terminal.app256 /Applications/UtilitiesE2#725/2:,/+29+//5*,027+2<0601:702M@+30291+N0@7/2A/56< qmakeE
#428+A2>:6727+235/715*A7027;02:99,5@:75+6/27;:728+A2@10:702>57;2:62+9062/+A1@0203575+62+42?7-28+A
CA/72@+C9,82>57;27;02/90@545@2701C/2:632@+63575+6/2,:5323+>625627;02,5@06/0/24+127;02/+47>:1028+A T+120K:C9,0-27+2<0601:702:62M@+30291+N0@724+127;0 hello20K:C9,0-2/7:172:2@+6/+,02/A@;2:/
A/027+2@10:7027;02:99,5@:75+6/E2T+12+9062/+A1@0203575+6/-27;02701C/2:632@+63575+6/256@,A3027;0 Terminal.app-2@;:6<023510@7+1827+ /Developer/Examples/Qt4Book/chap01/hello-2:6320670127;0
10SA510C06727+2A/027;02e$.2e0601:,2IA*,5@2)5@06/02OeI)PE2(9062,5@06/0/2,5L027;02eI)2<5=027;0 4+,,+>56<2@+CC:63F
:99,5@:75+6/B2A/01/2@017:56215<;7/-256@,A356<27;0215<;727+2=50>2:632C+354827;02/+A1@02:6327+235/715*A70
7;02:99,5@:75+6/2O+627;02/:C02701C/PE#428+A2>:6727+235/715*A70 8+A12:99,5@:75+6/2>57;+A72/+A1@02@+30
O7+2L00928+A12@+302915=:70P2+125428+A2>:6727+2:99,828+A12+>62@+CC01@5:,2,5@06/02@+63575+6/27+28+A1 qmake -spec macx-xcode hello.pro
:99,5@:75+6/-28+A2CA/72*A82@+CC01@5:,203575+6/2+427;02/+47>:1028+A2A/027+2@10:7027;02:99,5@:75+6/E
%;02@+CC01@5:,203575+6/2+427;02/+47>:102:,,+>28+A27+2/0,,2:63235/715*A7028+A12:99,5@:75+6/2+628+A1
+>62701C/E
Installing Qt/X11
%+256/7:,,2?7256257/2304:A,72,+@:75+62+62M]]-28+A2>5,,2600327+2*021++7E2#428+A23+26+72;:=021++72:@@0//-
%;02JR2@+67:56/2eI)2=01/5+6/2+42?724+12G563+>/-2H:@2(Q2M-2:632M]]E2%;024A,,2,0<:,270K7/2+427;0
A/0 configureB/ -prefix2:1<AC06727+2/90@5482:23510@7+1827+2>;5@;28+A2;:=02901C5//5+627+2>1570E
,5@06/0/2:10256@,A3032>57;27;029:@L:<0/2+627;02JR-2:,+6<2>57;2564+1C:75+62+62;+>27+2+*7:56
@+CC01@5:,2=01/5+6/E
]E J;:6<023510@7+1827+2:270C9+1:1823510@7+18E T+120K:C9,0F
2.
3. cd /tmp
bE .69:@L27;02:1@;5=0245,0241+C27;02JRF
5.
6. cp /cdrom/x11/qt-x11-opensource-src-4.1.1.tgz .
7.
8.
gunzip qt-x11-opensource-src-4.1.1.tgz
tar xvf qt-x11-opensource-src-4.1.1.tar Appendix B. Introduction to C++ for Java
%;5/2>5,,2@10:7027;023510@7+18 /tmp/qt-x11-opensource-src-4.1.1-2://AC56<27;:728+A12JRD"(H and C# Programmers
5/2C+A67032:7 /cdromE2?7210SA510/2e$. tarU2+62/+C02/8/70C/25725/2@:,,03 gtarE
• !""#$%&'"()"!*&+#",&0@@
gE VK0@A7027;0 configure27++,2>57;28+A129104011032+975+6/27+2*A5,327;02?7 ,5*1:182:6327;027++,/ • =(#$&7($%1(%!&A#BB!)!$8!2
/A99,5032>57;257F • C,!&'"($*()*&0@@&7#D)()E
10.
11. cd /tmp/qt-x11-opensource-src-4.1.1 !"#$%&&'()"*$&+,-")'#$%$#!,+.$"(.+,)/0.",($.,$122$3,+$)'-'4,&'+#$5!,$%4+'%)6$7(,5$8%-%$,+$19:$;.
12. ./configure %##/<'#$.!%.$6,/$%+'$3%<"4"%+$5".!$,=>'0.?,+"'(.')$0,(0'&.#$#/0!$%#$"(!'+".%(0'$%()$&,46<,+&!"#<
%()$5%(.$.,$4'%+($122:$ ,$%-,")$<%7"(@$.!"#$=,,7$%($/(5"'4)6$ABCDD$&%@'$),,+#.,&$=6$"(04/)"(@$%
a+A2@:621A6 ./configure -help27+2<072:2,5/72+42@+645<A1:75+62+975+6/E 0,<&4'.'$122$&+"<'+B$.!"#$%&&'()"*$0,(3"('#$".#'43$.,$'##'(."%4#:$;.$&+'#'(.#$.!'$=%#"0$7(,54')@'
%()$.'0!("E/'#$('0'##%+6$.,$/()'+#.%()$.!'$&+,@+%<#$&+'#'(.')$"($.!'$+'#.$,3$.!'$=,,7B$5".!
]`E %+2*A5,32?7-27890 '(,/@!$"(3,+<%.",($.,$#.%+.$)'-'4,&"(@$0+,##?&4%.3,+<$122$FG;$%&&4"0%.",(#$/#"(@$H.:
14.
15. make I.$.!'$."<'$,3$5+"."(@B$122$"#$.!'$,(46$+'%4"#."0$,&.",($3,+$5+"."(@$0+,##?&4%.3,+<B$!"@!?&'+3,+<%(0'
,=>'0.?,+"'(.')$FG;$%&&4"0%.",(#:$;.#$)'.+%0.,+#$/#/%446$&,"(.$,/.$.!%.$8%-%$,+$19B$5!"0!$)+,&&')$1
%;5/2>5,,2@10:7027;02,5*1:182:632@+C95,02:,,27;0230C+/-20K:C9,0/-2:6327++,/E (62/+C02/8/70C/ 0,<&%."="4".6B$%+'$("0'+$.,$/#'J$"($3%0.B$K>%+('$L.+,/#.+/&B$.!'$"(-'(.,+$,3$122B$(,.')$"( !"#$"%&'(
make25/2@:,,03 gmakeE )(*#+,-./0&-(#-1#233$.!%.$M5".!"($122B$.!'+'$"#$%$</0!$#<%44'+$%()$04'%('+$4%(@/%@'$#.+/@@4"(@
.,$@'.$,/.M:
]dE %+256/7:,,2?7-27890
17. N,+./(%.'46B$5!'($5'$&+,@+%<$5".!$H.B$5'$/#/%446$#."07$.,$%$#/=#'.$,3$122$.!%.$"#$-'+6$04,#'$.,$.!'
18. su -c "make install" /.,&"%($4%(@/%@'$'(-"#",(')$=6$L.+,/#.+/&B$4'%-"(@$/#$3+''$.,$0,(0'(.+%.'$,($.!'$&+,=4'<$%.$!%():
N/+.!'+<,+'B$H.$'*.'()#$122$"($#'-'+%4$+'#&'0.#B$.!+,/@!$".#$"((,-%."-'$M#"@(%4#$%()$#4,.#M
:6320670127;021++729://>+13E2%;5/2>5,,256/7:,,2?72567+ /usr/local/Troll-tech/Qt-4.1.1E2a+A2@:6 <'0!%("#<B$".#$G("0,)'$#/&&,+.B$%()$".# foreach$7'65,+):
@;:6<027;0230/756:75+62*82A/56<27;0 -prefix2+975+62>57; configure-2:6325428+A2;:=02>1570
:@@0//27+27;0230/756:75+628+A2@:62/5C9,827890F ;($.!'$3"+#.$#'0.",($,3$.!"#$%&&'()"*B$5'$5"44$#''$!,5$.,$0,<="('$122$#,/+0'$3"4'#$.,$,=.%"($%(
'*'0/.%=4'$&+,@+%<:$ !"#$5"44$4'%)$/#$.,$'*&4,+'$0,+'$122$0,(0'&.#$#/0!$%#$0,<&"4%.",($/(".#B
!'%)'+$3"4'#B$,=>'0.$3"4'#B$4"=+%+"'#%()$.,$@'.$3%<"4"%+$5".!$.!'$122$&+'&+,0'##,+B$0,<&"4'+B$%()
make install 4"(7'+:
!"#$"#$5!'+'$H.$#%-'#$.!'$)%6:$H.$='@%($%#$%$0+,##?&4%.3,+<$FG;$.,,47".$V%$#'.$,3$04%##'#$.!%.
#428+A2:102A/56<2:2@+C95,0127;:723+0/26+72/A99+17 rpath28+A2CA/72:,/+20K706327;0
<%7'#$".$&,##"=4'$.,$5+".'$&,+.%=4'$@+%&!"0%4$/#'+$"(.'+3%0'$%&&4"0%.",(#W$=/.$+%&")46$'-,4-')$"(.,$%
LD_LIBRARY_PATH206=51+6C0672=:15:*,027+256@,A30 /usr/local/Trolltech/Qt-4.1.1/libE2%;5/25/
3/44?=4,5($3+%<'5,+7$.!%.$&%+.46$'*.'()#$%()$&%+.46$+'&4%0'#$.!'$L.%()%+)$122$4"=+%+6:$I4.!,/@!
6+7260@0//:182+62)56AK2>57;2eJJE
.!"#$=,,7$/#'#$H.B$".$"#$/#'3/4$.,$7(,5$5!%.$.!'$L.%()%+)$122$4"=+%+6$!%#$.,$,33'+B$#"(0'$6,/$<%6
!%-'$.,$5,+7$5".!$0,)'$.!%.$/#'#$".:
?72@+C0/2>57;2:230C+2:99,5@:75+6- qtdemo-27;:72/;+>/2+442C:682+427;0 ,5*1:18B/240:7A10/E2#72/01=0/2:/
:265@02/7:1756<29+56727+2/002>;:72?72@:623+E2%+2/002?7B/23+@AC067:75+6-2057;012=5/57
;779F\\3+@E71+,,70@;E@+C-2+121A6 &2!--(-&'%&-2?7B/2;0,92:99,5@:75+6-256=+L032*8278956< assistant256 Getting Started with C++
:2@+6/+,02>563+>E
I$122$&+,@+%<$0,(#"#.#$,3$,('$,+$<,+' 4-56&.)0&-(#/(&0%:$X%0!$0,<&"4%.",($/(".$"#$%$#'&%+%.'
#,/+0'$0,)'$3"4'B$.6&"0%446$5".!$% .cpp$'*.'(#",($V,.!'+$0,<<,($'*.'(#",(#$%+' .cc$%() .cxxW$.!%. 14 }
.!'$0,<&"4'+$&+,0'##'#$"($,('$+/(:$N,+$'%0!$0,<&"4%.",($/(".B$.!'$0,<&"4'+$@'('+%.'#$%( -78"40#1&."B
5".!$.!'$'*.'(#",( .obj V,($Y"(),5#W$,+ .o$V,($G("*$%()$S%0$ZL$RW:$ !'$,=>'0.$3"4'$"#$%$="(%+6$3"4'
.!%.$0,(.%"(#$<%0!"('$0,)'$3,+$.!'$%+0!".'0./+'$,($5!"0!$.!'$&+,@+%<$5"44$+/(: !' main.cpp$#,/+0'$3"4'$0,(.%"(#$.!' main()$3/(0.",(U#$)'3"(".",(:$;($122B$.!"#$3/(0.",($.%7'#$%( int
%()$% char *$%++%6$V%($%++%6$,3$0!%+%0.'+$#.+"(@#W$%#$&%+%<'.'+#:$ !'$&+,@+%<U#$(%<'$"#$%-%"4%=4'
Z(0'$%44$.!' .cpp$3"4'#$!%-'$=''($0,<&"4')B$5'$0%($0,<="('$.!'$,=>'0.$3"4'#$.,@'.!'+$.,$0+'%.'$%( %# argv[0]$%()$.!'$0,<<%()?4"('$%+@/<'(.#$%# argv[1]B argv[2]B$\B argv[argc - 1]:$ !'$&%+%<'.'+
'*'0/.%=4'$/#"(@$%$#&'0"%4$&+,@+%<$0%44')$.!' .&(9"::$ !'$4"(7'+$0,(0%.'(%.'#$.!'$,=>'0.$3"4'#$%() (%<'# argc$VM%+@/<'(.$0,/(.MW$%() argv$VM%+@/<'(.$-%4/'#MW$%+'$0,(-'(.",(%4:$;3$.!'$&+,@+%<
+'#,4-'#$.!'$<'<,+6$%))+'##'#$,3$3/(0.",(#$%()$,.!'+$#6<=,4#$+'3'+'(0')$"($.!'$0,<&"4%.",($/(".#: ),'#(U.$%00'##$.!'$0,<<%()?4"('$%+@/<'(.#B$5'$0%($)'3"(' main()$5".!$(,$&%+%<'.'+#:
!'$)'04%+%.",($,($4"('$^$"#$% 1/(40&-(#6:-0-0;6":$;.$.'44#$.!'$0,<&"4'+$.!%.$%$3/(0.",($'*"#.#$5".!
Y!'($=/"4)"(@$%$&+,@+%<B$'*%0.46$,('$0,<&"4%.",($/(".$</#.$0,(.%"($% main()$3/(0.",($.!%.$#'+-'#$%# .!'$@"-'($&%+%<'.'+#$%()$+'./+($-%4/':$ !'$%0./%4$3/(0.",($0%($='$4,0%.')$"($.!'$#%<'$0,<&"4%.",(
.!'$&+,@+%<U#$'(.+6$&,"(.:$ !"#$3/(0.",($),'#(U.$='4,(@$.,$%(6$04%##J$".$"#$% '.-7).#1/(40&-(: /(".$,+$"($%(,.!'+$0,<&"4%.",($/(".:$Y".!,/.$.!'$3/(0.",($&+,.,.6&'B$.!'$0,<&"4'+$5,/4)(U. 4'.$/#$0%44
.!'$3/(0.",($,($4"('$A]:$_%+%<'.'+$(%<'#$"($3/(0.",($&+,.,.6&'#$%+'$,&.",(%4:
G(4"7'$8%-%B$5!'+'$'%0!$#,/+0'$3"4'$</#.$0,(.%"($'*%0.46$,('$04%##B$122$4'.#$/#$,+@%("Q'$.!'
0,<&"4%.",($/(".#$%#$5'$5%(.:$Y'$0%($"<&4'<'(.$#'-'+%4$04%##'#$"($.!'$#%<' .cpp$3"4'B$,+$#&+'%)$.!' !'$&+,0')/+'$.,$0,<&"4'$.!'$&+,@+%<$-%+"'#$3+,<$&4%.3,+<$.,$&4%.3,+<:$N,+$'*%<&4'B$.,$0,<&"4'$,(
"<&4'<'(.%.",($,3$%$04%##$%0+,##$#'-'+%4 .cpp$3"4'#B$%()$5'$0%($@"-'$.!'$#,/+0'$3"4'#$%(6$(%<'#$5' L,4%+"#$5".!$.!'$L/($122$0,<&"4'+B$5'$5,/4)$.6&'$.!'$3,44,5"(@$0,<<%()#O
4"7':$Y!'($5'$<%7'$%$0!%(@'$"($,('$&%+."0/4%+ .cpp$3"4'B$5'$,(46$('')$.,$+'0,<&"4'$.!%.$3"4'$%()
.!'($+'4"(7$.!'$%&&4"0%.",($.,$0+'%.'$%$('5$'*'0/.%=4':
CC -c main.cpp
K'3,+'$5'$@,$3/+.!'+B$4'.U#$E/"0746$+'-"'5$.!'$#,/+0'$0,)'$,3$%$.+"-"%4$122$&+,@+%<$.!%.$0,<&/.'# CC -c square.cpp
ld main.o square.o -o square
.!'$#E/%+'$,3$%($"(.'@'+:$ !'$&+,@+%<$0,(#"#.#$,3$.5,$0,<&"4%.",($/(".#O main.cpp$%() square.cpp:
['+'U# square.cppO
!'$3"+#.$.5,$4"('#$"(-,7'$.!'$0,<&"4'+$.,$@'('+%.' .o$3"4'#$3,+$.!' .cpp$3"4'#:$ !'$.!"+)$4"('$"(-,7'#
.!'$4"(7'+$%()$@'('+%.'#$%($'*'0/.%=4'$0%44') squareB$5!"0!$5'$0%($"(-,7'$%#$3,44,5#O
1 double square(double n)
2 {
3 return n * n; ./square 64
4 }
!'$&+,@+%<$,/.&/.#$.!'$3,44,5"(@$<'##%@'$.,$.!'$0,(#,4'O
!"#$3"4'$#"<&46$0,(.%"(#$%$@4,=%4$3/(0.",($0%44') square()$.!%.$+'./+(#$.!'$#E/%+'$,3$".#$&%+%<'.'+:
• <0)0&4#.&7:):&"%$%+'$&/.$)"+'0.46$"(.,$.!'$'*'0/.%=4'B$%#$"3$.!'6$5'+'$,=>'0.$3"4'#:$ !"#$'(#/+'#
!' bool$.6&'$0%($.%7'$.!'$-%4/'# true$%() false:$;($%))".",(B$(/<'+"0$.6&'#$0%($='$/#')$5!'+'$%
.!%.$.!'$4"=+%+6$0%((,.$@'.$4,#.$=/.$"(0+'%#'#$.!'$#"Q'$,3$.!'$'*'0/.%=4':
bool$"#$'*&'0.')B$5".!$.!'$+/4'$.!%.$D$<'%(# false$%()$%(6$(,(?Q'+,$-%4/'$<'%(# TRue:
• $;()5&4#.&7:):&"%$V%4#,$0%44')$#!%+')$4"=+%+"'#$,+$aTT#W$%+'$4,0%.')$%.$%$#.%()%+)$4,0%.",(
,($.!'$/#'+U#$<%0!"('$%()$%+'$%/.,<%."0%446$4,%)')$%.$%&&4"0%.",($#.%+./&:
!' char$.6&'$"#$/#')$=,.!$3,+$#.,+"(@$IL1;;$0!%+%0.'+#$%()$d?=".$"(.'@'+#$V=6.'#W:$Y!'($/#')$%#$%(
N,+$.!' square$&+,@+%<B$5'$4"(7$%@%"(#. .!'$L.%()%+)$122$4"=+%+6B$5!"0!$"#$"<&4'<'(.')$%#$% "(.'@'+B$".$0%($='$#"@(')$,+$/(#"@(')B$)'&'()"(@$,($.!'$&4%.3,+<:$ !'$.6&'# signed char$%()
unsigned char$%+'$%-%"4%=4'$%#$/(%<="@/,/#$%4.'+(%."-'#$., char:$H.$&+,-")'#$% QChar$.6&'$.!%. setY()W:
#.,+'#$Ac?=".$G("0,)'$0!%+%0.'+#:
!'$3/(0.",(#$%=,-'$5'+'$"<&4'<'(.')$"(4"('B$%#$&%+.$,3$.!'$04%##$)'3"(".",(:$I($%4.'+(%."-'$"#$.,
;(#.%(0'#$,3$=/"4.?"($.6&'#$%+'$(,.$"("."%4"Q')$=6$)'3%/4.:$Y!'($5'$0+'%.'$%( int$-%+"%=4'B$".#$-%4/' &+,-")'$,(46$3/(0.",($&+,.,.6&'#$"($.!'$!'%)'+$3"4'$%()$.,$"<&4'<'(.$.!'$3/(0.",(#$"($% .cpp$3"4':
0,/4)$0,(0'"-%=46$='$DB$=/.$0,/4)$>/#.$%#$4"7'46$=' ?]DhB^dcBCAC:$N,+./(%.'46B$<,#.$0,<&"4'+#$5%+( G#"(@$.!"#$%&&+,%0!B$.!'$!'%)'+$3"4'$5,/4)$4,,7$4"7'$.!"#O
/#$5!'($5'$%..'<&.$.,$+'%)$.!'$0,(.'(.#$,3$%($/("("."%4"Q')$-%+"%=4'B$%()$5'$0%($/#'$.,,4#$4"7'
i%.",(%4$_/+"36_4/#$%()$j%4@+"()$.,$)'.'0.$/("."%4"Q')$<'<,+6$%00'##'#$%()$,.!'+$<'<,+6?+'4%.')
&+,=4'<#$%.$+/(?."<': #ifndef POINT2D_H
#define POINT2D_H
;($<'<,+6B$.!'$(/<'+"0$.6&'#$V'*0'&. longW$!%-'$")'(."0%4$#"Q'#$,($.!'$)"33'+'(.$&4%.3,+<# class Point2D
{
#/&&,+.')$=6$H.B$=/.$.!'"+$+'&+'#'(.%.",($-%+"'#$)'&'()"(@$,($.!'$#6#.'<U#$=6.'$,+)'+:$Z($="@?
public:
'()"%($%+0!".'0./+'#$V#/0!$%#$_,5'+_1$%()$L_Ii1WB$.!'$P]?=".$-%4/' 0x12345678$"#$#.,+')$%#$.!'$3,/+ Point2D();
=6.'# 0x12 0x34 0x56 0x78B$5!'+'%#$,($4"..4'?'()"%($%+0!".'0./+'#$V#/0!$%#$;(.'4$*dcWB$.!'$=6.' Point2D(double x, double y);
#'E/'(0'$"#$+'-'+#'):$ !"#$<%7'#$%$)"33'+'(0'$"($&+,@+%<#$.!%.$0,&6$<'<,+6$%+'%#$,(.,$)"#7$,+ void setX(double x);
.!%.$#'()$="(%+6$)%.%$,-'+$.!'$('.5,+7:$H.U# QDataStream$04%##B$&+'#'(.')$"( 1!%&.'+$A] void setY(double y);
V;(&/.`Z/.&/.WB$0%($='$/#')$.,$#.,+'$="(%+6$)%.%$"($%$&4%.3,+<?"()'&'()'(.$5%6: double x() const;
double y() const;
private:
Class Definitions double xVal;
double yVal;
14%##$)'3"(".",(#$"($122$%+'$#"<"4%+$.,$.!,#'$"($8%-%$%()$19B$=/.$.!'+'$%+'$#'-'+%4$)"33'+'(0'#$.,$=' };
%5%+'$,3:$Y'$5"44$#./)6$.!'#'$)"33'+'(0'#$/#"(@$%$#'+"'#$,3$'*%<&4'#:$T'.U#$#.%+.$5".!$%$04%##$.!%. #endif
+'&+'#'(.$%($V@A#;W$0,,+)"(%.'$&%"+O
!'$3/(0.",(#$5,/4)$.!'($='$"<&4'<'(.')$"( point2d.cppO
#ifndef POINT2D_H
#define POINT2D_H
class Point2D
{ #include "point2d.h"
public: Point2D::Point2D()
Point2D() { {
xVal = 0; xVal = 0.0;
yVal = 0; yVal = 0.0;
} }
Point2D(double x, double y) { Point2D::Point2D(double x, double y)
xVal = x; {
yVal = y; xVal = x;
} yVal = y;
void setX(double x) { xVal = x; } }
void setY(double y) { yVal = y; } void Point2D::setX(double x)
double x() const { return xVal; } {
double y() const { return yVal; } xVal = x;
private: }
double xVal; void Point2D::setY(double y)
double yVal; {
}; yVal = y;
#endif }
double Point2D::x() const
{
return xVal;
!'$%=,-'$04%##$)'3"(".",($5,/4)$%&&'%+$"($%$!'%)'+$3"4'B$.6&"0%446$0%44') point2d.h:$ !'$'*%<&4' }
'*!"=".#$.!'$3,44,5"(@$122$")",#6(0+%#"'#O double Point2D::y() const
{
• I$04%##$)'3"(".",($"#$)"-")')$"($&/=4"0B$&+,.'0.')B$%()$&+"-%.'$#'0.",(#B$%()$'()#$5".!$% return yVal;
}
#'<"0,4,(:$;3$(,$#'0.",($"#$#&'0"3"')B$.!'$)'3%/4.$"#$&+"-%.':$VN,+$0,<&%."="4".6$5".!$1B$122
&+,-")'#$% struct$7'65,+)$.!%.$"#$")'(."0%4$., class$'*0'&.$.!%.$.!'$)'3%/4.$"#$&/=4"0$"3$(,
#'0.",($"#$#&'0"3"'):W
• !'$04%##$!%#$.5,$0,(#.+/0.,+#$V,('$.!%.$!%#$(,$&%+%<'.'+#$%()$,('$.!%.$!%#$.5,W:$;3$5' Y'$#.%+.$=6$"(04/)"(@ point2d.h$='0%/#'$.!'$0,<&"4'+$('')#$.!'$04%##$)'3"(".",($='3,+'$".$0%($&%+#'
)'04%+')$(,$0,(#.+/0.,+B$122$5,/4)$%/.,<%."0%446$#/&&46$,('$5".!$(,$&%+%<'.'+#$%()$%( <'<='+$3/(0.",($"<&4'<'(.%.",(#:$ !'($5'$"<&4'<'(.$.!'$3/(0.",(#B$&+'3"*"(@$.!'$3/(0.",($(%<'
'<&.6$=,)6: 5".!$.!'$04%##$(%<'$/#"(@$.!' ::$,&'+%.,+:
• !'$@'..'+$3/(0.",(# x()$%() y()$%+'$)'04%+')$.,$='$0,(#.:$ !"#$<'%(#$.!%.$.!'6$),(U.$V%()
0%(U.W$<,)"36$.!'$<'<='+$-%+"%=4'#$,+$0%44$(,(?0,(#.$<'<='+$3/(0.",(#$V#/0!$%# setX()$%() Y'$!%-'$#''($!,5$.,$"<&4'<'(.$%$3/(0.",($"(4"('$%()$(,5$!,5$.,$"<&4'<'(.$".$"($% .cpp$3"4':$ !'
.5,$%&&+,%0!'#$%+'$#'<%(."0%446$'E/"-%4'(.B$=/.$5!'($5'$0%44$%$3/(0.",($.!%.$"#$)'04%+')$"(4"('B$<,#.
0,<&"4'+#$#"<&46$'*&%()$.!'$3/(0.",(U#$=,)6$"(#.'%)$,3$@'('+%."(@$%($%0./%4$3/(0.",($0%44:$ !"# %$04%##$5".!$,(46$&/+'$-"+./%4$3/(0.",(#$"($122:
(,+<%446$4'%)#$.,$3%#.'+$0,)'B$=/.$<"@!.$"(0+'%#'$.!'$#"Q'$,3$6,/+$%&&4"0%.",(:$N,+$.!"#$+'%#,(B$,(46
-'+6$#!,+.$3/(0.",(#$#!,/4)$='$"<&4'<'(.')$"(4"('J$4,(@'+$3/(0.",(#$#!,/4)$%45%6#$='$"<&4'<'(.') ['+'U#$.!'$)'3"(".",($,3$.!' Circle$#/=04%##O
"($% .cpp$3"4':$;($%))".",(B$"3$5'$3,+@'.$.,$"<&4'<'(.$%$3/(0.",($%()$.+6$.,$0%44$".B$.!'$4"(7'+$5"44
0,<&4%"($%=,/.$%($/(+'#,4-')$#6<=,4:
#ifndef CIRCLE_H
k,5B$4'.U#$.+6$.,$/#'$.!'$04%##: #define CIRCLE_H
#include "shape.h"
class Circle : public Shape
#include "point2d.h" {
int main() public:
{ Circle(Point2D center, double radius = 0.5)
Point2D alpha; : Shape(center) {
Point2D beta(0.666, 0.875); myRadius = radius;
alpha.setX(beta.y()); }
beta.setY(alpha.x()); void draw() {
return 0; // do something here
} }
private:
double myRadius;
};
;($122B$-%+"%=4'#$,3$%(6$.6&'#$0%($='$)'04%+')$)"+'0.46$5".!,/.$/#"(@ new:$ !'$3"+#.$-%+"%=4'$"# #endif
"("."%4"Q')$/#"(@$.!'$)'3%/4. Point2D$0,(#.+/0.,+$V.!'$0,(#.+/0.,+$.!%.$!%#$(,$&%+%<'.'+#W:$ !'
#'0,()$-%+"%=4'$"#$"("."%4"Q')$/#"(@$.!'$#'0,()$0,(#.+/0.,+:$I00'##$.,$%($,=>'0.U#$<'<='+$"#
&'+3,+<')$/#"(@$.!' .$V),.W$,&'+%.,+: !' Circle$04%##$"(!'+".#$&/=4"046$3+,< ShapeB$<'%("(@$.!%.$%44$&/=4"0$<'<='+#$,3 Shape$+'<%"(
&/=4"0$"( Circle:$122$%4#,$#/&&,+.#$&+,.'0.')$%()$&+"-%.'$"(!'+".%(0'B$5!"0!$+'#.+"0.$.!'$%00'##$,3
j%+"%=4'#$)'04%+')$.!"#$5%6$='!%-'$4"7'$8%-%`19$&+"<"."-'$.6&'#$#/0!$%# int$%() double:$N,+ .!'$=%#'$04%##U#$&/=4"0$%()$&+,.'0.')$<'<='+#:
'*%<&4'B$5!'($5'$/#'$.!'$%##"@(<'(.$,&'+%.,+B .!'$0,(.'(.#$,3$.!'$-%+"%=4'$"#$0,&"')(,.$>/#.$%
+'3'+'(0'$.,$%($,=>'0.:$I()$"3$5'$<,)"36$%$-%+"%=4'$4%.'+$,(B$%(6$,.!'+$-%+"%=4'#$.!%.$5'+'$%##"@(') !'$0,(#.+/0.,+$.%7'#$.5,$&%+%<'.'+#:$ !'$#'0,()$&%+%<'.'+$"#$,&.",(%4$%()$.%7'#$.!'$-%4/'$D:C$"3
3+,<$".$%+'$4'3.$/(0!%(@'): (,.$#&'0"3"'):$ !'$0,(#.+/0.,+$&%##'#$.!' center$&%+%<'.'+$.,$.!'$=%#'$04%##U#$0,(#.+/0.,+$/#"(@$%
#&'0"%4$#6(.%*$='.5''($.!'$3/(0.",($#"@(%./+'$%()$.!' 3/(0.",($=,)6:$;($.!'$=,)6B$5'$"("."%4"Q'$.!'
I#$%($,=>'0.?,+"'(.')$4%(@/%@'B$122$#/&&,+.#$"(!'+".%(0'$%()$&,46<,+&!"#<:$ , "44/#.+%.'$!,5$". myRadius$<'<='+$-%+"%=4':$Y'$0,/4)$%4#,$!%-'$"("."%4"Q')$.!'$-%+"%=4'$,($.!'$#%<'$4"('$%#$.!'$=%#'
5,+7#B$5'$5"44$+'-"'5$.!'$'*%<&4'$,3$% Shape$%=#.+%0.$=%#'$04%##$%()$%$#/=04%##$0%44') Circle:$T'.U# 04%##$0,(#.+/0.,+$"("."%4"Q%.",(O
#.%+.$5".!$.!'$=%#'$04%##O
122$#/&&,+.#$</4."&4'$"(!'+".%(0'B$<'%("(@$.!%.$%$04%##$0%($)'+"-'$3+,<$#'-'+%4$04%##'#$%.$.!' Pointers
#%<'$."<':$ !'$#6(.%*$"#$%#$3,44,5#O
I 6-&(0":$"($122$"#$%$-%+"%=4'$.!%.$#.,+'#$.!'$<'<,+6$%))+'##$,3$%($,=>'0.$V"(#.'%)$,3$#.,+"(@$.!'
class DerivedClass : public BaseClass1, public BaseClass2, ..., ,=>'0.$)"+'0.46W:$8%-%$%()$19$!%-'$%$#"<"4%+$0,(0'&.B$.!%.$,3$%$M+'3'+'(0'MB$=/.$.!'$#6(.%*$"#
public BaseClassN )"33'+'(.:$Y'$5"44$#.%+.$=6$#./)6"(@$%$0,(.+"-')$'*%<&4'$.!%.$"44/#.+%.'#$&,"(.'+#$"($%0.",(O
{
...
}; 1 #include "point2d.h"
2 int main()
3 {
4 Point2D alpha;
K6$)'3%/4.B$3/(0.",(#$%()$-%+"%=4'#$)'04%+')$"($%$04%##$%+'$%##,0"%.')$5".!$"(#.%(0'#$,3$.!%.$04%##:$Y' 5 Point2D beta;
0%($%4#,$)'04%+'$#.%."0$<'<='+$3/(0.",(#$%()$#.%."0$<'<='+$-%+"%=4'#B$5!"0!$0%($='$/#')$5".!,/.$%( 6 Point2D *ptr;
"(#.%(0':$N,+$'*%<&4'O 7 ptr = α
8 ptr->setX(1.0);
9 ptr->setY(2.5);
#ifndef TRUCK_H 10 ptr = β
#define TRUCK_H 11 ptr->setX(4.0);
class Truck 12 ptr->setY(4.5);
{ 13 ptr = 0;
public: 14 return 0;
Truck() { ++counter; } 15 }
~Truck() { --counter; }
static int instanceCount() { return counter; }
private:
static int counter; !'$'*%<&4'$+'4"'#$,($.!' Point2D$04%##$3+,<$.!'$&+'-",/#$#/=#'0.",(:$T"('#$^$%()$C$)'3"('$.5,
}; ,=>'0.#$,3$.6&' Point2D:$ !'#'$,=>'0.#$%+' "("."%4"Q')$.,$VDB$DW$=6$.!'$)'3%/4. Point2D$0,(#.+/0.,+:
#endif
T"('$c$)'3"('#$%$&,"(.'+$.,$% Point2D$,=>'0.:$ !'$#6(.%*$3,+$&,"(.'+#$/#'#$%($%#.'+"#7$"($3+,(.$,3$.!'
-%+"%=4'$(%<':$L"(0'$5'$)")$(,.$"("."%4"Q'$.!'$&,"(.'+B$".$0,(.%"(#$%$+%(),<$<'<,+6$%))+'##:$ !"#$"#
!'$#.%."0$<'<='+$-%+"%=4' counter$7''&#$.+%07$,3$!,5$<%(6 truck$"(#.%(0'#$'*"#.$%.$%(6$."<':$ !' #,4-')$,($4"('$b$=6$%##"@("(@ alphaU#$%))+'##$.,$.!'$&,"(.'+:$ !'$/(%+6 &$,&'+%.,+$+'./+(#$.!'
truck$0,(#.+/0.,+$"(0+'<'(.#$".:$ !'$)'#.+/0.,+B$+'0,@("Q%=4'$=6$.!' ~$&+'3"*B$)'0+'<'(.#$".:$;($122B <'<,+6$%))+'##$,3$%($,=>'0.:$I($%))+'##$"#$.6&"0%446$%$P]?=".$,+$%$c^?=".$"(.'@'+$-%4/'$#&'0"36"(@$.!'
.!'$)'#.+/0.,+$"#$%/.,<%."0%446$"(-,7')$5!'($%$#.%."0%446$%44,0%.')$-%+"%=4' @,'#$,/.$,3$#0,&'$,+ ,33#'.$,3$%($,=>'0.$"($<'<,+6:
5!'($%$-%+"%=4'$%44,0%.')$/#"(@ new$"#$)'4'.'):$ !"#$"#$#"<"4%+$.,$.!' finalize()$<'.!,)$"($8%-%B
'*0'&.$.!%.$5'$0%($+'46$,($".$='"(@$0%44')$%.$%$#&'0"3"0$&,"(.$"($."<': Z($4"('#$d$%()$hB$5' %00'##$.!' alpha$,=>'0.$.!+,/@!$.!' ptr$&,"(.'+:$K'0%/#' ptr$"#$%$&,"(.'+$%()
(,.$%($,=>'0.B$5'$</#.$/#'$.!' ->$V%++,5W$,&'+%.,+$"(#.'%)$,3$.!' .$V),.W$,&'+%.,+:
I$#.%."0$<'<='+$-%+"%=4'$!%#$%$#"(@4'$'*"#.'(0'$"($%$04%##O$L/0! -%+"%=4'#$%+'$M04%##$-%+"%=4'#M
+%.!'+$.!%($M"(#.%(0'$-%+"%=4'#M:$X%0!$#.%."0$<'<='+$-%+"%=4'$</#.$='$)'3"(')$"($% .cpp$3"4'$V=/. Z($4"('$ADB$5'$%##"@( betaU#$%))+'##$.,$.!'$&,"(.'+:$N+,<$.!'($,(B$%(6$,&'+%.",($5'$&'+3,+<
5".!,/.$+'&'%."(@$.!' static$7'65,+)W:$N,+$'*%<&4'O .!+,/@!$.!'$&,"(.'+$5"44$%33'0.$.!' beta$,=>'0.:
T"('$AP$#'.#$.!'$&,"(.'+$.,$='$%$(/44$&,"(.'+:$122$!%#$(,$7'65,+)$3,+$+'&+'#'(."(@$%$&,"(.'+$.!%.
#include "truck.h" ),'#$(,.$&,"(.$.,$%($,=>'0.J$"(#.'%)B$5'$/#'$.!'$-%4/'$D$V,+$.!'$#6<=,4"0$0,(#.%(. NULLB$5!"0!
int Truck::counter = 0; '*&%()#$.,$DW:$ +6"(@$.,$/#'$%$(/44$&,"(.'+$+'#/4.#$"($%$0+%#!$5".!$%($'++,+$<'##%@'$#/0!$%#
ML'@<'(.%.",($3%/4.MB$MF'('+%4$&+,.'0.",($3%/4.MB$,+$MK/#$'++,+M:$G#"(@$%$)'=/@@'+B$5'$0%($3"()$,/.
5!"0!$4"('$,3$0,)'$0%/#')$.!'$0+%#!:
N%"4"(@$.,$),$.!"#$5,/4)$+'#/4.$"($%($M/(+'#,4-')$#6<=,4M$'++,+$%.$4"(7$."<':$ !' instanceCount()
#.%."0$3/(0.",($0%($='$%00'##')$3+,<$,/.#")'$.!'$04%##B$&+'3"*')$=6$.!'$04%##$(%<':$N,+$'*%<&4'O I.$.!'$'()$,3$.!'$3/(0.",(B$.!' alpha$,=>'0.$!,4)#$.!'$0,,+)"(%.'$&%"+$VA:DB$]:CWB$5!'+'%# beta$!,4)#
V^:DB$^:CW:
• i'3'+'(0'#$%+'$)'04%+')$/#"(@ &$"(#.'%)$,3 *:
Point2D point; • !'$+'3'+'(0'$</#.$='$"("."%4"Q')$%()$0%(U.$='$+'%##"@(')$4%.'+:
point.setX(1.0);
• !'$,=>'0.$%##,0"%.')$5".!$%$+'3'+'(0'$"#$)"+'0.46$%00'##"=4'J$.!'+'$"#$(,$#&'0"%4$#6(.%*$#/0!
point.setY(2.5);
%# *$,+ ->:
• I$+'3'+'(0'$0%((,.$='$(/44:
Z=>'0.#$%44,0%.')$4"7'$.!"#$%+'$%/.,<%."0%446$3+'')$%.$.!'$'()$,3$.!'$=4,07$"($5!"0!$.!'6$%&&'%+:
i'3'+'(0'#$%+'$<,#.46$/#')$5!'($)'04%+"(@$&%+%<'.'+#:$K6$)'3%/4.B$122$/#'#$0%44?=6?-%4/'$%#$".#
&%+%<'.'+?&%##"(@$<'0!%("#<B$<'%("(@$.!%.$5!'($%($%+@/<'(.$"#$&%##')$.,$%$3/(0.",(B$.!'
;3$5'$),(U.$"(.'()$.,$<,)"36$.!'$,=>'0.$.!+,/@!$.!'$&,"(.'+B$5'$0%($)'04%+'$.!'$&,"(.'+$0,(#.:$N,+ 3/(0.",($+'0'"-'#$%$=+%()$('5$0,&6$,3$.!'$,=>'0.:$['+'U#$.!'$)'3"(".",($,3$%$3/(0.",($.!%.$+'0'"-'#$".#
'*%<&4'O &%+%<'.'+#$.!+,/@!$0%44?=6?-%4/'O
i'3,+<')$1$&+,@+%<<'+#$%-,")$('')4'##$0,&6$,&'+%.",(#$=6$)'04%+"(@$.!'"+$&%+%<'.'+#$%#$&,"(.'+#
"(#.'%)$,3$%#$-%4/'#O Point2D point;
Point2D *ptr = &point;
Point2D &ref = *ptr;
double manhattanDistance(const Point2D *ap, const Point2D *bp)
{
return abs(bp->x() - ap->x()) + abs(bp->y() - ap->y());
i'3'+'(0'#$%()$&,"(.'+#$%+'$+'&+'#'(.')$.!'$#%<'$5%6$"($<'<,+6B$%()$.!'6$0%($,3.'($='$/#')
}
"(.'+0!%(@'%=46B$5!"0!$='@#$.!'$E/'#.",($,3$5!'($.,$/#'$5!"0!:$Z($.!'$,('$!%()B$+'3'+'(0'#$!%-'$%
<,+'$0,(-'("'(.$#6(.%*J$,($.!'$,.!'+$!%()B$&,"(.'+#$0%($='$+'%##"@(')$%.$%(6$."<'$.,$&,"(.$.,
%(,.!'+$,=>'0.B$.!'6$0%($!,4)$%$(/44$-%4/'B$%()$.!'"+$<,+'$'*&4"0".$#6(.%*$"#$,3.'($%$=4'##"(@$"(
!'6$</#.$.!'($&%##$%))+'##'#$"(#.'%)$,3$-%4/'#$5!'($0%44"(@$.!'$3/(0.",(O )"#@/"#':$N,+$.!'#'$+'%#,(#B$&,"(.'+#$.'()$.,$&+'-%"4B$5".!$+'3'+'(0'#$%4<,#.$'*04/#"-'46$/#')$3,+
)'04%+"(@$3/(0.",($&%+%<'.'+#B$"($0,(>/(0.",($5".! const:
int fibonacci[10];
double manhattanDistance(const Point2D &a, const Point2D &b)
{
return abs(b.x() - a.x()) + abs(b.y() - a.y()); !'$".'<#$%+'$%00'##"=4'$%# fibonacci[0]B fibonacci[1]B$\B fibonacci[9]:$Z3.'($5'$5%(.$.,$"("."%4"Q'
} .!'$%++%6$%#$5'$)'3"('$".O
!'$&+'-",/#$'*%<&4'$/#')$0,(#.$+'3'+'(0'#B$&+'-'(."(@$.!'$3/(0.",($3+,<$<,)"36"(@$.!'$,=>'0.#
%##,0"%.')$5".!$.!'$+'3'+'(0'#:$Y!'($.!"#$7"()$,3$#")'$'33'0.$"#$)'#"+')B$5'$0%($&%##$%$(,(?0,(#. L.%."0$"("."%4"Q%.",($%4#,$5,+7#$3,+$0,<&4'*$.6&'#B$#/0!$%# Point2DO
+'3'+'(0'$,+$&,"(.'+:$N,+$'*%<&4'O
Point2D triangle[] = {
void transpose(Point2D &point) Point2D(0.0, 0.0), Point2D(1.0, 0.0), Point2D(0.5, 0.866)
{ };
double oldX = point.x();
point.setX(point.y());
point.setY(oldX);
} ;3$5'$!%-'$(,$"(.'(.",($,3$%4.'+"(@$.!'$%++%6$4%.'+$,(B$5'$0%($<%7'$".$0,(#.O
,$3"()$,/.$!,5$<%(6$".'<#$%($%++%6$0,(.%"(#B$5'$0%($/#'$.!' sizeof()$,&'+%.,+$%#$3,44,5#O
Point2D point;
Point2D &ref = point;
Point2D *ptr = &ref; int n = sizeof(fibonacci) / sizeof(fibonacci[0]);
;+,("0%446B$%4.!,/@!$122$),'#(U.$@"-'$/#$%(6$0!,"0'$%=,/.$5!'.!'+$5'$5%(.$.,$&%##$%($%++%6$=6
!' sizeof() ,&'+%.,+$+'./+(#$.!'$#"Q'$,3$".#$%+@/<'(.$"($=6.'#:$ !'$(/<='+$,3$".'<#$"($%($%++%6$"# %))+'##$,+$=6$-%4/'B$".$@"-'#$/#$#,<'$3+''),<$"($.!' %;(0)@$/#')$.,$)'04%+'$.!'$&%+%<'.'+$.6&':
".#$#"Q'$"($=6.'#$)"-")')$=6$.!'$#"Q'$,3$,('$,3$".#$".'<#:$K'0%/#'$.!"#$"#$0/<='+#,<'$.,$.6&'B$% ;(#.'%)$,3 const int *tableB$5'$0,/4)$%4#,$!%-'$5+"..'( const int table[]$.,$)'04%+'$%$&,"(.'+?.,?
0,<<,($%4.'+(%."-'$"#$.,$)'04%+'$%$0,(#.%(.$%()$.,$/#'$".$3,+$)'3"("(@$.!'$%++%6O 0,(#.%(.? int$&%+%<'.'+:$L"<"4%+46B$.!' argv$&%+%<'.'+$., main()$0%($='$)'04%+')$%#$'".!'+ char
*argv[]$,+ char **argv:
;.'+%."(@$.!+,/@!$%($%++%6$"#$(,+<%446$),('$/#"(@$%($"(.'@'+:$N,+$'*%<&4'O
N,+$=%#"0$)%.%$.6&'#$#/0!$%# intB$5'$0%($%4#,$/#' std::memcpy()B$5!"0!$0,&"'#$%$=4,07$,3$<'<,+6:
N,+$'*%<&4'O
for (int i = 0; i < NFibonacci; ++i)
cout << fibonacci[i] << endl;
memcpy(temp, fibonacci, sizeof(fibonacci));
;.$"#$%4#,$&,##"=4'$.,$.+%-'+#'$.!'$%++%6$/#"(@$%$&,"(.'+O
Y!'($5'$)'04%+'$%$122$%++%6B$.!'$#"Q'$</#.$='$%$0,(#.%(.: efg$;3$5'$5%(.$.,$0+'%.'$%($%++%6$,3$%
-%+"%=4'$#"Q'B$5'$!%-'$#'-'+%4$,&.",(#:
const int *ptr = &fibonacci[0];
[*]
while (ptr != &fibonacci[10]) { Some compilers allow variables in that context, but this feature should not be relied upon in portable programs.
cout << *ptr << endl;
++ptr; • 8+&.34&9B430#.322B&322/.3%+&%"+&3553BD
} •
• int *fibonacci = new int[n];
#include <iostream>
;.'<#$%+'$%00'##"=4'$/#"(@$.!' []$,&'+%.,+B$>/#.$4"7'$5".!$%$&4%"($122$%++%6:$Y".!
using namespace std;
void printIntegerTable(const int *table, int size) std::vector<T>$V5!'+' T$"#$.!'$.6&'$,3$.!'$".'<#$#.,+')$"($.!'$-'0.,+WB$5'$0%($+'#"Q'$.!'
{ %++%6$%.$%(6$."<'$/#"(@ resize()$%()$5'$0%($0,&6$".$/#"(@$.!'$%##"@(<'(.$,&'+%.,+:$14%##'#
for (int i = 0; i < size; ++i) .!%.$0,(.%"($%(@4'$=+%07'.#$V<>W$"($.!'"+$(%<'$%+'$0%44')$.'<&4%.'$04%##'#:
cout << table[i] << endl;
} • 8+&.34&>6+&G%H6&GI+.%/5E*F&.2366D
int main() •
{
• #include <QVector>
const int fibonacci[10] = { 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 };
printIntegerTable(fibonacci, 10); • QVector<int> fibonacci(n);
return 0;
} QVector<T>U#$I_;$"#$-'+6$#"<"4%+$.,$.!%.$,3 std::vector<T>B$=/.$".$%4#,$#/&&,+.#$".'+%.",($/#"(@
H.U# foreach$7'65,+)$%()$/#'#$"<&4"0". )%.%$#!%+"(@$VM0,&6$,($5+".'MW$%#$%$<'<,+6$%()
#&'')$,&."<"Q%.",(: 1!%&.'+$AA$&+'#'(.#$H.U#$0,(.%"('+$04%##'#$%()$'*&4%"(#$!,5$.!'6$+'4%.' {
.,$.!'$L.%()%+)$122$0,(.%"('+#: cout << str << endl;
}
int main(int argc, char *argv[])
l,/$<"@!.$='$.'<&.')$.,$%-,")$=/"4.?"($%++%6#$5!'('-'+$&,##"=4'$%()$/#' std::vector<T>$,+
{
QVector<T>$"(#.'%):$;.$"#$(,('.!'4'##$5,+.!5!"4'$/()'+#.%()"(@$!,5$.!'$=/"4.?"($%++%6#$5,+7$='0%/#' for (int i = 1; i < argc; ++i) {
#,,('+$,+$4%.'+$6,/$<"@!.$5%(.$.,$/#'$.!'<$"($!"@!46$,&."<"Q')$0,)'B$,+$('')$.!'<$.,$"(.'+3%0'$5".! makeUppercase(argv[i]);
'*"#."(@$1$4"=+%+"'#: writeLine(argv[i]);
}
Character Strings return 0;
}
!'$<,#.$=%#"0$5%6$,3$+'&+'#'(."(@$0!%+%0.'+$#.+"(@#$"($122$"#$.,$/#'$%($%++%6$,3 char#$.'+<"(%.')
=6$%$(/44$=6.'$VUmDUW:$ !'$3,44,5"(@$3,/+$3/(0.",(#$)'<,(#.+%.'$!,5$.!'#'$7"()#$,3$#.+"(@#$5,+7O
;($122B$.!' char$.6&'$(,+<%446$!,4)#$%($d?=".$-%4/':$ !"#$<'%(#$.!%.$5'$0%($'%#"46$#.,+'$IL1;;B$;LZ
ddCh?A$VT%."(?AWB$%()$,.!'+$d?=".?'(0,)')$#.+"(@#$"($% char$%++%6B$=/.$.!%.$5'$0%(U.$#.,+'$%+=".+%+6
void hello1() G("0,)'$0!%+%0.'+#$5".!,/.$+'#,+."(@$.,$</4."=6.'$#'E/'(0'#:$H.$&+,-")'#$.!'$&,5'+3/4 QString
{ 04%##B$5!"0!$#.,+'#$G("0,)'$#.+"(@#$%#$#'E/'(0'#$,3$Ac?=". QChar#$%()$"(.'+(%446$/#'#$.!'$"<&4"0".
const char str[] = { )%.%$#!%+"(@$VM0,&6$,($5+".'MW$,&."<"Q%.",(: 1!%&.'+$AA$V1,(.%"('+$14%##'#W$%() 1!%&.'+$Ab
'H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '\0' V;(.'+(%.",(%4"Q%.",(W$'*&4%"( QString$"($<,+'$)'.%"4:
};
cout << str << endl;
} Enumerations
void hello2()
{ 122$!%#$%($'(/<'+%.",($3'%./+'$3,+$)'04%+"(@$%$#'.$,3$(%<')$0,(#.%(.#$#"<"4%+$.,$.!%.$&+,-")')$=6
const char str[] = "Hello world!"; 19:$T'.U#$#/&&,#'$.!%.$5'$5%(.$.,$#.,+'$)%6#$,3$.!'$5''7$"($%$&+,@+%<O
cout << str << endl;
}
void hello3() enum DayOfWeek {
{ Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday
cout << "Hello world!" << endl; };
}
void hello4()
{
const char *str = "Hello world!"; k,+<%446B$5'$5,/4)$&/.$.!"#$)'04%+%.",($"($%$!'%)'+$3"4'B$,+$'-'($"(#")'$%$04%##:$ !'$%=,-'
cout << str << endl; )'04%+%.",($"#$#/&'+3"0"%446$'E/"-%4'(.$.,$.!'$3,44,5"(@$0,(#.%(.$)'3"(".",(#O
}
!'$3,/+.!$3/(0.",($"#$%$=".$)"33'+'(.$"($.!%.$".$0+'%.'#$(,.$,(46$%($V%(,(6<,/#W$%++%6$=/.$%4#,$%
K6$/#"(@$.!'$'(/<'+%.",($0,(#.+/0.B$5'$0%($4%.'+$)'04%+'$-%+"%=4'#$,+$&%+%<'.'+#$,3$.6&' DayOfWeek
&,"(.'+$-%+"%=4'$0%44') str$.!%.$#.,+'#$.!'$%))+'##$,3$.!'$%++%6U#$3"+#.$".'<:$;($#&".'$,3$.!"#B$.!'
%()$.!'$0,<&"4'+$5"44$'(#/+'$.!%.$,(46$-%4/'#$3+,<$.!' DayOfWeek$'(/<'+%.",($%+'$%##"@(')$.,$".:$N,+
#'<%(."0#$,3$.!'$3/(0.",($%+'$")'(."0%4$.,$.!'$&+'-",/#$.!+''$3/(0.",(#B$%()$%($,&."<"Q"(@$0,<&"4'+
'*%<&4'O
5,/4)$'4"<"(%.'$.!'$#/&'+34/,/# str$-%+"%=4':
;3$5'$),(U.$0%+'$%=,/.$.6&'$#%3'.6B$5'$0%($%4#,$5+".'
#include <cctype>
#include <iostream>
using namespace std;
void makeUppercase(char *str) int day = Sunday;
{
for (int i = 0; str[i] != '\0'; ++i)
str[i] = toupper(str[i]); k,."0'$.!%.$.,$+'3'+$.,$.!' Sunday 0,(#.%(.$3+,<$.!' DayOfWeek$'(/<B$5'$#"<&46$5+".' SundayB$(,.
}
void writeLine(const char *str)
DayOfWeek::Sunday: }
K6$)'3%/4.B$.!'$0,<&"4'+$%##"@(#$0,(#'0/."-'$"(.'@'+$-%4/'#$.,$.!'$0,(#.%(.#$,3$%($'(/<B$#.%+."(@$%.
D:$Y'$0%($#&'0"36$,.!'+$-%4/'#$"3$5'$5%(.O I$-%+"%=4'$,3$.6&' FindOption$0%($,(46$0,(.%"($,('$34%@$%.$%$."<':$ !'$+'#/4.$,3$0,<="("(@$#'-'+%4
34%@#$/#"(@ |$"#$%$&4%"($"(.'@'+:$G(3,+./(%.'46B$.!"#$"#$(,.$.6&'?#%3'O$ !'$0,<&"4'+$5,(U.$0,<&4%"($"3$%
3/(0.",($'*&'0."(@$%$0,<="(%.",($,3 FindOption#$.!+,/@!$%( int$&%+%<'.'+$+'0'"-'# Saturday
enum DayOfWeek { "(#.'%):$H.$/#'# QFlags<T>$.,$&+,-")'$.6&'$#%3'.6$3,+$".#$,5($34%@$.6&'#:$ !'$04%##$"#$%4#,$%-%"4%=4'
Sunday = 628, 5!'($5'$)'3"('$0/#.,<$34%@$.6&'#:$L''$.!' QFlags<T>$,(4"('$),0/<'(.%.",($3,+$)'.%"4#:
Monday = 616,
Tuesday = 735,
Wednesday = 932, Typedefs
Thursday = 852,
Friday = 607, 122$4'.#$/#$@"-'$%($%4"%#$.,$%$)%.%$.6&'$/#"(@$.!' typedef$7'65,+):$N,+$'*%<&4'B$"3$5'$/#'
Saturday = 845
QVector<Point2D>$%$4,.$%() 5%(.$.,$#%-'$%$3'5$7'6#.+,7'#$V,+$%+'$/(3,+./(%.'$'(,/@!$.,$='$#./07
};
5".!$%$k,+5'@"%($7'6=,%+)$%()$!%-'$.+,/=4'$4,0%."(@$.!'$%(@4'$=+%07'.#WB$5'$0%($&/.$.!"#$.6&')'3
)'04%+%.",($"($,('$,3$,/+$!'%)'+$3"4'#O
;3$5'$),(U.$#&'0"36$.!'$-%4/'$,3$%($'(/<$".'<B$.!'$".'<$.%7'#$.!'$-%4/'$,3$.!'$&+'-",/#$".'<B$&4/#$A:
X(/<#$%+' #,<'."<'#$/#')$.,$)'04%+'$"(.'@'+$0,(#.%(.#B$"($5!"0!$0%#'$5'$(,+<%446$,<".$.!'$(%<' typedef QVector<Point2D> PointVector;
,3$.!'$'(/<O
• reinterpret_cast<T>()$0,(-'+.#$%(6$&,"(.'+$,+$+'3'+'(0'$.6&'$.,$%(6$,.!'+$#/0!$.6&': N,+
short j = 0x1234; '*%<&4'O
if ((char &)j == 0x12) •
cout << "The byte order is big-endian" << endl;
• short j = 0x1234;
• if (reinterpret_cast<char &>(j) == 0x12)
• cout << "The byte order is big-endian" << endl;
;3$.!'$)%.%$.6&'$"#$%$04%##$(%<'B$%$.6&')'3B$,+$%$&+"<"."-'$.6&'$.!%.$0%($='$'*&+'##')$%#$%$#"(@4'
%4&!%(/<'+"0$.,7'(B$5'$0%($/#'$.!'$0,(#.+/0.,+$#6(.%*$%#$%$0%#.O
;($8%-%$%()$19B$%(6$+'3'+'(0'$0%($='$#.,+')$%#$%( Object$+'3'+'(0'$"3$('')'):$122$),'#(U.$!%-'
%(6$/("-'+#%4$=%#'$04%##B$=/.$".$&+,-")'#$%$#&'0"%4$)%.%$.6&'B void *B$.!%.$#.,+'#$.!'$%))+'##$,3$%(
int x = int(Pi * 100); "(#.%(0'$,3$%(6$.6&':$I void *$</#.$='$0%#.$=%07$.,$%(,.!'+$.6&'$V/#"(@ static_cast<T>()W$='3,+'$".
0%($='$/#'):
122$&+,-")'#$<%(6$5%6#$,3$0%#."(@$.6&'#B$=/.$<,#.$,3$.!'$."<'$5'$),(U.$'-'($('')$%$0%#.:$Y!'(
1%#."(@$&,"(.'+#$%()$+'3'+'(0'#$/#"(@$.!'$.+%)".",(%4$1?#.64'$0%#.#$"#$%$7"()$,3$'*.+'<'$#&,+.B$,($&%+
/#"(@$0,(.%"('+$04%##'#$#/0! %# std::vector<T>$,+ QVector<T>B$5'$0%($#&'0"36$.!' T$.6&'$%()$'*.+%0.
5".! &%+%@4")"(@$%()$'4'-%.,+$#/+3"(@B$='0%/#'$.!'$0,<&"4'+$4'.#$/#$0%#.$%(6$&,"(.'+$V,+$+'3'+'(0'W
".'<#$5".!,/.$0%#.#:$;($%))".",(B$3,+$&+"<"."-'$.6&'#B$0'+.%"($0,(-'+#",(#$,00/+$"<&4"0".46$V3,+
.6&'$"(.,$%(6$,.!'+$&,"(.'+$V,+$+'3'+'(0'W$.6&':$N,+$.!%.$+'%#,(B$122$"(.+,)/0')$3,/+$('5?#.64'
'*%<&4'B$3+,< char$., intWB$%()$3,+$0/#.,<$.6&'#$5'$0%($)'3"('$"<&4"0".$0,(-'+#",(#$=6$&+,-")"(@$%
0%#.#$5".!$<,+'$&+'0"#'$#'<%(."0#:$N,+$&,"(.'+#$%()$+'3'+'(0'#B$.!'$('5?#.64'$0%#.#$%+'$&+'3'+%=4'
,('?&%+%<'.'+$0,(#.+/0.,+:$N,+$'*%<&4'O
.,$.!'$+"#76$1?#.64'$0%#.#$%()$%+'$/#')$"($.!"#$=,,7:
#ifndef POINT2D_H
#define POINT2D_H
class Point2D Y'$0%($%4#,$"(-,7'$.!' operator$3/(0.",(#$>/#.$4"7'$%(6$,.!'+$3/(0.",(#O
{
public:
Point2D(); Point2D alpha(12.5, 40.0);
Point2D(double x, double y); Point2D beta(77.5, 50.0);
void setX(double x); alpha.operator+=(beta);
void setY(double y); beta.operator-=(alpha);
double x() const; Point2D gamma = operator+(alpha, beta);
double y() const; Point2D delta = operator-(beta, alpha);
Point2D &operator+=(const Point2D &other) {
xVal += other.xVal;
yVal += other.yVal;
return *this; Z&'+%.,+$,-'+4,%)"(@$"($122$"#$%$0,<&4'*$.,&"0B$=/.$5'$0%($@,$%$4,(@$5%6 5".!,/.$7(,5"(@$%44$.!'
} )'.%"4#:$;.$"#$#."44$"<&,+.%(.$.,$/()'+#.%()$.!'$3/()%<'(.%4#$,3$,&'+%.,+$,-'+4,%)"(@$='0%/#'$#'-'+%4
Point2D &operator-=(const Point2D &other) { H.$04%##'#$V"(04/)"(@ QString$%() QVector<T>W$/#'$.!"#$3'%./+'$.,$&+,-")'$%$#"<&4'$%()$<,+'$(%./+%4
xVal -= other.xVal; #6(.%*$3,+$#/0!$,&'+%.",(#$%# 0,(0%.'(%.",($%()$%&&'():
yVal -= other.yVal;
return *this; Value Types
}
private:
double xVal; 8%-%$%()$19$)"#."(@/"#!$='.5''($-%4/'$.6&'#$%()$+'3'+'(0'$.6&'#:
double yVal;
}; • C)./"#0;6"%B$ !'#'$%+'$&+"<"."-'$.6&'#$#/0!$%# charB intB$%() floatB$%#$5'44$%#$19$#.+/0.#:
inline Point2D operator+(const Point2D &a, const Point2D &b) Y!%.$0!%+%0.'+"Q'#$.!'<$"#$.!%.$.!'6$%+'(U.$0+'%.')$/#"(@ new$%()$.!'$%##"@(<'(.$,&'+%.,+
{ &'+3,+<#$%$0,&6$,3$.!'$-%4/'$!'4)$=6$.!'$-%+"%=4': N,+$'*%<&4'O
return Point2D(a.x() + b.x(), a.y() + b.y()); •
}
inline Point2D operator-(const Point2D &a, const Point2D &b) • int i = 5;
{ • int j = 10;
return Point2D(a.x() - b.x(), a.y() - b.y()); • i = j;
} • D"1":"(4"#0;6"%B$ !'#'$%+'$04%##'#$#/0!$%# Integer$V"($8%-%WB StringB$%() MyVeryOwnClass:
#endif ;(#.%(0'#$%+'$0+'%.')$/#"(@ new:$ !'$%##"@(<'(.$,&'+%.,+$0,&"'#$,(46$%$+'3'+'(0'$.,$.!'
,=>'0.J$.,$,=.%"($%$)''&$0,&6B$5'$</#.$0%44 clone()$V"($8%-%W$,+ Clone()$V"($19W: N,+
'*%<&4'O
Z&'+%.,+#$0%($='$"<&4'<'(.')$'".!'+$%#$<'<='+$3/(0.",(#$,+$%#$@4,=%4$3/(0.",(#:$;($,/+$'*%<&4'B •
5'$"<&4'<'(.') +=$%() -=$%#$<'<='+$3/(0.",(#B +$%() -$%#$@4,=%4$3/(0.",(#: • Integer i = new Integer(5);
• Integer j = new Integer(10);
!' +=$%() -=$,&'+%.,+#$.%7'$%$+'3'+'(0'$.,$%(,.!'+ Point2D$,=>'0.$%()$"(0+'<'(.$,+$)'0+'<'(.$.!' • i = j.clone();
@$%() ;$0,,+)"(%.'#$,3$.!'$0/++'(.$,=>'0.$=%#')$,($.!'$,.!'+$,=>'0.:$ !'6$+'./+( *thisB$5!"0!
)'(,.'#$%$+'3'+'(0'$.,$.!'$0/++'(.$,=>'0.$Vthis$"#$,3$.6&' Point2D *W:$i'./+("(@$%$+'3'+'(0'$%44,5# ;($122B$%44$.6&'#$0%($='$/#')$%#$M+'3'+'(0'$.6&'#MB$%()$.!,#'$.!%.$%+'$0,&6%=4'$0%($='$/#')$%#
/#$.,$5+".'$'*,."0$0,)'$4"7'E M-%4/'$.6&'#M$%#$5'44:$N,+$'*%<&4'B$122$),'#(U.$('')$%(6 Integer$04%##B$='0%/#'$5'$0%($/#'
&,"(.'+#$%() new$%#$3,44,5#O
a += b += c;
int *i = new int(5);
int *j = new int(10);
!' +$%() -$,&'+%.,+#$.%7'$.5,$&%+%<'.'+#$%()$+'./+($% Point2D$,=>'0.$=6$-%4/'$V(,.$%$+'3'+'(0'$., *i = *j;
%($'*"#."(@$,=>'0.W:$ !' inline$7'65,+)$%44,5#$/#$.,$&/.$.!'#'$3/(0.",($)'3"(".",(#$"($.!'$!'%)'+$3"4':
;3$.!'$3/(0.",(U#$=,)6$!%)$=''($4,(@'+B$5'$5,/4)$&/.$%$3/(0.",($&+,.,.6&'$"($.!'$!'%)'+$3"4'$%()$.!'
3/(0.",($)'3"(".",($V5".!,/.$.!' inline$7'65,+)W$"($% .cpp$3"4': G(4"7'$8%-%$%()$19B$122$.+'%.#$/#'+?)'3"(')$04%##'#$.!'$#%<'$%#$=/"4."($.6&'#O
!'$3,44,5"(@$0,)'$#("&&'.#$#!,5#$%44$3,/+$,-'+4,%)')$,&'+%.,+#$"($%0.",(O
Point2D *i = new Point2D(5, 5);
Point2D *j = new Point2D(10, 10);
*i = *j;
;($H.B$<%(6$04%##'#$%+'$)'#"@(')$.,$='$/#')$%#$-%4/'$04%##'#:$ !'#'$!%-'$%$0,&6$0,(#.+/0.,+$%()$%(
%##"@(<'(.$,&'+%.,+B$%()$%+'$(,+<%446$"(#.%(."%.')$,($.!'$#.%07$5".!,/. new:$ !"#$"#$.!'$0%#'$3,+
;3$5'$5%(.$.,$<%7'$%$122$04%##$0,&6%=4'B$5'$</#.$'(#/+'$.!%.$,/+$04%##$!%#$%$0,&6$0,(#.+/0.,+$%() QDateTimeB QImageB QStringB$%()$0,(.%"('+$04%##'#$#/0!$%# QList<T>B QVector<T>B$%() QMap<K, T>:
%($%##"@(<'(.$,&'+%.,+:$ !'$0,&6$0,(#.+/0.,+$"#$"(-,7')$5!'($5'$"("."%4"Q'$%($,=>'0.$5".!$%(,.!'+
,=>'0.$,3$.!'$#%<'$.6&':$122$&+,-")'#$.5,$'E/"-%4'(.$#6(.%*'#$3,+$.!"#O Z.!'+$04%##'#$3%44$"($.!'$M+'3'+'(0'$.6&'M$0%.'@,+6B$(,.%=46 QObject$%()$".#$#/=04%##'#$VQWidgetB
QTimerB QTcpSocketB$'.0:W:$ !'#'$!%-'$-"+./%4$3/(0.",(#$%()$0%((,.$='$0,&"'):$N,+$'*%<&4'B$% QWidget
+'&+'#'(.#$%$#&'0"3"0$5"(),5$,+$0,(.+,4$,($#0+''(:$;3$.!'+'$%+'$bC QWidget$"(#.%(0'#$"($<'<,+6B
Point2D i(20, 20); .!'+'$%+'$%4#,$bC$5"(),5#$,+$0,(.+,4#$,($#0+''(:$ !'#'$04%##'#$%+'$.6&"0%446$"(#.%(."%.')$/#"(@$.!'
Point2D j(i); // first syntax
new$,&'+%.,+:
Point2D k = i; // second syntax
,$"44/#.+%.'$!,5$@4,=%4$3/(0.",(#$%()$-%+"%=4'#$5,+7B$5'$5"44$#./)6$%$#<%44$&+,@+%<$.!%.$&+"(.#$%$4"#.
Y!'($5'$)'3"('$%$04%##B$.!'$122$0,<&"4'+$%/.,<%."0%446$&+,-")'#$%$0,&6$0,(#.+/0.,+$%()$%( ,3$A]d$&#'/),?+%(),<$(/<='+#$/#"(@$%$E/"07?%()?)"+.6$%4@,+".!<:$ !'$&+,@+%<U#$#,/+0'$0,)'$"#
%##"@(<'(.$,&'+%.,+$.!%.$&'+3,+<$<'<='+?=6?<'<='+$0,&6:$N,+$.!' Point2D$04%##B$.!"#$"#$%#$"3$5' #&+'%)$,-'+$.5, .cpp$3"4'#:
!%)$5+"..'($.!'$3,44,5"(@$0,)'$"($.!'$04%##$)'3"(".",(O
!'$3"+#.$#,/+0'$3"4'$"# random.cppO
class Point2D
{ int randomNumbers[128];
public: static int seed = 42;
... static int nextRandomNumber()
Point2D(const Point2D &other) {
: xVal(other.xVal), yVal(other.yVal) { } seed = 1009 + (seed * 2011);
Point2D &operator=(const Point2D &other) { return seed;
xVal = other.xVal; }
yVal = other.yVal; void populateRandomArray()
return *this; {
} for (int i = 0; i < 128; ++i)
... randomNumbers[i] = nextRandomNumber();
private: }
double xVal;
double yVal;
};
!'$3"4'$)'04%+'#$.5,$@4,=%4$-%+"%=4'#$VrandomNumbers$%() seedW$%()$.5,$@4,=%4$3/(0.",(#
VnextrandomNumber()$%() populateRandomArray()W:$ 5,$,3$.!'$)'04%+%.",(#$0,(.%"($.!' static
7'65,+)J$.!'#'$%+'$-"#"=4'$,(46$5".!"($.!'$0/++'(.$0,<&"4%.",($/(".$V random.cppW$%()$%+'$#%")$.,$!%-'
N,+$#,<'$04%##'#B$.!'$)'3%/4.$0,&6$0,(#.+/0.,+$%()$%##"@(<'(.$,&'+%.,+$%+'$/(#/".%=4':$ !"#
%0)0&4#.&(9)'":$ !'$.5,$,.!'+#$0%($='$%00'##')$3+,<$%(6$0,<&"4%.",($/(".$"($.!'$&+,@+%<J$.!'#'
.6&"0%446$,00/+#$"3$.!'$04%##$/#'#$)6(%<"0$<'<,+6:$ ,$<%7'$.!'$04%##$0,&6%=4'B$5'$</#.$.!'(
!%-' "@0":().#.&(9)'":
"<&4'<'(.$.!'$0,&6$0,(#.+/0.,+$%()$.!'$%##"@(<'(.$,&'+%.,+$,/+#'4-'#:
L.%."0$4"(7%@'$"#$")'%4$3,+$!'4&'+$3/(0.",(#$%()$"(.'+(%4$-%+"%=4'#$.!%.$#!,/4)$(,.$='$/#')$"($,.!'+
N,+$04%##'#$.!%.$),(U.$('')$.,$='$0,&6%=4'B$5'$0%($)"#%=4'$.!'$0,&6$0,(#.+/0.,+$%()$%##"@(<'(.
0,<&"4%.",($/(".#:$;.$+')/0'#$.!'$+"#7#$,3$!%-"(@$0,44")"(@$")'(."3"'+#$V@4,=%4$-%+"%=4'#$5".!$.!'$#%<'
,&'+%.,+$=6$<%7"(@$.!'<$&+"-%.':$;3$5'$%00")'(.%446$%..'<&.$.,$0,&6$"(#.%(0'#$,3$#/0!$%$04%##B$.!'
(%<'$,+$@4,=%4$3/(0.",(#$5".!$.!'$#%<'$#"@(%./+'$"($)"33'+'(.$0,<&"4%.",($/(".#W$%()$&+'-'(.#
0,<&"4'+$+'&,+.#$%($'++,+:$N,+$'*%<&4'O
<%4"0",/#$,+$,.!'+5"#'$"44?%)-"#')$/#'+#$3+,<$%00'##"(@$.!'$"(.'+(%4#$,3$%$0,<&"4%.",($/(".:
Y'$)'04%+'$.!'$'*.'+(%4$-%+"%=4'#$%()$3/(0.",(#$='3,+'$5'$0%44$.!'<:$ !'$'*.'+(%4$-%+"%=4'
)'04%+%.",($V5!"0!$<%7'#$%($'*.'+(%4$-%+"%=4'$-"#"=4'$"($.!'$0/++'(.$0,<&"4%.",($/(".W$3,+ Vk,."0'$.!%.$5'$!%-'$%4#,$+'(%<')$.!'$&+'&+,0'##,+$<%0+,$/#')$.,$%-,")$</4."&4'$"(04/#",(#B
randomNumbers$#.%+.#$5".!$.!' extern$7'65,+):$Y".!,/. externB$.!'$0,<&"4'+$5,/4)$.!"(7$".$!%#$., +')/0"(@$.!'$+"#7$,3$%$(%<'$04%#!$5".!$%$!'%)'+$3"4'$,3$.!'$#%<'$(%<'$=/.$4,0%.')$"($%$)"33'+'(.
)'%4$5".!$%$-%+"%=4' *"1&(&0&-(B$%()$.!'$4"(7'+$5,/4)$0,<&4%"($='0%/#'$.!'$#%<'$-%+"%=4'$"#$)'3"(') )"+'0.,+6:W
"($.5,$0,<&"4%.",($/(".#$Vrandom.cpp$%() main.cppW:$j%+"%=4'#$0%($='$)'04%+')$%#$<%(6$."<'#$%#$5'
5%(.B$=/.$.!'6$<%6$,(46$='$)'3"(')$,(0':$ !'$)'3"(".",($"#$5!%.$0%/#'#$.!'$0,<&"4'+$.,$+'#'+-' !'$(%<'#&%0'$#6(.%*$"#$#"<"4%+$.,$.!%.$,3$%$04%##B$=/.$".$),'#(U.$'()$5".!$%$#'<"0,4,(:$['+'U#$.!'
#&%0'$3,+$.!'$-%+"%=4': ('5 random.cpp$3"4'O
Y'$!%-'$%4+'%)6$#''($!,5 static$0%($='$/#')$.,$)'04%+'$<'<='+$-%+"%=4'#$%()$3/(0.",(#$.!%.$%+'
(,.$%..%0!')$.,$%$#&'0"3"0$"(#.%(0'$,3$.!'$04%##B$%()$(,5$5'$!%-'$#''($!,5$.,$/#'$".$.,$)'04%+' G(4"7'$04%##'#B$(%<'#&%0'#$0%($='$M+',&'(')M$%.$%(6$."<':$N,+$'*%<&4'O
3/(0.",(#$%()$-%+"%=4'#$5".!$#.%."0$4"(7%@':$ !'+'$"#$,('$<,+'$/#'$,3$.!' static$7'65,+)$.!%.$#!,/4)
='$(,.')$"($&%##"(@:$;($122B$5'$0%($)'04%+'$%$4,0%4$-%+"%=4'$#.%."0:$L/0!$-%+"%=4'#$%+'$"("."%4"Q')$.!'
3"+#.$."<'$.!'$3/(0.",($"#$0%44')$%()$!,4)$.!'"+$-%4/'$='.5''($3/(0.",($"(-,0%.",(#:$N,+$'*%<&4'O namespace Alpha
{
void alpha1();
void nextPrime() void alpha2();
{ }
static int n = 1; namespace Beta
do { {
++n; void beta1();
} while (!isPrime(n)); }
return n; namespace Alpha
} {
void alpha3();
}
L.%."0$4,0%4$-%+"%=4'#$%+'$#"<"4%+$.,$@4,=%4$-%+"%=4'#B$'*0'&.$.!%.$.!'6$%+'$,(46$-"#"=4'$"(#")'$.!'
3/(0.",($5!'+'$.!'6$%+'$)'3"('):
!"#$<%7'#$".$&,##"=4'$.,$)'3"('$!/()+')#$,3$04%##'#B$4,0%.')$"($%#$<%(6$!'%)'+$3"4'#B$%#$&%+.$,3$%
#"(@4'$(%<'#&%0':$G#"(@$.!"#$.+"07B$.!'$L.%()%+)$122$4"=+%+6$&/.#$%44$".#$")'(."3"'+#$"($.!' std
Namespaces (%<'#&%0':$;($H.B$(%<'#&%0'#$%+'$/#')$3,+$@4,=%4?4"7'$")'(."3"'+#$#/0!$%# Qt::AlignBottom$%()
Qt::yellow:$N,+$!"#.,+"0%4$+'%#,(#B$H.$04%##'#$),$(,.$='4,(@$.,$%(6$(%<'#&%0'$=/.$%+'$&+'3"*')$5".!
k%<'#&%0'#$%+'$%$<'0!%("#<$3,+$+')/0"(@$.!'$+"#7#$,3$(%<'$04%#!'#$"($122$&+,@+%<#:$k%<' .!'$4'..'+$UHU:
04%#!'#$%+'$,3.'($%($"##/'$"($4%+@'$&+,@+%<#$.!%.$/#'$#'-'+%4$.!"+)?&%+.6$4"=+%+"'#:$;($6,/+$,5(
&+,@+%<#B$6,/$0%($0!,,#'$5!'.!'+$6,/$5%(.$.,$/#'$(%<'#&%0'#$,+$(,.:
,$+'3'+$.,$%($")'(."3"'+$)'04%+')$"($%$(%<'#&%0'$3+,<$,/.#")'$.!'$(%<'#&%0'B$5'$&+'3"*$".$5".!$.!'
(%<'$,3$.!'$(%<'#&%0'$V%() ::W:$I4.'+(%."-'46B$5'$0%($/#'$,('$,3$.!'$3,44,5"(@$.!+''$<'0!%("#<#B
6&"0%446B$5'$&/.$%$(%<'#&%0'$%+,/()$%44$.!'$)'04%+%.",(#$"($%$!'%)'+$3"4'$.,$'(#/+'$.!%.$.!' 5!"0!$%+'$%"<')$%.$+')/0"(@$.!'$(/<='+$,3$7'6#.+,7'#$5'$</#.$.6&':
")'(."3"'+#$)'04%+')$"($.!%.$!'%)'+$3"4'$),(U.$4'%7$"(.,$.!'$@4,=%4$(%<'#&%0':$N,+$'*%<&4'O
• 8+&.34&9+J#4+&3&430+613.+&32#36D
•
#ifndef SOFTWAREINC_RANDOM_H
• namespace ElPuebloDeLaReinaDeLosAngeles 0,<&"4%.",($/(".$5".!$.!'$.,7'( 3.14159265359:$ ,$%-,")$04%#!'#$5".!$-%+"%=4'$%()$04%##
• { (%<'#B$".$"# 0,<<,($&+%0."0'$.,$@"-'$<%0+,#$%44/&&'+0%#'$(%<'#:$;.$"#$&,##"=4'$.,$)'3"('
• void beverlyHills(); <%0+,#$.!%.$.%7'$%+@/<'(.#O
• void culverCity();
• void malibu();
• void santaMonica(); #define SQUARE(x) ((x) * (x))
• }
• namespace LA = ElPuebloDeLaReinaDeLosAngeles; ;($.!'$<%0+,$=,)6B$".$"#$@,,)$#.64'$.,$#/++,/()$%44$,00/++'(0'#$,3$.!'$&%+%<'.'+#$5".!
&%+'(.!'#'#B$%#$5'44$%#$.!'$'(."+'$=,)6B$.,$%-,")$&+,=4'<#$5".!$,&'+%.,+$&+'0')'(0':$I3.'+
%44B$5'$5%(. 7 * SQUARE(2 + 3)$.,$'*&%()$., 7 * ((2 + 3) * (2 + 3))B$(,.$., 7 * 2 + 3 * 2 +
I3.'+$.!'$%4"%#$)'3"(".",(B$.!'$%4"%#$0%($='$/#')$"(#.'%)$,3$.!'$,+"@"(%4$(%<':E
3:
• 8+&.34/5%&3&6#4=2+	+4%#J#+5&J5/0&3&430+613.+D
122$0,<&"4'+#$(,+<%446$%44,5$/#$.,$)'3"('$<%0+,#$,($.!'$0,<<%()$4"('B$/#"(@$.!' -D$,+ /D
•
,&.",(:$N,+$'*%<&4'O
• int main()
• {
• using ElPuebloDeLaReinaDeLosAngeles::beverlyHills; CC -DPI=3.14159265359 -c main.cpp
• beverlyHills();
• ... S%0+,#$5'+'$-'+6$&,&/4%+$"($.!'$,4)$)%6#B$='3,+'$.6&')'3#B$'(/<#B$0,(#.%(.#B$"(4"('
• } 3/(0.",(#B$%()$.'<&4%.'#$5'+'$"(.+,)/0'):$k,5%)%6#B$.!'"+$<,#.$"<&,+.%(.$+,4'$"#$.,$&+,.'0.
!'%)'+$3"4'#$%@%"(#.$</4."&4'$"(04/#",(#:
!' using$)'04%+%.",($%44,5#$/#$.,$%00'##$%$@"-'($")'(."3"'+$3+,<$%$(%<'?#&%0'$5".!,/.
!%-"(@$.,$&+'3"*$".$5".!$.!'$(%<'$,3$.!'$(%<'#&%0': • S%0+,#$0%($='$/()'3"(')$%.$%(6$&,"(.$/#"(@ #undefO
•
• 8+&.34/5%&34&+4%#5+&430+613.+&:#%"&3&6#4=2+&9#5+.%#A+D • #undef PI
•
• int main() !"#$"#$/#'3/4$"3$5'$5%(.$.,$+')'3"('$%$<%0+,B$#"(0'$.!'$&+'&+,0'##,+$),'#(U.$4'.$/#$)'3"('$.!'
• { #%<'$<%0+,$.5"0': ;.$"#$%4#,$/#'3/4$.,$0,(.+,4$0,()".",(%4$0,<&"4%.",(:
• using namespace ElPuebloDeLaReinaDeLosAngeles;
• santaMonica(); • _,+.",(#$,3$0,)'$0%($='$&+,0'##')$,+$#7"&&')$/#"(@ #ifB #elifB #elseB$%() #endifB$=%#')$,(
• malibu(); .!'$(/<'+"0$-%4/'$,3$<%0+,#: N,+$'*%<&4'O
• ... •
• } • #define NO_OPTIM 0
• #define OPTIM_FOR_SPEED 1
Y".!$.!"#$%&&+,%0!B$(%<' 04%#!'#$%+'$<,+'$4"7'46$.,$,00/+:$;3$.!'$0,<&"4'+$0,<&4%"(#$%=,/.$%( • #define OPTIM_FOR_MEMORY 2
%<="@/,/#$(%<'$V3,+$'*%<&4'B$.5,$04%##'#$5".!$.!'$#%<'$(%<'$)'3"(')$"($.5,$)"33'+'(. • #define OPTIMIZATION OPTIM_FOR_MEMORY
(%<'#&%0'#WB$5'$0%($%45%6#$E/%4"36$.!'$")'(."3"'+$5".!$.!'$(%<'$,3$.!'$(%<'#&%0'$5!'($+'3'++"(@ • ...
.,$".: • #if OPTIMIZATION == OPTIM_FOR_SPEED
• typedef int MyInt;
The Preprocessor • #elif OPTIMIZATION == OPTIM_FOR_MEMORY
• typedef short MyInt;
!'$122$&+'&+,0'##,+$"#$%$&+,@+%<$.!%.$0,(-'+.#$% .cpp$#,/+0'$3"4'$0,(.%"("(@ #?)"+'0."-'#$V#/0!$%# • #else
#includeB #ifndefB$%() #endifW$"(.,$%$#,/+0'$3"4'$.!%.$0,(.%"(#$(,$#/0!$)"+'0."-'#:$ !'#'$)"+'0."-'# • typedef long long MyInt;
&'+3,+<$#"<&4'$.'*./%4$,&'+%.",(#$,( .!'$#,/+0'$3"4'B$#/0!$%#$0,()".",(%4$0,<&"4%.",(B$3"4'$"(04/#",(B • #endif
%()$<%0+,$'*&%(#",(:$k,+<%446B$.!'$&+'&+,0'##,+$"#$"(-,7')$%/.,<%."0%446$=6$.!'$0,<&"4'+B$=/.
<,#.$#6#.'<#$#."44$,33'+$%$5%6$,3$"(-,7"(@$".$%4,('$V,3.'($.!+,/@!$% -E$,+ /E$0,<&"4'+$,&.",(W: ;($.!'$'*%<&4'$%=,-'B$,(46$.!'$#'0,() typedef$)'04%+%.",($5,/4)$='$&+,0'##')$=6$.!'
0,<&"4'+B$+'#/4."(@$"( MyInt$='"(@$)'3"(')$%#$%$#6(,(6<$3,+ short:$K6$0!%(@"(@$.!'$)'3"(".",(
• !' #include$)"+'0."-'$'*&%()#$.,$.!'$0,(.'(.#$,3$.!'$3"4'$#&'0"3"')$5".!"($%(@4'$=+%07'.#$V <>W ,3$.!' OPTIMIZATION$<%0+,B$5'$@'.$)"33'+'(.$&+,@+%<#:$;3$%$<%0+,$"#(U.$)'3"(')B$".#$-%4/'$"#
,+$),/=4'$E/,.'#$V""WB$)'&'()"(@$,($5!'.!'+$.!'$!'%)'+$3"4'$"#$"(#.%44')$%.$%$#.%()%+) .%7'($.,$='$D:
4,0%.",($,+$"#$&%+.$,3$.!'$0/++'(.$&+,>'0.:$ !'$3"4'$(%<'$<%6$0,(.%"( .. %() /$V5!"0!$Y"(),5#
0,<&"4'+#$0,++'0.46$"(.'+&+'.$%#$%$)"+'0.,+6$#'&%+%.,+W: N,+$'*%<&4'O I(,.!'+$%&&+,%0!$.,$0,()".",(%4$0,<&"4%.",($"#$.,$.'#.$5!'.!'+$%$<%0+,$"#$)'3"(')$,+$(,.:$ !"#
• 0%($='$),('$/#"(@$.!'$/#"(@$.!' defined()$,&'+%.,+$%#$3,44,5#O
• #include "../shared/globaldefs.h"
• !' #define$)"+'0."-'$)'3"('#$%$<%0+,:$Z00/++'(0'#$,3$.!'$<%0+,$%&&'%+"(@$%3.'+$.!' #define
)"+'0."-'$%+'$+'&4%0')$5".!$.!'$<%0+,U#$)'3"(".",(: N,+$'*%<&4'B$.!'$)"+'0."-' #define OPTIM_FOR_MEMORY
• ...
• #define PI 3.14159265359 #if defined(OPTIM_FOR_SPEED)
typedef int MyInt;
#elif defined(OPTIM_FOR_MEMORY)
.'44#$.!'$&+'&+,0'##,+$.,$+'&4%0'$%44$3/./+'$,00/++'(0'#$,3$.!'$.,7'( PI$"($.!'$0/++'(.
typedef short MyInt;
#else
typedef long long MyInt;
#endif
The Standard C++ Library
• N,+$0,(-'("'(0'B$.!'$&+'&+,0'##,+$+'0,@("Q'# #ifdef X$%() #ifndef X$%#$#6(,(6<#$3,+ #if
defined(X)$%() #if !defined(X):$ ,$&+,.'0.$%$!'%)'+$3"4'$%@%"(#.$</4."&4'$"(04/#",(#B$5'$5+%& ;($.!"#$#'0.",(B$5'$5"44$=+"'346$+'-"'5$.!'$L.%()%+)$122$4"=+%+6: N"@/+'$K:P$4"#.#$.!'$0,+'$122$!'%)'+
".#$0,(.'(.#$5".!$.!'$3,44,5"(@$")",<O 3"4'#:$ !' <exception>B <limits>B <new>B$%() <typeinfo>$!'%)'+#$#/&&,+. .!'$122$4%(@/%@'J$3,+
• '*%<&4'B <limits>$%44,5#$/#$.,$.'#.$&+,&'+."'#$,3$.!'$0,<&"4'+U#$"(.'@'+$%()$34,%."(@?&,"(.$%+".!<'."0
• #ifndef MYHEADERFILE_H #/&&,+.B$%() <typeinfo>$,33'+#$=%#"0$"(.+,#&'0.",(:$ !'$,.!'+$!'%)'+#$&+,-")'$@'('+%446$/#'3/4
• #define MYHEADERFILE_H 04%##'#B$"(04/)"(@$%$#.+"(@$04%##$%()$%$0,<&4'*$(/<'+"0$.6&':$ !'$3/(0.",(%4".6$,33'+')$=6 <bitset>B
• ... <locale>B <string>B$%() <typeinfo>$4,,#'46$,-'+4%&#$5".!$.!' QBitArrayB QLocaleB QStringB$%()
• #endif QMetaObject$04%##'#$"($H.:
G(4"7'$<,#.$,.!'+$122$0,(#.+/0.#B5!'+'$5!".'#&%0'$"#$"++'4'-%(.B&+'&+,0'##,+$)"+'0."-'#$#.%()
%4,('$,($%$4"('$%()$+'E/"+'$(,$#'<"0,4,(:$j'+6$4,(@$)"+'0."-'#$0%($='$#&4".$%0+,##$</4."&4'$4"('#$=6
'()"(@$'-'+6$4"('$'*0'&.$.!'$4%#.$5".!$%$=%07#4%#!: L.%()%+)$122$%4#,$"(04/)'#$%$#'.$,3$!'%)'+$3"4'#$.!%.$)'%4$5".!$;`ZB$4"#.')$"( N"@/+'$K:^:$ !'
#.%()%+)$;`Z$04%##'#U )'#"@($!%+7#$=%07$.,$.!'$AhdD#$%()$"#$('')4'##46$0,<&4'*B$<%7"(@$.!'<$-'+6
!%+)$.,$'*.'()#,$)"33"0/4.B$"($3%0.B$.!%.$'(."+'$=,,7#$!%-'$=''($5+"..'($,($.!'$#/=>'0.:$;.$%4#,$4'%-'#
.!'$&+,@+%<<'+$5".!$%$_%(),+%U#$=,*$,3$/(+'#,4-')$"##/'#$+'4%.')$.,$0!%+%0.'+$'(0,)"(@#$%()
&4%.3,+<?)'&'()'(.$="(%+6$+'&+'#'(.%.",(#$,3$&+"<"."-'$)%.%$.6&'#:
<#=>5+&'(M(&,--&NOP&2#$535B&"+39+5&J#2+6
L+39+5&J#2+ C+6.5#1%#/4
<fstream> '<&4%.'$04%##'#$.!%.$<%("&/4%.'$'*.'+(%4$3"4'#
<iomanip> ;`Z$#.+'%<$<%("&/4%.,+#$.!%.$.%7'$%($%+@/<'(.
<ios> '<&4%.'$=%#'$04%##$3,+$;`Z$#.+'%<#
<iosfwd> N,+5%+)$)'04%+%.",(#$3,+$#'-'+%4$;`Z$#.+'%<$.'<&4%.'$04%##'#
<iostream> L.%()%+)$;`Z$#.+'%<#$VcinB coutB cerrB clogW
<istream> '<&4%.'$04%##$.!%.$0,(.+,4#$"(&/.$3+,<$%$#.+'%<$=/33'+
<ostream> N"@/+'$K:c$4"#.#$.!'$1$4"=+%+6$!'%)'+$3"4'#:$S,#.$,3$.!'#'$,33'+$3/(0.",(%4".6$.!%.$,-'+4%&#$5".!$<,+'
'<&4%.'$04%##$.!%.$0,(.+,4#$,/.&/.$.,$%$#.+'%<$=/33'+ +'0'(.$122$!'%)'+#$,+$5".!$H.:$Z('$(,.%=4'$'*0'&.",($"# <cmath>B$5!"0!$)'04%+'#$<%.!'<%."0%4
<sstream> '<&4%.'$04%##'#$.!%.$%##,0"%.'$#.+'%<$=/33'+#$5".!$#.+"(@# 3/(0.",(#$#/0!$%# sin()B sqrt()B$%() pow():
<csignal> N/(0.",(#$3,+$!%()4"(@$#6#.'<$#"@(%4#
L+39+5&J#2+ C+6.5#1%#/4
<cstdarg> S%0+,#$3,+$"<&4'<'(."(@$-%+"%=4'$%+@/<'(.$4"#.$3/(0.",(#
<algorithm> F'('+%4?&/+&,#'$.'<&4%.'$3/(0.",(#
<cstddef> 1,<<,($)'3"(".",(#$3,+$#'-'+%4$#.%()%+)$!'%)'+#
<deque> a,/=4'?'()')$E/'/'$.'<&4%.'$0,(.%"('+
<cstdio> N/(0.",(#$3,+$&'+3,+<"(@$;`Z
<functional> '<&4%.'#$.!%.$!'4&$0,(#.+/0.$%()$<%("&/4%.'$3/(0.,+#
<cstdlib> F'('+%4$/."4".6$3/(0.",(#
<iterator> '<&4%.'#$.!%.$!'4&$0,(#.+/0.$%()$<%("&/4%.'$".'+%.,+#
<cstring> N/(0.",(#$3,+$<%("&/4%."(@ char$%++%6#
<list> a,/=46?4"(7')$4"#.$.'<&4%.'$0,(.%"('+
<ctime> 6&'#$%()$3/(0.",(#$3,+$<%("&/4%."(@$."<'
<map> L"(@4'?-%4/')$%()$</4."?-%4/')$<%&$.'<&4%.'$0,(.%"('+#
<cwchar> X*.'()')$</4."=6.'$%()$5")'$0!%+%0.'+$/."4"."'#
<memory> G."4"."'#$3,+$#"<&4"36"(@$<'<,+6$<%(%@'<'(.
<cwctype> N/(0.",(#$3,+$04%##"36"(@$%()$<%&&"(@$5")'$0!%+%0.'+#
<numeric> '<&4%.'$(/<'+"0$,&'+%.",(#
<queue> H/'/'$.'<&4%.'$0,(.%"('+
<set> L"(@4'?-%4/')$%()$</4."?-%4/')$#'.$.'<&4%.'$0,(.%"('+#
!"#$0,<&4'.'#$,/+$E/"07$,-'+-"'5$,3$.!'$L.%()%+)$122$4"=+%+6:$Z($.!'$;(.'+('.B$a"(7/<5%+'$,33'+#
<stack> L.%07$.'<&4%.'$0,(.%"('+ 0,<&4'.'$+'3'+'(0'$),0/<'(.%.",($3,+$.!'$L.%()%+)$122$4"=+%+6$%.
!..&O``555:)"(7/<5%+':0,<`+'3*0&&:!.<4B %()$LF;$!%#$%$0,<&+'!'(#"-'$L T$&+,@+%<<'+U#$@/")'
<utility> K%#"0$.'<&4%.'$3/(0.",(# %. !..&O``555:#@":0,<`.'0!`#.4`:$ !'$,33"0"%4$)'3"(".",($,3$.!'$L.%()%+)$122$4"=+%+6$"#$3,/()$"($.!'$1
%()$122$#.%()%+)#B$%-%"4%=4'$%#$_aN$3"4'#$,+ &%&'+$0,&"'#$3+,<$.!'$;(.'+(%.",(%4$Z+@%("Q%.",($3,+
<vector> j'0.,+$.'<&4%.'$0,(.%"('+ L.%()%+)"Q%.",($V;LZW:
;($.!"#$%&&'()"*B$5'$!%-'$0,-'+')$%$4,.$,3$@+,/()$%.$%$3%#.$&%0':$Y!'($6,/$#.%+.$4'%+("(@$H.$3+,<
1!%&.'+$AB$6,/$#!,/4)$3"()$.!%.$.!'$#6(.%*$"# %$4,.$#"<&4'+$%()$04'%+'+$.!%($.!"#$%&&'()"*$<"@!.$!%-'
#/@@'#.'):$F,,)$H.$&+,@+%<<"(@$,(46$+'E/"+'#$.!'$/#'$,3$%$#/=#'.$,3$122$%()$/#/%446$%-,")#$.!'
L"(0'$122$"#$'##'(."%446$%$#/&'+#'.$,3$.!'$1$&+,@+%<<"(@$4%(@/%@'B$122$&+,@+%<<'+#$%4#,$!%-'
('')$3,+$.!'$<,+'$0,<&4'*$%()$,=#0/+'$#6(.%*$.!%.$122$<%7'#$&,##"=4':$Z(0'$6,/$#.%+.$.6&"(@$"(
.!'$'(."+'$1$4"=+%+6$%.$.!'"+$)"#&,#%4:$ !'$1$!'%)'+$3"4'#$%+'$%-%"4%=4'$'".!'+$5".!$.!'"+$.+%)".",(%4
0,)'$%()$=/"4)"(@$%()$+/(("(@$'*'0/.%=4'#B$.!'$04%+".6$%()$#"<&4"0".6$,3$.!'$H.$%&&+,%0!$5"44$='0,<'
(%<'#$V3,+$'*%<&4'B <stdio.h>W$,+$5".!$('5?#.64'$(%<'#$5".!$% c?$&+'3"*$%()$(, .h$V3,+$'*%<&4'B
%&&%+'(.:$I()$%#$#,,($%#$6,/$#.%+.$5+"."(@$<,+'$%<=".",/#$&+,@+%<#B$'#&'0"%446$.!,#'$.!%.$('')$3%#.
<cstdio>W:$Y!'($5'$/#'$.!'$('5?#.64'$-'+#",(B$.!'$3/(0.",(#$%()$)%.%$.6&'#$%+'$)'04%+')$"($.!' std
%()$3%(06$@+%&!"0#B$.!'$122`H.$0,<="(%.",($5"44$0,(."(/'$.,$7''& &%0'$5".!$6,/+$('')#:
(%<'#&%0':$V !"#$),'#(U.$%&&46$.,$<%0+,#$#/0!$%# ASSERT()B$='0%/#'$.!'$&+'&+,0'##,+$"#$/(%5%+'$,3
(%<'#&%0'#:W$ !'$('5?#.64'$#6(.%*$"#$+'0,<<'()')$"3$6,/+$0,<&"4'+$#/&&,+.#$".:
Appendix. About the Authors
U360#4&'234."+%%+
8%#<"($@+%)/%.')$"($0,<&/.'+$#0"'(0'$"($]DDA$3+,<$.!'$G("-'+#".6$,3$L!'+?=+,,7'B$H/'='0:$['$)")$%
5,+7$.'+<$%.$ +,44.'0!$"($.!'$#/<<'+$,3$]DDD$%#$%$#,3.5%+'$'(@"(''+$%()$!%#$=''($5,+7"(@$.!'+'
0,(."(/,/#46$#"(0'$'%+46$]DDA:$;($]DDPB$8%#<"($0,?5+,.'233#EFG#=:-':)55&('#H&0!#I0#J !"#
$%&!'%()*$#+!,-#!.%/#+!%0!1.%//,#'-2+!3%'4(#$,5,*%$!(5$56#.!5$3!+#$*%.!+%0,&5.#!#$6*$##. !"#!&5+
,-#!3.*7*$6!0%.'#!)#-*$3!,-# !"#$%&'$(!!,.5$+/5,*%$!,%%/!5$3!*+!+,*//!5!8#9!:/59#.!*$!;,!<2+!'%$,5*$#.
'/5++#+ !"#!*+!5/+%!'%=#3*,%.!%0 !" ')*!+*,->!1.%//,#'-2+!,#'-$*'5/!$#&+/#,,#.
!"#$%&''(")*(+,
?5.8!6.5345,#3!*$!'%(:4,#.!+'*#$'#!*$!@AAB!0.%(!,-#!C$*7#.+*,9!%0!D5/#+!E&5$+#5 !"#!0%//%!,-*+
&*,-!5!9#5.2+!:%+,6.5345,#!.#+#5.'-!)#0%.#!6%*$6!*$,%!*$34+,.9 !"#!+:#$,!(5$9!9#5.+!&%.8*$6!5+!5
+%0,&5.#!#$6*$##.!0%.!5!75.*#,9!%0!0*.(+!)#0%.#!F%*$*$6!1.%//,#'- !"#!+:#$,!5/(%+,!,-.##!9#5.+!5+
1.%//,#'-2+!3%'4(#$,5,*%$!(5$56#.>!34.*$6!&-*'-!-#!0%4$3#3 !" ')*!+*,-!5$3!'%=&.%,# .//"012
3*4&*)55$%&"6$!7" !"8 !?5.8!%&$+!;,.5*$*$6 #4!5$3!&%.8+!5+!5$!*$3#:#$3#$,!,.5*$#.!5$3
'%$+4/,5$,!+:#'*5/*G*$6!*$!HII>!;,>!5$3!J9,-%$