Journal Articles

CVu Journal Vol 17, #4 - Aug 2005 + Programming Topics
Browse in : All > Journals > CVu > 174 (12)
All > Topics > Programming (877)
Any of these categories - All of these categories

Note: when you create a new publication type, the articles module will automatically use the templates user-display-[publicationtype].xt and user-summary-[publicationtype].xt. If those templates do not exist when you try to preview or display a new article, you'll get this warning :-) Please place your own templates in themes/yourtheme/modules/articles . The templates will get the extension .xt there.

Title: Qt 4.0 is Out!

Author: Administrator

Date: 03 August 2005 05:00:00 +01:00 or Wed, 03 August 2005 05:00:00 +01:00

Summary: 

Body: 

Qt 4.0, the latest major version of Qt, is now available for download. Like previous Qt releases, Qt 4.0's primary goal is to allow C++ developers to create readable, maintainable, cross-platform GUI applications that look native on all platforms. Beyond that, the focus has been to make Qt even easier to learn and use, to increase Qt's performance, and to make multithreaded programming easier.

In the previous instalment of this series on GUI programming with Qt, we presented the new set of collection classes introduced with version 4.0. In this article, we will concentrate on some of Qt 4.0's architectural changes and on its powerful 2D drawing capabilities. But first, a note on licensing.

Qt's Dual-Licensing

Starting with Qt 4, the Windows version of Qt is available both under a commercial license and under the GNU General Public License (GPL), extending Qt's Open Source offer to cover all platforms supported by Qt. This means that if you want to build commercial applications using Qt, you must buy a commercial licence from Trolltech; if you want to build Open Source programs for Unix/Linux, Windows or Mac OS X, you can download the Qt Open Source Edition from http://www.trolltech.com/. Time-limited evaluation versions are available for commercial evaluators.

The availability of a Qt/Windows Open Source Edition this year is the last brick in the construction of our successful dual-licensing business model. In the early days, Qt/X11 was available as a binary-only package to Open Source developers-notably the developers of the K Desktop Environment (KDE) for Linux/Unix. The table below shows how we have made our licensing more flexible and extended it to more platforms through the years.

<colgroup> <col width="50%"> <col width="50%"></colgroup> <thead> </thead> <tbody> </tbody>
Year Event
1998 Qt/X11 is released under the Q Public License (QPL), an Open Source license, to satisfy the needs of the KDE project
2000 Qt/ X11 is released under the GPL, in addition to the QPL, making it possible to write GPL software using Qt
2000 Qt/Embedded is released under the GPL
2001 Qt/Windows version 2.3 is made available as a binary-only package under a non-commercial license
2003 Qt/Mac is released under the GPL
2005 Qt/Windows is released under the GPL

Other Trolltech products, notably Qt Script for Applications (QSA) and Qtopia PDA Edition, are available under both commercial and Open Source licences.

Architectural Changes

Unlike previous Qt releases, Qt 4 is a collection of smaller libraries:

<colgroup> <col width="50%"> <col width="50%"></colgroup> <thead> </thead> <tbody> </tbody>
Library Description
QtCore Core non-GUI functionality
QtGui Core GUI functionality
QtNetwork Network module
QtOpenGL OpenGL module
QtSql SQL module
QtXml XML module
Qt3Support Qt 3 compatibility classes

QtCore contains tool classes like QString, QList, and QFile, as well as kernel classes like QObject and QTimer. The QApplication class has been refactored so that it can be used in non-GUI applications. It is split into QCoreApplication (in QtCore) and QApplication (in QtGui). This split makes it possible to develop server applications using Qt without linking in any unnecessary GUI-related code and without requiring GUI-related system libraries to be present on the target machine (e.g. Xlib on X11, Carbon on Mac OS X).

In addition, Qt 4 provides an extension library that applications based on Qt 3 called Qt3Support, that Qt applications can link against. This allows for more compatibility than ever before, without bloating Qt.

  • Classes that have been replaced by a different class with the same name, such as QListView, and classes that no longer exist in Qt 4 are available with a 3 in their name (e.g., Q3ListView, Q3Accel).

  • Other classes provide compatibility functions. Most of these are implemented inline, so that they don't bloat the Qt libraries.

New Technologies

Qt 4 introduces the following core technologies:

  • Tulip, a new set of template container classes.

  • Arthur, the Qt 4 painting framework.

  • Interview, a model/view architecture for item views.

  • Scribe, the Unicode text renderer with a public API for performing low-level text layout.

  • Mainwindow, a modern action-based mainwindow, toolbar, menu, and docking architecture.

Qt 4 also includes the new Qt Designer user interface design tool, which can be integrated with popular IDEs. In addition, the following modules have been significantly improved since Qt 3:

  • fully cross-platform accessibility module, with support for the emerging SP-API Unix standard in addition to Microsoft and Mac Accessibility.

  • The SQL module, which is now based on the Interview model/view framework.

  • The network module, with better support for UDP and synchronous sockets.

  • The style API, which is now decoupled from the widgets, meaning that you can draw any user interface element on any device (widget, pixmap, etc.).

  • Enhanced thread support, with signal-slot connections across threads and per-thread event loops.

  • A new resource system for embedding images and other resource files into the application executable.

Arthur: The New Paint System

Qt 4 features a brand new paint subsystem, codenamed Arthur, that takes advantage of advances in 2D graphics support on modern window systems and the increased speed of desktop computers. Arthur introduces support for antialiasing, alpha blending, gradient filling, vector paths, and more. In this section, will show how to use these new features to make Qt applications look nicer.

Antialiasing

Aliasing when painting on a fixed-resolution device (such as a screen) is a visual distortion that occurs when the edges of a shape are converted into pixels. Antialiasing is a technique that reduces aliasing by using different colour intensities on the edges.

Antialiased shapes are usually more pleasant to look at. They can give the impression of a higher resolution than the screen actually uses, and make adjacent edges and intersection points clearer.

Qt 3 already supported antialiasing for screen fonts on systems that support it. Qt 4 adds supports for the other drawing shapes (lines, polygons, ellipses, etc).

Alpha Blending

Alpha blending is the process of compositing pixels with semi-transparency. This is done by extending the RGB triplet with an extra component, the "alpha channel", that specifies the level of transparency. The image below shows a semi-transparent selection rectangle.

In Qt 3, only QImage and QPixmap supported alpha blending. QImage could support an 8-bit alpha channel and QPainter recognised this; QPixmap preserved the alpha channel for pixmaps that were created from QImages.

In Qt 4, QPainter supports alpha blending for all drawing operations, for filling, stroking, and text rendering. To make this possible, an alpha channel was added to QColor. For example, here's how we would draw a semi-transparent selection rectangle à la Windows XP:

painter.setPen(QColor(0, 0, 255, 191));
painter.setBrush(QColor(0, 0, 255, 63));
painter.drawRect(rect);

The fourth arguments to the QColor constructors specify the alpha channel. The alpha values extend from 0 (fully transparent) to 255 (opaque). In our example, the outline is 75% opaque and the fill is 25% opaque.

Gradient Filling

Gradient fills are defined by the interpolation between two or more colours, as opposed to a solid fill, which consists of a uniform colour. In Qt 4, they are implemented as a new QBrush fill pattern. For example:

QLinearGradient gradient(0, 0, 200, 100);
gradient.setColorAt(0.0, Qt::red);
gradient.setColorAt(1.0, Qt::blue);
painter.setBrush(gradient);
painter.drawEllipse(0, 0, 200, 100);

The code snippet defines a linear gradient fill that extends from red at (0, 0) to blue at (200, 100). The colours at points in between are interpolated linearly; points beyond the extremities are filled with the nearest extremity's colour. The points are expressed in logical painter coordinates. In addition to linear gradients, Qt 4 also supports radial and conical gradients.

This feature makes it easy to create visually pleasing effects such as shading on buttons. It can also be used in combination with alpha blending to fade colours in and out. For example, the following code snippet draws a gradient-filled rectangle on top of a pixmap to fade it out:

QRect rect = pixmap.rect();
painter.drawPixmap(rect, pixmap);

QColor transparent(255, 255, 255, 0);
QLinearGradient gradient(rect.topLeft(), rect.bottomLeft());
gradient.setColorAt(0.0, transparent);
gradient.setColorAt(1.0, Qt::white);
painter.fillRect(rect, gradient);

Floating Point Based Painting

QPainter in Qt 4 introduces a floating point based API in addition to the existing integer-based API. Classes like QPoint, QSize, and QRect are now complemented by float-based classes such as QPointF, QSizeF, and QRectF.

This feature is often used in combination with antialiasing to increase the perceived resolution of what can be seen on screen. To illustrate this, we will study the example of concentric circles with alternating odd-even diameters.

The image on the left is drawn using QPainter's int-based API. The image in the middle is drawn using the new float-based API. The image on the right uses the float-based API together with antialiasing.

The circles with an even diameter on the left image don't have exactly the same centre point as the circles with an odd diameter; there is a half pixel offset between the odd circles' center and the even circles' centre. With the float-based API, we can specify "half pixel" coordinates, and with antialiasing, we get circles that look more accurate. Another benefit of using floating point coordinates is that you can work in arbitrary resolutions. Previously, if you wanted to plot floating point data, you typically had to scale the coordinates and convert them to integers.

Painter Paths

Qt 4 introduces support for painter paths through the QPainterPath class. A painter path (also called "vector path") is a vectorial specification of a shape. Painter paths are the ultimate drawing primitive, in the sense that any shape (rectangle, ellipse, spline, etc.) or combination of shapes can be expressed as a path. QPainter uses painter paths internally when talking to the underlying paint engine.

A path specifies both an outline and an area. QPainter::drawPath() draws the outline using the current pen and fills the area with the current brush. Paths can also be used for clipping using QPainter::setClipPath().

For many applications, the basic drawing operations provided by QPainter (drawRect(), drawEllipse(), etc.) are sufficient. Applications with more advanced 2D graphics, such as CAD applications, might use QPainterPath to represent their graphical data. QPainterPath can also be used to create scalable icons or more complex clip areas than are possible with QRegion.

A painter path is composed of two primitive elements: straight lines and cubic Bézier curves. You can compose shapes by connecting primitive elements together. A single path can contain multiple shapes, or subpaths.

You can create paths using the basic functions moveTo(), lineTo(), and curveTo(). For example:

QPainterPath path;
path.moveTo(10, 10);
path.lineTo(20, 10);
path.curveTo(30, 20, 15, 15, 10, 20);

You can call moveTo() at any time to start a new subpath, and closeSubpath() to connect the first and last points of the current subpath. QPainterPath also provides convenience functions for commonly used shapes: addRect(), addEllipse(), addPolygon(), addText(), and addRegion().

Advanced Text Rendering

In this last section, we will combine antialiasing, gradient filling, and painter paths to render the word "Arthur" in a cool way.

We start by setting up the painter to use antialiasing and by erasing the background:

QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
painter.fillRect(rect(), Qt::white);

We create a QPainterPath object that corresponds to the outline and area of the text "Arthur" in 200-point Times:

QFont timesFont("Times", 200);
timesFont.setStyleStrategy(QFont::ForceOutline);

QPainterPath path;
path.addText(0, 200, timesFont, "Arthur");

We fill the painter path's area with a gradient fill:

QLinearGradient pathGradient(0, 0, 0, 210);
pathGradient.setColorAt(0.0, QColor(219, 238, 188));
pathGraident.setColorAt(1.0, QColor(59, 156, 69));
painter.fillPath(path, pathBrush);

Finally, we use the QPainterPathStroker class to create a 2-pixel thick painter path for the outline and fill it with a somewhat darker gradient fill:

QPainterPathStroker stroker;
stroker.setWidth(2);
stroker.setJoinStyle(Qt::RoundJoin);
QPainterPath stroke = stroker.createStroke(path);

QLinearGradient strokeGradient(0, 0, 0, 210);
strokeGradient.setColorAt(0.0, QColor(150, 170, 140));
strokeGradient.setColorAt(1.0, QColor(0, 100, 20));
painter.fillPath(stroke, strokeBrush);

This is just a quick overview of the possibilities offered by Arthur. Check out the Arthur demos in Qt's demos directory for some mind-blowing effects.

Notes: 

More fields may be available via dynamicdata ..