By Matthias Kalle Dalheimer
Price: $39.95 USD
£28.50 GBP
Cover | Table of Contents | Colophon
http://www.trolltech.com/purchase/.
When ordering, you can decide whether you want to get Qt delivered
via normal mail on CD or if you would prefer to
download it from the vendor's FTP server.ftp://ftp.trolltech.com/qt/source
.
You will have to compile the source code yourself, as explained
in the next section. If you are unsure of which file to obtain, go to
http://www.trolltech.com/products/download/ for guidance to the file you need.zcat qt-x11-3.0.1.tar.gz | tar xvf -
tar xvzf qt-x11-3.0.1.tar.gz
set... (e.g., setText()), while
get methods have no prefix (not even get—,
e.g., text()). This is fairly basic stuff;
there's no sophistication involved here.http://www.kde.org) mailing lists are
populated with some very experienced
Qt developers, too, so you can ask for help there if you are writing
a KDE application. Remember that most KDE programmers do their work
voluntarily in their spare time, so please be polite and do not
demand quick answers.
Please see the web site
http://www.kde.org/mailinglists.html for
information about which lists exist and how to subscribe to them.#include <qapplication.h>
#include <qlabel.h>
int main( int argc, char* argv[] )
{
QApplication myapp( argc, argv );
QLabel* mylabel = new QLabel( "Hello, world", 0 );
mylabel->resize( 120, 30 );
myapp.setMainWidget( mylabel );
mylabel->show();
return myapp.exec();
}QListView and QListViewItem in qlistview.h. When
in doubt, check the documentation. Shortly, we'll cover how the Qt
reference documentation is organized. In this example,
qapplication.h is for
the class QApplication and qlabel.h is
for QLabel.QApplication is
created. Every Qt application must have exactly one object of
class QApplication.
This object is responsible for all event handling and it holds
everything together. It also provides some useful methods (member
functions), which we'll talk about later.#include <qapplication.h>
#include <qlabel.h>
int main( int argc, char* argv[] )
{
QApplication myapp( argc, argv );
QLabel* mylabel = new QLabel( "Hello, world", 0 );
mylabel->resize( 120, 30 );
myapp.setMainWidget( mylabel );
mylabel->show();
return myapp.exec();
}QListView and QListViewItem in qlistview.h. When
in doubt, check the documentation. Shortly, we'll cover how the Qt
reference documentation is organized. In this example,
qapplication.h is for
the class QApplication and qlabel.h is
for QLabel.QApplication is
created. Every Qt application must have exactly one object of
class QApplication.
This object is responsible for all event handling and it holds
everything together. It also provides some useful methods (member
functions), which we'll talk about later.QApplication object.
This step is done because QApplication accepts some
special command-line arguments, which it handles and removes later
from the command-line variables. Your application
never sees these special command-line arguments. Among
them are -style, which tells Qt which
widget style to use by default; and -nograb,
which tells Qt never to grab the mouse or the keyboard to facilitate
debugging. If your application interprets its own command-line
parameters, make sure to interpret them after having passed the
command line to assistant (assuming that you have installed Qt
correctly as described in the previous chapter). It is fairly
self-explanatory, so we will concentrate on guiding you through
the Qt documentation using a web browser here (Qt Assistant has a
browser-like view, so you can even follow what we describe here
with Qt Assistant, if you like).
QPushButton—a subclass
of QButton, which itself is a subclass of QWidget,
the base class for all Qt UI elements. Besides showing how to create
a push button, which is not very different from
the label we created two sections ago, this example gives you a
first impression of how to react to user interaction in Qt. The
first task will be very simple: when the user presses the button
(which will ingeniously be labeled "Quit"), the whole program
will terminate. Before we start explaining, you should look at the program
in Example 2-2 and its output
in Figure 2-4.#include <qapplication.h> #include <qlabel.h> #include <qpushbutton.h> int main( int argc, char* argv[] ) { QApplication myapp( argc, argv ); QWidget* mywidget = new QWidget; mywidget->setGeometry( 400, 300, 120, 90 ); QLabel* mylabel = new QLabel( "Hello world", mywidget ); mylabel->setGeometry( 10, 10, 80, 30 ); QPushButton* myquitbutton = new QPushButton( "Quit", mywidget ); myquitbutton->setGeometry( 10, 50, 100, 30 ); QObject::connect( myquitbutton, SIGNAL(clicked()), &myapp, SLOT(quit()) ); myapp.setMainWidget( mywidget ); mywidget->show(); return myapp.exec(); }
mywidget.
It is an object of the class QWidget, meaning
that it has no special widget properties, but knows about all the
general things that widgets can do, such as resizing and moving.QLabel object
and the QPushButton object,
we pass the address of QPainter,
which encapsulates Qt's drawing routines. At the end
of this section, we will have a small program for scribbling your
own drawings in a predefined color. You will also learn a bit about
handling low-level events.QPainter is
one of Qt's strengths. It is a class that bundles many
highly optimizing routines for drawing graphical objects such as
lines, circles, and Bézier curves. In addition, it supports different
coordinate systems and geometrical transformations including rotating,
scaling, and shearing. Furthermore, it supports the use of these operations
with widgets, pixmaps, metafiles, and printers alike.QWidget anyway
to handle the redisplay, and if you already have derived your own
class, it does not matter much if you override some virtual methods
for low-level events such as mouse movements and key presses.QMenuBar and QPopupMenu.
Both are derived from a common base class, QMenuData.
Thus, working with menu bars and pop-up menus
is very similar. A menu bar serves as a container for its menus,
which are just objects of the type QPopupMenu. These
menus can have other submenus, which are also objects of type QPopupMenu.
In addition, you can also use pop-up menus (also called contextual menus) directly,
for example, when the user presses the right mouse button.#include <qapplication.h> #include <qmenubar.h> #include <qmessagebox.h> #include <qpainter.h> #include <qpixmap.h> #include <qpopupmenu.h> #include <qwidget.h> enum MenuIDs{ COLOR_MENU_ID_BLACK, COLOR_MENU_ID_RED, COLOR_MENU_ID_BLUE, COLOR_MENU_ID_GREEN, COLOR_MENU_ID_YELLOW }; /** * A class that lets the user draw with the mouse. The * window knows how to redraw itself. */ class ScribbleWindow : public QWidget { Q_OBJECT // necessary because ScribbleWindow contains slots public: ScribbleWindow(); ~ScribbleWindow(); protected: virtual void mousePressEvent( QMouseEvent* ); virtual void mouseMoveEvent( QMouseEvent* ); virtual void paintEvent( QPaintEvent* ); virtual void resizeEvent( QResizeEvent* );
QMenuBar and QPopupMenu.
Both are derived from a common base class, QMenuData.
Thus, working with menu bars and pop-up menus
is very similar. A menu bar serves as a container for its menus,
which are just objects of the type QPopupMenu. These
menus can have other submenus, which are also objects of type QPopupMenu.
In addition, you can also use pop-up menus (also called contextual menus) directly,
for example, when the user presses the right mouse button.#include <qapplication.h> #include <qmenubar.h> #include <qmessagebox.h> #include <qpainter.h> #include <qpixmap.h> #include <qpopupmenu.h> #include <qwidget.h> enum MenuIDs{ COLOR_MENU_ID_BLACK, COLOR_MENU_ID_RED, COLOR_MENU_ID_BLUE, COLOR_MENU_ID_GREEN, COLOR_MENU_ID_YELLOW }; /** * A class that lets the user draw with the mouse. The * window knows how to redraw itself. */ class ScribbleWindow : public QWidget { Q_OBJECT // necessary because ScribbleWindow contains slots public: ScribbleWindow(); ~ScribbleWindow(); protected: virtual void mousePressEvent( QMouseEvent* ); virtual void mouseMoveEvent( QMouseEvent* ); virtual void paintEvent( QPaintEvent* ); virtual void resizeEvent( QResizeEvent* ); private slots: void slotAbout(); void slotAboutQt(); void slotColorMenu( int ); private: QPoint _last; QColor _currentcolor;
QScrollView, which allows you
to add scrollbars to your programs easily. Just specify the
widget you want to make scrollable, and QScrollView does
the rest for you. You can specify whether the scrollbars should
always be visible, off (in this case, you will have to provide
another means of scrolling, such as with the keyboard), or automatic.
Automatic scrollbars are only visible when the visible area of
the scrolled widget is smaller than the widget itself; in other
words, when there is something to scroll.QScrollView to
our painting application.#include <qapplication.h> #include <qmenubar.h> #include <qmessagebox.h> #include <qpainter.h> #include <qpixmap.h> #include <qpopupmenu.h> #include <qscrollview.h> #include <qwidget.h> enum MenuIDs{ COLOR_MENU_ID_BLACK, COLOR_MENU_ID_RED, COLOR_MENU_ID_BLUE, COLOR_MENU_ID_GREEN, COLOR_MENU_ID_YELLOW }; /** * A class that lets the user draw scribbles with the mouse. The * window knows how to redraw itself. */ class ScribbleArea : public QWidget { Q_OBJECT // necessary because ScribbleArea contains a slot public: ScribbleArea(); ~ScribbleArea(); public slots: void setColor( QColor ); protected: virtual void mousePressEvent( QMouseEvent* ); virtual void mouseMoveEvent( QMouseEvent* ); virtual void paintEvent( QPaintEvent* ); virtual void resizeEvent( QResizeEvent* ); private: QPoint _last; QColor _currentcolor; QPixmap _buffer; }; class ScribbleWindow : public QWidget { Q_OBJECT public: ScribbleWindow(); ~ScribbleWindow(); private slots: void slotAbout(); void slotAboutQt(); void slotColorMenu( int );
Clear, which wipes the entire
drawing off the screen.QPopupMenu. The only difference
is that you do not attach them to a QMenuBar object
by calling insertItem(). Instead, you create
a QPopupMenu and show it later by calling either exec() or popup().
The former performs a blocking popup of a pop-up
menu, which means that the method call returns only when the menu
was popped down again either by selecting a menu entry or by
clicking somewhere else. In contrast, popup() pops
up the menu and the method call
returns immediately.activated( int ) and highlighted(
int ). In addition, when you pop up the menu in a blocked
way via exec(), this method returns the item
number of the item selected. It returns -1 if
no item has been selected because the menu has been popped down
by clicking somewhere else.QPopupMenu makes
it very easy to do this because both exec() and popup() accept
a QPoint as the first parameter that indicates
the global coordinates of the pop-up
menu (where 0,0 is the top left corner of the screen).QCursor::pos(),
all you have to do in response to a mouseclick is call:mypopupmenu->exec( QCursor::pos() );
QFileDialog,
so you don't have to roll your own. Actually, the static methods
getOpenFileName() and
getSaveFileName() will do almost all of the work.QPixmap and QPixmap provides a method save() for
storing the data in one of several supported file formats.QPicture object
instead of a QPixmap. We mentioned this option before
as a way to manage off-screen data. Like QPixmap, QPicture has
a save() method. QPicture uses
a file format of its own, which is portable across all platforms
that Qt supports, but cannot be read by any non-Qt application.
The difference between the QPixmap variant and
the QPicture variant is mainly one of storing
pixel data or storing vector-based graphics data. The goals
of your application will determine what the best option is. For
our application, it does not really matter, but since we use
a large virtual drawing area, a vector-based file
format would probably be more space efficient. On the other
hand, saving with QPixmap requires using a well-known
file format so you can check the results of the save operation
with tools such as MS Paint on Windows
or pixmap on Unix systems. Therefore, we have
decided to use QPixmap for the save operations
here.#include <qapplication.h>
#include <qfiledialog.h>
#include <qmenubar.h>
#include <qmessagebox.h>
#include <qpainter.h>
#include <qpixmap.h>
#include <qpopupmenu.h>
#include <qscrollview.h>
#include <qwidget.h>
#include <qcursor.h>
enum MenuIDs{
COLOR_MENU_ID_BLACK,
COLOR_MENU_ID_RED,
COLOR_MENU_ID_BLUE,
COLOR_MENU_ID_GREEN,
COLOR_MENU_ID_YELLOW };
/**
* A class that lets the user draw with the mouse. The
* window knows how to redraw itself.
*/
class ScribbleArea : public QWidget
{
Q_OBJECT // necessary because ScribbleArea contains slots
public:
ScribbleArea();
~ScribbleArea();
public slots:
void setColor( QColor );
| Widget | Description | Section |
|---|---|---|
QButton
|
A common base class for button-like widgets
|
See Section 4.3.
|
QButtonGroup
|
Organizes QButton widgets in a group
|
See Section 4.8.2.
|
QCanvasView
|
A widget that displays a canvas with items on it
|
See Section 9.7 in Chapter 9.
|
QWidget for these methods.
The method setEnabled(), which accepts a bool parameter
for influencing whether a widget is available for user interaction,
is very useful. Enabling and disabling widgets, depending on the
situation, is very important for creating good user
interfaces. Disabled widgets are displayed "grayed out." All
too often, you see programs in which you can choose some settings,
and then you are told "Sorry, this choice is not possible."
Worse, you may be offered choices that have absolutely no effect.
These choices waste the user's time. Remember this when you design
your application—your users will thank you for it.setFont(), and the palette for drawing,
which is set with setPalette() (you can learn more
about palettes in Section 9.3.3 in Chapter 9).QWidget* that
specifies the parent, a name (see Chapter 21 to find out how this
is used), and widget flags, which only apply
to top-level widgets and are rarely needed even for them.
You can create a top-level widget without passing any parameters
to the constructor because all three parameters usually default to 0. You can create any other widget simply by passing
the parent.QPushButton.
Any additional parameters usually come before the
standard ones.setStyle() on
the widget object and passing a pointer to an object of a class that inherits from
QStyle. The two most frequently used subclasses are
QWindowsStyle and QMotifStyle,
but there is also QCDEStyle (which emulates the
look and feel of the Common Desktop Environment in a way that's similar to
QMotifStyle), QMotifPlusStyle (a
Motif-like style with better bevelling and highlighting buttons when the
mouse rolls over them), QSGIStyle (a Motif-like style
that looks like systems running the Unix-variant Irix from Silicon
Graphics), and QPlatinumStyle (which emulates the
look of the standard style of the Java Swing toolkit). Qt/Embedded also includes QCompactStyle, which is similar to
QWindowsStyle, but which occupies less screen
real estate (useful on embedded devices with limited screen resolutions). Finally, in the Qt version of MacOS X, QAquaStyle emulates the default Aqua style used in MacOS X. If you build Qt on Windows XP, you can configure it to use an additional QXPStyle.QApplication::setStyle(). You should call this
method before any widget is created or repaint all the widgets afterwards.
This repainting can be done with the following code:
// set the default
QApplication::setStyle( new QWindowsStyle ); // or any other style you like
// get a list of all top-level widgets of the application
QWidgetList* widgetlist = QApplication::topLevelWidgets();
// create an iterator over the list
QWidgetListIt widgetlist_it( *widgetlist );
// do the following for each top-level widget
while( widgetlist_it.current() )
{
// take one widget from the list
QWidget* widget = widgetlist_it.current();
// advance the iterator to the next element
++widgetlist_it;
// apply the new style to this widget
widget->setStyle( newstyle );
// get a list of all descendants of this widget that are widgets
// themselves
QObjectList* objectlist = widget->queryList( "QWidget", 0, 0, true );
// create an iterator over this list
QObjectListIt objectlist_it( *objectlist );
// apply the new style to all descendant widgets
while ( objectlist_it.current() )
{
++objectlist_it; // advance iterator to next element,
// the current one is already changed
QWidget *child = (QWidget *)( objectlist_it.current() );
child->setStyle( newstyle );
}
delete objectlist;
}
delete widgetlist;QPushButton (see
Figure 4-1) in Qt. These buttons yield some kind
of action, such as closing a dialog box or invoking a program-specific
function. They can be labeled with either text or pixmaps, using
the method setText() or setPixmap().
A text string can also be passed in the constructor. You usually
connect a slot to the signal clicked(), which
is emitted when the mouse is pressed and released again over the
button.pressed() and released() are
also available, but you should be careful with them, since you
are probably on your way to designing a
hard-to-use GUI if you use them. There is also a signal
called toggled(), which is only emitted in a
special mode of a QPushButton object (we will
discuss this signal later).
setDefault() on it. A related
method is setAutoDefault(), which makes a button
an autodefault button. Unlike the default button, there
can be more than one autodefault button. An autodefault
button becomes the new default button when it gets the keyboard
focus, and it loses this property when the keyboard focus moves
to a different widget.