C++ GUI Programming with Qt 4 C++ GUI Programming with Qt 4 Jasmin Blanchette Mark Summerfield In association with Trolltech Press Upper Saddle River, NJ Boston Indianapolis San Francisco New York Toronto Montreal London Munich Paris Madrid Capetown Sydney Tokyo Singapore Mexico City Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks Where those designations appear in this book, and the publisher was aware of a trademark claim, the.
C++ GUI Programming with Qt C++ GUI Programming with Qt Jasmin Blanchette Mark Summerfield In association with Trolltech Press Upper Saddle River, NJ · Boston · Indianapolis · San Francisco New York · Toronto · Montreal · London · Munich · Paris · Madrid Capetown · Sydney · Tokyo · Singapore · Mexico City Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks Where those designations appear in this book, and the publisher was aware of a trademark claim, the designations have been printed with initial capital letters or in all capitals The authors and publisher have taken care in the preparation of this book, but make no expressed or implied warranty of any kind and assume no responsibility for errors or omissions No liability is assumed for incidental or consequential damages in connection with or arising out of the use of the information or programs contained herein The publisher offers excellent discounts on this book when ordered in quantity for bulk purchases or special sales, which may include electronic versions and/or custom covers and content particular to your business, training goals, marketing focus, and branding interests For more information, please contact: U.S Corporate and Government Sales (800) 382-3419 corpsales@pearsontechgroup.com For sales outside the United States, please contact: International Sales international@pearsoned.com Visit us on the Web: www.prenhallprofessional.com This Book Is Safari Enabled The Safari Enabled icon on the cover of your favorite technology book means the book is available through Safari Bookshelf When you buy this book, you get free access to the online edition for 45 days Safari Bookshelf is an electronic reference library that lets you easily search thousands of technical books, find code samples, download chapters, and access technical information whenever and wherever you need it To gain 45-day Safari Enabled access to this book: • Go to http://www.prenhallprofessional.com/safarienabled • Complete the brief registration form • Enter the coupon code FTMP-7EXM-TI8P-6GM1-3Y85 If you have difficulty registering on Safari Bookshelf or accessing the online edition, please e-mail customer-service@safaribooksonline.com Library of Congress Cataloging-in-Publication Data Blanchette, Jasmin C++ GUI programming with Qt / Jasmin Blanchette, Mark Summerfield p cm Includes bibliographical references and index ISBN 0-13-187249-4 (pbk.: alk paper) Graphical user interfaces (Computer systems) C++ (Computer program language) I Summerfield, Mark II Title QA76.9.U83B532 2006 005.4’37—dc22 2006013376 Copyright © 2006 Trolltech AS All rights reserved Printed in the United States of America This publication may only be distributed subject to the terms and conditions set forth in the Open Publication License, v1.0 or later (the latest version is available at http://www.open-content.org/openpub/) Trolltech, Qt, Qtopia, and the Trolltech and Qtopia logos are registered trademarks of Trolltech AS ISBN 0-13-187249-4 Text printed in the United States on recycled paper at Courier in Stoughton, Massachusetts First printing, June 2006 Contents Foreword ix Preface xi Acknowledgments xiii A Brief History of Qt xv Part I: Basic Qt Getting Started Hello Qt Making Connections Laying Out Widgets Using the Reference Documentation 3 Creating Dialogs Subclassing QDialog Signals and Slots in Depth Rapid Dialog Design Shape-Changing Dialogs Dynamic Dialogs Built-in Widget and Dialog Classes 13 13 20 23 29 36 37 Creating Main Windows Subclassing QMainWindow Creating Menus and Toolbars Setting Up the Status Bar Implementing the File Menu Using Dialogs Storing Settings Multiple Documents Splash Screens 43 44 48 52 54 61 67 68 71 v Implementing Application Functionality The Central Widget Subclassing QTableWidget Loading and Saving Implementing the Edit Menu Implementing the Other Menus Subclassing QTableWidgetItem 73 73 74 80 83 87 91 Creating Custom Widgets Customizing Qt Widgets Subclassing QWidget Integrating Custom Widgets with Qt Designer Double Buffering 101 101 103 113 116 Part II: Intermediate Qt Layout Management Laying Out Widgets on a Form Stacked Layouts Splitters Scrolling Areas Dock Widgets and Toolbars Multiple Document Interface 137 137 143 145 148 150 152 Event Processing Reimplementing Event Handlers Installing Event Filters Staying Responsive During Intensive Processing 163 163 168 171 2D and 3D Graphics Painting with QPainter Painter Transformations High-Quality Rendering with QImage Printing Graphics with OpenGL 175 175 180 188 190 198 Drag and Drop Enabling Drag and Drop Supporting Custom Drag Types Clipboard Handling 205 205 210 215 vi 10 Item View Classes Using the Item View Convenience Classes Using Predefined Models Implementing Custom Models Implementing Custom Delegates 217 218 225 230 244 11 Container Classes Sequential Containers Associative Containers Generic Algorithms Strings, Byte Arrays, and Variants 251 252 260 263 265 12 Input/Output Reading and Writing Binary Data Reading and Writing Text Traversing Directories Embedding Resources Inter-Process Communication 273 274 279 285 286 287 13 Databases Connecting and Querying Presenting Data in Tabular Form Implementing Master–Detail Forms 293 294 299 304 14 Networking Writing FTP Clients Writing HTTP Clients Writing TCP Client–Server Applications Sending and Receiving UDP Datagrams 311 311 320 323 333 15 XML Reading XML with SAX Reading XML with DOM Writing XML 339 339 344 348 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 351 351 353 356 vii Part III: Advanced Qt 17 Internationalization Working with Unicode Making Applications Translation-Aware Dynamic Language Switching Translating Applications 361 362 365 371 376 18 Multithreading Creating Threads Synchronizing Threads Communicating with the Main Thread Using Qt’s Classes in Secondary Threads 381 381 385 391 396 19 Creating Plugins Extending Qt with Plugins Making Applications Plugin-Aware Writing Application Plugins 399 400 408 412 20 Platform-Specific Features Interfacing with Native APIs Using ActiveX on Windows Handling X11 Session Management 415 415 419 431 21 Embedded Programming Getting Started with Qtopia Customizing Qtopia Core 439 440 441 Appendices A Installing Qt 447 B Introduction to C++ for Java and C# Programmers 451 Index 493 viii Foreword Why Qt? Why programmers like us choose Qt? Sure, there are the obvious answers: Qt’s single-source compatibility, its feature richness, its C++ performance, the availability of the source code, its documentation, the high-quality technical support, and all the other items mentioned in Trolltech’s glossy marketing materials This is all very well, but it misses the most important point: Qt is successful because programmers like it How come programmers like one technology, but dislike another? Personally I believe software engineers enjoy technology that feels right, but dislike everything that doesn’t “Feels right” means many things In the Qt edition of the book, I mentioned Trolltech’s phone system as a particularly good example of some particularly bad technology The phone system didn’t feel right, because it forced us to apparently random things depending on some equally random context Randomness doesn’t feel right Another thing that doesn’t feel right is repetitiveness and redundancy Good programmers are lazy What we love about computers compared to, say, gardening is that we don’t have to the same things over and over Let me emphasize this point with a real-world example: travel reimbursement forms Typically those forms come as fancy spreadsheets; you fill them out, and you get real money Simple technology, one should think, and given the monetary incentive this should be a simple task for a grown-up engineer Reality looks different, though While nobody else in the company seems to have any problems whatsoever dealing with those forms, the engineers And having talked to people in other companies, this seems to be a common pattern We defer reimbursement until the very last moment, and sometimes we might even forget about it Why is that? Looking at our form, it’s a straightforward, standard procedure One has to collect receipts, number them, and put those numbers into the proper fields with the date, the location, a description, and the amount The numbering and copying is designed to ease someone’s work, but strictly speaking it is redundant, given that the date, location, description, and amount unambiguously identify a receipt A tiny bit of extra work to get your money back, one would think A small annoyance is the per-diem rate, though, which depends on the travel location There’s some separate document somewhere that lists the standardized rates for all the different travel locations You can’t just select “Chicago”; instead you have to look up the rate for Chicago yourself There’s a similar annoyance with the exchange rate field One has to find the current exchange rate somewhere—perhaps with Google’s help—and then enter the rate in evix ery single field Well, strictly speaking, you should wait for your credit card company to issue a statement to you with the actual exchange rate that they used While this is not hard to do, looking up different pieces of information from different sources, and then copying the relevant items to several places in the form feels needlessly awkward Programming can be a lot like filling in travel reimbursement forms, only worse And this is where Qt comes to the rescue Qt is different For one thing, Qt makes sense And for another, Qt is fun Qt lets you concentrate on your tasks When Qt’s original architects faced a problem, they didn’t just look for a good solution, or the simplest solution They looked for the right solution, and then they documented it Granted they made mistakes, and granted some of their design decisions didn’t pass the test of time, but they still got a lot of things right, and what wasn’t right could and can be corrected You can see this by the fact that a system originally designed to bridge Windows 95 and Unix/Motif now unifies modern desktop systems as diverse as Windows XP, Mac OS X, and GNU/Linux, and provides the foundation for the Qtopia application platform for embedded Linux Long before Qt became so popular and so widely used, the dedication of Qt’s developers to finding the right solutions made Qt special That dedication is just as strong today and affects everyone who develops and maintains Qt For us, working on Qt is a responsibility and a privilege We are proud of helping to make your professional and open source lives easier and more enjoyable Matthias Ettrich Oslo, Norway June 2006 x ... Embedded Programming Getting Started with Qtopia Customizing Qtopia Core 43 9 44 0 44 1... called Qt/ Embedded) in 2000 It was designed to run on embedded Linux devices and provided its own window system as a lightweight replacement for X11 Both Qt/ X11 and Qtopia Core were now offered... that were introduced with Qt 4. 1) and to present code that shows good idiomatic Qt programming techniques In many cases, we have used examples similar to the ones used in the Qt edition This will