Using Qt for GUI developmentUsing Qt for GUI development
Brad WhitlockBrad WhitlockMarch 2002March 2002
OutlineOutline
GUI toolkitsGUI toolkits What is Qt?What is Qt? Qt FeaturesQt Features Signals and slotsSignals and slots ExamplesExamples
– Creating a custom widgetCreating a custom widget– NetworkingNetworking
What makes a good What makes a good GUI Toolkit?GUI Toolkit? Implementation languageImplementation language Easy to programEasy to program
– Consistent interfaceConsistent interface– Little code for large resultsLittle code for large results
Excellent documentationExcellent documentation Availability of tools for code Availability of tools for code
generationgeneration PortabilityPortability Easy to extendEasy to extend
Some GUI ToolkitsSome GUI Toolkits
QtQt– Written in C++Written in C++– Qt programs are portableQt programs are portable– Object oriented. Allows your window to be encapsulated into a real C++ classObject oriented. Allows your window to be encapsulated into a real C++ class– Easy to hand codeEasy to hand code
GTKGTK– Written in CWritten in C– GTK programs are mostly limited to UNIX though GTK does exist on other platformsGTK programs are mostly limited to UNIX though GTK does exist on other platforms– Not object orientedNot object oriented
MotifMotif– Written in CWritten in C– Motif programs are limited to UNIXMotif programs are limited to UNIX– Not object orientedNot object oriented– Difficult to hand codeDifficult to hand code
MFCMFC– MFC programs are limited to WindowsMFC programs are limited to Windows
Qt BackgroundQt Background
Created and maintained by Created and maintained by Trolltech since 1995Trolltech since 1995
Now on version 3.0.2Now on version 3.0.2 Foundation of KDE a popular Foundation of KDE a popular
Linux desktop environmentLinux desktop environment
Qt is a C++ toolkit for cross-platform GUI and application development. It . It lets application developers target all lets application developers target all major operating systems with a single major operating systems with a single application source code.application source code.
Supported platformsSupported platforms– UNIXUNIX– MS Windows 9x/NT/2000/XPMS Windows 9x/NT/2000/XP– Mac OS XMac OS X– Embedded (PDA’s)Embedded (PDA’s)
What is Qt?
FeaturesFeatures
Fully object-orientedFully object-oriented Consistent interfacesConsistent interfaces Rich set of widgets (controls)Rich set of widgets (controls)
– Have native look and feelHave native look and feel– Drag and dropDrag and drop– Customizable appearanceCustomizable appearance
Utility classesUtility classes OpenGL supportOpenGL support Network supportNetwork support Database supportDatabase support Plugin supportPlugin support Unicode/Internationalization supportUnicode/Internationalization support GUI builderGUI builder
Utility classesUtility classes
This is a sample of the dozens of utility This is a sample of the dozens of utility classes provided by Qt.classes provided by Qt.
ContainersContainers– QString – String classQString – String class– QList – Template List classQList – Template List class– QMap – Template map classQMap – Template map class
ProgramProgram– QThread – Platform independent threadsQThread – Platform independent threads– QProcess – Launches processes and communicates with QProcess – Launches processes and communicates with
themthem
XMLXML– QXmlSimpleReader – Simple XML readerQXmlSimpleReader – Simple XML reader
WidgetsWidgets
A widget is a user interface component A widget is a user interface component such as a button or a scroll-barsuch as a button or a scroll-bar
Reusable!Reusable! Well defined interface Well defined interface Uses C++ inheritanceUses C++ inheritance All widgets derive from a common baseAll widgets derive from a common base Widgets may contain other widgetsWidgets may contain other widgets Custom widgets can be created from existing widgets Custom widgets can be created from existing widgets
or they can be created from scratchor they can be created from scratch
Qt Built-in WidgetsQt Built-in Widgets
Qt Built-in dialogsQt Built-in dialogs
File dialogFile dialog Font dialogFont dialog Color dialogColor dialog Printer dialogPrinter dialog
OpenGL SupportOpenGL Support
QGLWidgetQGLWidget Subclass of QWidget so it Subclass of QWidget so it
behaves like any other QWidgetbehaves like any other QWidget Gives you access to the OpenGL Gives you access to the OpenGL
contextcontext Can make raw OpenGL function Can make raw OpenGL function
callscalls
Network supportNetwork support
Remote files accessed using the FTP Remote files accessed using the FTP and HTTP protocolsand HTTP protocols
New protocols can be implemented by New protocols can be implemented by subclassing QNetworkProtocolsubclassing QNetworkProtocol
Inter-process communication and Inter-process communication and socket-based TCP and UDP networking socket-based TCP and UDP networking are also fully supportedare also fully supported
QSocket and QServerSocket provide QSocket and QServerSocket provide socket communicationsocket communication
Database supportDatabase support
Cross platform Cross platform interface for interface for accessing SQL accessing SQL databasesdatabases
Supported DatabasesSupported Databases– OracleOracle– Microsoft SQL ServerMicrosoft SQL Server– Sybase Adaptive ServerSybase Adaptive Server– PostgreSQLPostgreSQL– MySQLMySQL– ODBCODBC
Any Qt widget can be Any Qt widget can be made data awaremade data aware
SQL module fully SQL module fully integrated into integrated into Qt designerQt designer
Plugin supportPlugin support
Style pluginsStyle plugins Image readers/writersImage readers/writers Widget pluginsWidget plugins Netscape pluginsNetscape plugins
Unicode/InternationalizationUnicode/Internationalization
Programmer can freely Programmer can freely mix any language mix any language supported by Unicodesupported by Unicode
Includes tools to support Includes tools to support application translationapplication translation– Qt LinguistQt Linguist
Can identify strings that Can identify strings that need translation in the need translation in the source code using tr()source code using tr()– Button-Button-
>setText(tr(“Save”));>setText(tr(“Save”));
Qt DesignerQt Designer
Written using Qt Written using Qt so it is available so it is available on all platforms on all platforms where Qt is where Qt is availableavailable
Used to speed Used to speed design of Qt design of Qt applicationsapplications
Supports all Qt Supports all Qt widgets and can widgets and can be used to be used to incorporate incorporate custom widgetscustom widgets
Hello World!Hello World!
#include <qapplication.h>#include <qapplication.h>
#include <qlabel.h>#include <qlabel.h>
intint main( main(intint argc, argc, charchar *argv[]) *argv[])
{{
// Create an application object// Create an application object
QApplication *app = QApplication *app = newnew QApplication(argc, QApplication(argc, argv);argv);
// Create a label// Create a label
QLabel *label = QLabel *label = newnew QLabel(“Hello World!”, QLabel(“Hello World!”, 0, “label”);0, “label”);
app->setMainWidget(label);app->setMainWidget(label);
// Show the label and enter the main loop// Show the label and enter the main loop
label->show();label->show();
int int ret =ret = app->exec();app->exec();
// Clean up omitted// Clean up omitted
return ret;return ret;
}}
QApplicationQApplication Manages widget style, Manages widget style,
colors, global colors, global preferencespreferences
Operates main event Operates main event loop and dispatches loop and dispatches events to other events to other objectsobjects
Using LayoutsUsing Layouts
Layouts should be used to manage Layouts should be used to manage widget position and resize behaviorwidget position and resize behavior
Layout typesLayout types– HorizontalHorizontal– VerticalVertical– GridGrid
Layouts can be nestedLayouts can be nested User can control layout spacing, User can control layout spacing,
stretch, and strutstretch, and strut
Signals and SlotsSignals and Slots
Facilitates inter-object communicationFacilitates inter-object communication Replaces callback mechanism found in older Replaces callback mechanism found in older
toolkitstoolkits Type safe since arguments for signal must Type safe since arguments for signal must
match arguments slotmatch arguments slot Objects don’t have to care about other Objects don’t have to care about other
objects.objects. Can be overloaded or re-implemented in Can be overloaded or re-implemented in
subclassessubclasses Signals can be connected to multiple slots or Signals can be connected to multiple slots or
other signalsother signals
Signals and Slots 2Signals and Slots 2
An object emits a signal with a certain An object emits a signal with a certain prototypeprototype
Other objects may be connected to that Other objects may be connected to that object’s signalobject’s signal– connectconnect(button, (button, SIGNALSIGNAL(clicked()), qApp, (clicked()), qApp, SLOTSLOT(quit()));(quit()));
The slot functions for all the connected The slot functions for all the connected objects are calledobjects are called
Signals and Slots 3Signals and Slots 3
ExampleExample
classclass BankAccount : BankAccount : publicpublic QObject QObject{{ Q_OBJECTQ_OBJECTPublicPublic:: BankAccount() { curBalance = 0; }BankAccount() { curBalance = 0; } intint balance() balance() constconst { { returnreturn curBalance; } curBalance; }signalssignals:: voidvoid balanceChanged( balanceChanged(intint newBalance); newBalance);publicpublic slotsslots:: voidvoid setBalance( setBalance(intint newBalance) { newBalance) { ifif(curBalance != newBalance) {(curBalance != newBalance) { curBalance = newBalance;curBalance = newBalance; emitemit balanceChanged(curBalance); balanceChanged(curBalance); }} }}privateprivate:: intint curBalance; curBalance;}; };
UsageUsage
// Create 2 accounts that have zero balance// Create 2 accounts that have zero balanceBankAccount x, y;BankAccount x, y;
// Connect account x to account y so that // Connect account x to account y so that // whenever it gets money, account y gets// whenever it gets money, account y gets// the same amount.// the same amount.connectconnect(&x, (&x, SIGNALSIGNAL(balanceChanged(int)),(balanceChanged(int)), &y, &y, SLOTSLOT(setBalance(int)));(setBalance(int)));
// Set the balance for account x// Set the balance for account xx.setBalance(2450);x.setBalance(2450);
// Account y also now has $2450// Account y also now has $2450
Building classes that have Building classes that have signals and slotssignals and slots
Class definition must contain Class definition must contain Q_OBJECTQ_OBJECT macro macro Slots are defined with Slots are defined with slotsslots “keyword” “keyword”
– Can be declared public, protected, privateCan be declared public, protected, private Signals are declared with Signals are declared with signalssignals “keyword” “keyword”
– Qt provides the body for a signal functionQt provides the body for a signal function MOC preprocessorMOC preprocessor
– Reads class header file and creates supplementary C++ Reads class header file and creates supplementary C++ code to support signals/slotscode to support signals/slots
– All header files for classes defining signals/slots need to All header files for classes defining signals/slots need to use MOCuse MOC
– Easily incorporated into Make rulesEasily incorporated into Make rules– Transparent to userTransparent to user
Creating a custom Creating a custom widgetwidget
Derive from the Derive from the base classbase class– Provide all relevant Provide all relevant
behavior by overriding behavior by overriding or adding member or adding member functionsfunctions
Derive from an Derive from an existing classexisting class– Customize behavior Customize behavior
by overriding by overriding member functionsmember functions
Simple custom widgetSimple custom widget
#ifndef SIMPLE_H#ifndef SIMPLE_H#define SIMPLE_H#define SIMPLE_H#include <qwidget.h>#include <qwidget.h>#include <qtimer.h>#include <qtimer.h>#include <qpainter.h>#include <qpainter.h>#include <qpointarray.h>#include <qpointarray.h>
classclass Simple : Simple : publicpublic QWidget QWidget{{ Q_OBJECTQ_OBJECTpublicpublic:: Simple(QWidget *parent, Simple(QWidget *parent, const charconst char
*name) : QWidget(parent, name), *name) : QWidget(parent, name), shape(4)shape(4)
{{ angle = 0.;angle = 0.; timer = timer = newnew QTimer( QTimer(thisthis,"timer");,"timer"); connectconnect(timer, (timer, SIGNALSIGNAL(timeout()),(timeout()), thisthis, , SLOTSLOT(rotateAngle()));(rotateAngle())); shape.setPoint(0, QPoint(-50, -50));shape.setPoint(0, QPoint(-50, -50)); shape.setPoint(1, QPoint(50, -50));shape.setPoint(1, QPoint(50, -50)); shape.setPoint(2, QPoint(50, 50));shape.setPoint(2, QPoint(50, 50)); shape.setPoint(3, QPoint(-50, 50));shape.setPoint(3, QPoint(-50, 50)); setMinimumSize(200,200);setMinimumSize(200,200); }}
virtualvirtual ~Simple() { timer->stop(); }; ~Simple() { timer->stop(); }; virtualvirtual QSize sizeHint() { QSize sizeHint() { returnreturn
QSize(200,200); };QSize(200,200); };
publicpublic slotsslots:: virtual voidvirtual void show() { timer->start(50); QWidget::show(); } show() { timer->start(50); QWidget::show(); } virtual voidvirtual void hide() { timer->stop(); QWidget::hide(); } hide() { timer->stop(); QWidget::hide(); }protectedprotected:: virtual voidvirtual void paintEvent(QPaintEvent *pe) { paintEvent(QPaintEvent *pe) { QPainter paint(QPainter paint(thisthis);); paint.setBrush(QColor(0,0,255));paint.setBrush(QColor(0,0,255)); QWMatrix m1; m1.rotate(-angle);QWMatrix m1; m1.rotate(-angle); QWMatrix m2; m2.translate(width()/2,height()/2);QWMatrix m2; m2.translate(width()/2,height()/2); QWMatrix m3 = m1*m2;QWMatrix m3 = m1*m2; paint.setWorldMatrix(m3, TRUE);paint.setWorldMatrix(m3, TRUE); paint.drawPolygon(shape);paint.drawPolygon(shape); }}privateprivate slotsslots:: voidvoid rotateAngle() { rotateAngle() { angle += 3.;angle += 3.; ifif(angle >= 360.) angle -= 360.;(angle >= 360.) angle -= 360.; update();update(); }}privateprivate:: QTimer *timer;QTimer *timer; double angle;double angle; QPointArray shape;QPointArray shape;};};#endif#endif
Simple custom widget Simple custom widget 22#include <Simple.h>#include <Simple.h>#include <qapplication.h>#include <qapplication.h>#include <qvbox.h>#include <qvbox.h>#include <qpushbutton.h>#include <qpushbutton.h>
intintmain(main(intint argc, argc, charchar *argv[]) *argv[]){{ QApplication *app = QApplication *app = newnew QApplication(argc, argv); QApplication(argc, argv); QVBox *top = QVBox *top = newnew QVBox; QVBox; app->setMainWidget(top);app->setMainWidget(top);
Simple *s = Simple *s = newnew Simple(top, "simple"); Simple(top, "simple"); QPushButton *btn = QPushButton *btn = newnew QPushButton("Quit", top, QPushButton("Quit", top,
"btn");"btn"); app->app->connectconnect(btn, (btn, SIGNALSIGNAL(clicked()),(clicked()), qApp, qApp, SLOTSLOT(quit()));(quit()));
top->show();top->show();
intint ret = app->exec(); ret = app->exec(); deletedelete top; top; deletedelete app; app;
returnreturn ret; ret;}}
Simple networking Simple networking exampleexampleClassClass MessagePrinter : MessagePrinter : publicpublic QObject QObject{{ Q_OBJECTQ_OBJECTPublicPublic:: MessagePrinter(MessagePrinter(constconst QString &host, QString &host, intint port) : QObject() port) : QObject() {{ // Create a new socket and connect to a port.// Create a new socket and connect to a port. S = S = newnew QSocket( QSocket(thisthis);); connectconnect(S, (S, SIGNALSIGNAL(readyRead()),(readyRead()), thisthis, , SLOTSLOT(readMessage()));(readMessage())); S->connectToHost(host, port);S->connectToHost(host, port); }}
virtualvirtual ~MessagePrinter() { S->close(); }; ~MessagePrinter() { S->close(); };PrivatePrivate slotsslots:: voidvoid readMessage() readMessage() {{ if(S->canReadLine())if(S->canReadLine()) {{ qDebug(“MSG=%s”, S->readLine().latin1());qDebug(“MSG=%s”, S->readLine().latin1()); S->close();S->close(); }} }}PrivatePrivate:: QSocket *S;QSocket *S;};};
VisItVisIt
Developed here Developed here at LLNLat LLNL
Uses Qt 2.3 or Uses Qt 2.3 or greatergreater
Hand coded Hand coded windowswindows
Custom widgetsCustom widgets OpenGLOpenGL Uses some Qt Uses some Qt
networking networking codecode
Qt licensingQt licensing
Qt Free EditionQt Free Edition– For UNIX/X11For UNIX/X11– Version 2.2 and laterVersion 2.2 and later– Open source license QPL and GPLOpen source license QPL and GPL– May be freely copied and distributedMay be freely copied and distributed– Binaries may be redistributedBinaries may be redistributed
Users creating closed source projects Users creating closed source projects must purchase a development license must purchase a development license from Trolltechfrom Trolltech
Where to find QtWhere to find Qt
On the WebOn the Web– http://www.trolltech.comhttp://www.trolltech.com
On LC computersOn LC computers– /usr/gapps/visit/qt/current/<platform>//usr/gapps/visit/qt/current/<platform>/