Qt certification

PASSED exam on March 23, 2010.

Overview of modules and classes

* Be able to list major Qt modules
* Understand the concept and the functionality of a Qt module
* Understand the major APIs provided by different Qt modules

QtCore, QtGui, QtNetwork

Basic drawing

* Understand the difference between QPixmap, QImage and QPicture
* Be able to load an image from a file

The QPixmap class is an off-screen image representation that can be used as a paint device.

The QImage class provides a hardware-independent image representation that allows direct access to the pixel data, and can be used as a paint device

The QPicture class is a paint device that records and replays QPainter commands

Main windows and actions

* Know how to implement a menu
* Be able to use a toolbar and statusbar

fileMenu = menuBar()->addMenu(tr(“&File”)
fileToolBar = addToolBar(tr(“File”));
QStatusBar * QMainWindow::statusBar () const

Temporary – briefly occupies most of the status bar. Used to explain tool tip texts or menu entries, for example.
Normal – occupies part of the status bar and may be hidden by temporary messages. Used to display the page and line number in a word processor, for example.
Permanent – is never hidden. Used for important mode indications, for example, some applications put a Caps Lock indicator in the status bar.

* Know how to use QVariant to store data in Actions
setData()

* Understand the usage of scrolled areas

scrollArea = new QScrollArea;
scrollArea->setWidget(imageLabel);

QSignalMapper

* Understand the concept of signal mapper
* Be able to use QSignalMapper

ButtonWidget::ButtonWidget(QStringList texts, QWidget *parent)
: QWidget(parent)
{
signalMapper = new QSignalMapper(this);

QGridLayout *gridLayout = new QGridLayout;
for (int i = 0; i < texts.size(); ++i) {
QPushButton *button = new QPushButton(texts[i]);
connect(button, SIGNAL(clicked()), signalMapper, SLOT(map()));
signalMapper->setMapping(button, texts[i]);
gridLayout->addWidget(button, i / 3, i % 3);
}

connect(signalMapper, SIGNAL(mapped(const QString &)),
this, SIGNAL(clicked(const QString &)));

setLayout(gridLayout);
}

Signals and Slots

* Learn the advantages of signals/slots

And we can have overloaded signals and slots, which feels natural when programming in a language where overloads are a key concept. Our signals add zero bytes to the size of a class instance, which means we can add new signals without breaking binary compatibility. Because we do not rely on excessive inlining as done with templates, we can keep the code size smaller. Adding new connections just expands to a simple function call rather than a complex template function.

Another benefit is that we can explore an object’s signals and slots at runtime. We can establish connections using type-safe call-by-name, without having to know the exact types of the objects we are connecting. This is impossible with a template based solution. This kind of runtime introspection opens up new possibilities, for example GUIs that are generated and connected from Qt Designer’s XML ui files.

QObject::disconnect
The sender may never be 0. (You cannot disconnect signals from more than one object in a single call.)

If signal is 0, it disconnects receiver and method from any signal. If not, only the specified signal is disconnected.

If receiver is 0, it disconnects anything connected to signal. If not, slots in objects other than receiver are not disconnected.

If method is 0, it disconnects anything that is connected to receiver. If not, only slots named method will be disconnected, and all other slots are left alone. The method must be 0 if receiver is left out, so you cannot disconnect a specifically-named slot on all objects.

Generic IO, files and printing

* Understand the usage of QFile
* Be able to identify the difference between QDataStream and QTextStream

The QDataStream class provides serialization of binary data to a QIODevice.

A data stream is a binary stream of encoded information which is 100% independent of the host computer’s operating system, CPU or byte order. For example, a data stream that is written by a PC under Windows can be read by a Sun SPARC running Solaris.

* Know the related classes for file and directory access

QDir dir(“example”);
if (!dir.exists())
qWarning(“Cannot find the example directory”);
(We could also use the static convenience function QFile::exists().)

Traversing directories and reading a file:

QDir dir = QDir::root(); // “/”
if (!dir.cd(“tmp”)) { // “/tmp”
qWarning(“Cannot find the \”/tmp\” directory”);
} else {
QFile file(dir.filePath(“ex1.txt”)); // “/tmp/ex1.txt”
if (!file.open(QIODevice::ReadWrite))
qWarning(“Cannot create the file %s”, file.name());
}
A program that lists all the files in the current directory (excluding symbolic links), sorted by size, smallest first:

#include
#include

int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
QDir dir;
dir.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks);
dir.setSorting(QDir::Size | QDir::Reversed);

QFileInfoList list = dir.entryInfoList();
std::cout << " Bytes Filename" << std::endl;
for (int i = 0; i < list.size(); ++i) {
QFileInfo fileInfo = list.at(i);
std::cout << qPrintable(QString("%1 %2").arg(fileInfo.size(), 10)
.arg(fileInfo.fileName()));
std::cout << std::endl;
}
return 0;
}

* Be able to read/write from/to files using Qt
* Understand the issue of text encodings and files

QTextStream out(&file);
out.setCodec("UTF-8");

* Understand when better to use QDataStream instead of QTextStream
* Be able to print a widget or text document in PDF format using QPrinter

QPrinter printer;
printer.setOutputFormat(QPrinter::PdfFormat);
printer.setOutputFileName("/foobar/nonwritable.pdf");
QPainter painter;
if (! painter.begin(&printer)) { // failed to open file
qWarning("failed to open file, is it writable?");
return 1;
}
painter.drawText(10, 10, "Test");
if (! printer.newPage()) {
qWarning("failed in flushing page to disk, disk full?");
return 1;
}
painter.drawText(10, 10, "Test 2");
painter.end();

Standard dialogs

* Know the various standard dialog types

QPrintDialog,QColorDialog (static), QErrorMessage, QFileDialog (static), QFontDialog (static), QInputDialog (static functions), QMessageBox (static)

qInstallMsgHandler() - process error messages.

* Understand the usage of standard dialogs
* Be able to use these dialogs
* Understand how processing of events works with QProgressDialog

QProgressDialog modal and modeless

* Understand the structure of wizards
* Be able to create your own wizards with pages

QWizard and QWizardPage. Provides example of QTranslator

Strings, URLs and regular expressions

* Know how to extract data from strings
* Know how to test strings
* Know useful utility functions in QString

QString str = "and";
str.prepend("rock "); // str == "rock and"
str.append(" roll"); // str == "rock and roll"
str.replace(5, 3, "&"); // str == "rock & roll"

* Know the basics about Qt support of translation of strings into other languages

QTranslator translator;
translator.load("hellotr_la");
app.installTranslator(&translator);

QPushButton hello(QPushButton::tr("Hello world!"));

* Understand QUrl and the components of an URL
QUrl QUrl::fromUserInput ( const QString & userInput ) [static]
QString QUrl::host () const
QString QUrl::password () const
QString QUrl::path () const
int QUrl::port () const
QList > QUrl::queryItems () const
QString QUrl::scheme () const
QString QUrl::userName () const

* Learn how to use QRegExp for regular expression and shell globing
QRegExp rx(“^\\d\\d?$”); // match integers 0 to 99
rx.indexIn(“123″); // returns -1 (no match)
rx.indexIn(“-6″); // returns -1 (no match)
rx.indexIn(“6″); // returns 0 (matched as position 0)

QRegExp rx(“^\\S+$”); // match strings without whitespace
rx.indexIn(“Hello world”); // returns -1 (no match)
rx.indexIn(“This_is-OK”); // returns 0 (matched at position 0)

RegExp rx(“\\b(mail|letter|correspondence)\\b”);
rx.indexIn(“I sent you an email”); // returns -1 (no match)
rx.indexIn(“Please write the letter”); // returns 17

QRegExp rx(“&(?!amp;)”); // match ampersands but not &
QString line1 = “This & that”;
line1.replace(rx, “&”);
// line1 == “This & that”
QString line2 = “His & hers & theirs”;
line2.replace(rx, “&”);
// line2 == “His & hers & theirs”

str = “Nokia Corporation\tqt.nokia.com\tNorway”;
QString company, web, country;
rx.setPattern(“^([^\t]+)\t([^\t]+)\t([^\t]+)$”);
if (rx.indexIn(str) != -1) {
company = rx.cap(1);
web = rx.cap(2);
country = rx.cap(3);
}

QRegExp rx(“*.html”);
rx.setPatternSyntax(QRegExp::Wildcard);
rx.exactMatch(“index.html”); // returns true
rx.exactMatch(“default.htm”); // returns false
rx.exactMatch(“readme.txt”); // returns false

Validating Input

* Be able to set input masks on line edits

QLineEdit
A related class is QTextEdit which allows multi-line, rich text editing.

* Understand the format for input masks

000.000.000.000;_
HH:HH:HH:HH:HH:HH;_
0000-00-00

setInputMask()

* Know that QCompleter offer popup completion

setCompletionMode(QCompleter::PopupCompletion).

QStringList wordList;
wordList << "alpha" << "omega" << "omicron" << "zeta";

QLineEdit *lineEdit = new QLineEdit(this);

QCompleter *completer = new QCompleter(wordList, this);
completer->setCaseSensitivity(Qt::CaseInsensitive);
lineEdit->setCompleter(completer);

Qt Designer

* Understand how designer can help in creating widgets
* Understand the concept of designer files
* Be able to load designer code inside your code

ui_dialog.h:
class Ui_Dialog
{
public:
void setupUi(QDialog *Dialog)
};

dialog.cpp
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
}

* Be able to connect designer elements with business functions

QMetaObject::connectSlotsByName
Toolbar: edit widgets, edit signals

* Know how to manage custom widgets in designer
Promote widget

http://doc.trolltech.com/4.6/designer-using-custom-widgets.html

* Be able to load designer files in runtime

MyWidget::MyWidget(QWidget *parent)
: QWidget(parent)
{
QUiLoader loader;
QFile file(“:/forms/myform.ui”);
file.open(QFile::ReadOnly);
QWidget *myWidget = loader.load(&file, this);
file.close();

QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(myWidget);
setLayout(layout);
}



myform.ui

* Be able to write a dialog using the designer tool

Resources

* Know the resource XML file structure
* Be able to access resources from the application
* Know that resource files can be localized

Some resources, such as translation files and icons, many need to change based on the user’s locale. This is done by adding a lang attribute to the qresource tag, specifying a suitable locale string. For example:


cut.jpg


cut_fr.jpg

If the user’s locale is French (i.e., QLocale::system().name() returns “fr_FR”), :/cut.jpg becomes a reference to the cut_fr.jpg image. For other locales, cut.jpg is used.

* earn how to load a resource file dynamically

http://doc.trolltech.com/4.5/resources.html

QResource::registerResource(“/path/to/myresource.rcc”);

Container classes

* Know the difference between Java and STL styled APIs

Unlike STL-style iterators (covered below), Java-style iterators point between items rather than directly at items.

* Know the different container types
* Know the requirements for a type to be storable in a container

To qualify, a type must provide a default constructor, a copy constructor, and an assignment operator.

* Be able to iterate of containers

Java-style:
QListIterator i(list);
while (i.hasNext())
qDebug() << i.next();

STL-style:
for (i = list.begin(); i != list.end(); ++i)
*i = (*i).toLower();

* Know the difference standard and mutable iterators

QListIterator provides no functions to insert or remove items from the list as we iterate. To accomplish this, you must use QMutableListIterator

* Be able to use the foreach keyword on containers

QLinkedList list;

QString str;
foreach (str, list)
qDebug() << str;

* Know the utility container algorithms offered by Qt

The header includes the generic, template-based algorithms.

* Understand the concept of implicit shared classes

A shared class consists of a pointer to a shared data block that contains a reference count and the data.
Implicit sharing automatically detaches the object from a shared block if the object is about to change and the reference count is greater than one

Help system

* Know the different possibilities to provide help

toolTip, statusTip, whatIsThis

QWhatsThis
The QWhatsThis class provides a simple description of any widget, i.e. answering the question “What’s This?”

Qt Help Project .qhp The input file for the help generator consisting of the table of contents, indices and references to the actual documentation files (*.html); it also defines a unique namespace for the documentation.
Qt Compressed Help .qch The output file of the help generator. This binary file contains all information specified in the help project file along with all compressed documentation files.
Qt Help Collection Project .qhcp The input file for the help collection generator. It contains references to compressed help files which should be included in the collection; it also may contain other information for customizing Qt Assistant.
Qt Help Collection .qhc The output of the help collection generator. This is the file QHelpEngine operates on. It contains references to any number of compressed help files as well as additional information, such as custom filters.

* Understand the concept of the system tray icon

The tray icon is an instance of the QSystemTrayIcon class. To check whether a system tray is present on the user’s desktop, call the static QSystemTrayIcon::isSystemTrayAvailable() function.

* Learn how to support dynamic help

HelpEngineCore helpEngine(“mycollection.qhc”);

// get all file references for the identifier
QMap links =
helpEngine.linksForIdentifier(QLatin1String(“MyDialog::ChangeButton”));

// If help is available for this keyword, get the help data
// of the first file reference.
if (links.count()) {
QByteArray helpData = helpEngine->fileData(links.constBegin().value());
// show the documentation to the user
if (!helpData.isEmpty())
displayHelp(helpData);
}

Synthetic Events

* Understand the concept of event propagation

bool QCoreApplication::notify()
Sends event to receiver: receiver->event(event). Returns the value that is returned from the receiver’s event handler. Note that this function is called for all events sent to any object in any thread.

For certain types of events (e.g. mouse and key events), the event will be propagated to the receiver’s parent and so on up to the top-level object if the receiver is not interested in the event (i.e., it returns false).

* Learn how to post/send events

QCoreApplication::sendEvent()
Sends event event directly to receiver receiver, using the notify() function. Returns the value that was returned from the event handler.

QCoreApplication::postEvent()
Adds the event event, with the object receiver as the receiver of the event, to an event queue and returns immediately.

The event must be allocated on the heap since the post event queue will take ownership of the event and delete it once it has been posted. It is not safe to modify or delete the event after it has been posted.

When control returns to the main event loop, all events that are stored in the queue will be sent using the notify() function.

* Be able to create/send/handle custom events

QCustomEvent class provides support for custom events.

QCustomEvent has a void * that can be used to store custom data.
In Qt 4, QObject::customEvent() takes a plain QEvent pointer. You can add custom data by subclassing.

See also QObject::customEvent() and QCoreApplication::notify().

void QObject::customEvent ( QEvent * event ) [virtual protected]
This event handler can be reimplemented in a subclass to receive custom events. Custom events are user-defined events with a type value at least as large as the QEvent::User item of the QEvent::Type enum, and is typically a QEvent subclass. The event is passed in the event parameter.

Delayed Invocation

* Understand the need for idle processing
* Be able to implement delayed method invocation

To make your application perform idle processing (i.e. executing a special function whenever there are no pending events), use a QTimer with 0 timeout.

Event Filters

* Understand the advantage of event filters
* Be able to install your own event filters on objects

monitoredObj->installEventFilter(filterObj);
The event filter filterObj receives events via its eventFilter() function. The eventFilter() function must return true if the event should be filtered, (i.e. stopped); otherwise it must return false.

* Know the difference between object and application event filters
EventFilter QCoreApplication::setEventFilter ( EventFilter filter )
Replaces the event filter function for the QCoreApplication with filter and returns the pointer to the replaced event filter function. Only the current event filter function is called. If you want to use both filter functions, save the replaced EventFilter in a place where yours can call it.

The event filter function set here is called for all messages received by all threads meant for all Qt objects. It is not called for messages that are not meant for Qt objects.

The event filter function should return true if the message should be filtered, (i.e. stopped). It should return false to allow processing the message to continue.

Understand the fundamentals of QObject
* Understand the need for layout management

Event handling

* Understand the concept of events
* Understand the difference between events and signal/slots
* Be able to implement event handling
* Understand the role of events in painting

Geometry management

* Learn how to manipulate the geometry of a widget
A QSizePolicy has both a horizontal and a vertical component. Here are the most useful values:

– Fixed means that the widget cannot grow or shrink. The widget always stays at the size of its size hint.
– Minimum means that the widget’s size hint is its minimum size. The widget cannot shrink below the size hint, but it can grow to fill available space if necessary.
– Maximum means that the widget’s size hint is its maximum size. The widget can be shrunk to its minimum size hint.
– Preferred means that the widget’s size hint is its preferred size, but that the widget can still shrink or grow if necessary.
– Expanding means that the widget can shrink or grow and that it is especially willing to grow.

* Understand the concepts behind a layout manager in Qt
* Know and understand the various layout managers
* Learn how to use widgets with layout a managers

QWidget::setSize()
The size is adjusted if it lies outside the range defined by minimumSize() and maximumSize().

sizeHint
This property holds the recommended size for the widget.
If the value of this property is an invalid size, no size is recommended.
The default implementation of sizeHint() returns an invalid size if there is no layout for this widget, and returns the layout’s preferred size otherwise.

minimumSize
The widget cannot be resized to a smaller size than the minimum widget size. The widget’s size is forced to the minimum size if the current size is smaller.
The minimum size set by this function will override the minimum size defined by QLayout. In order to unset the minimum size, use a value of QSize(0, 0).
By default, this property contains a size with zero width and height.

maximumSize
The widget cannot be resized to a larger size than the maximum widget size.
By default, this property contains a size in which both width and height have values of 16777215.

sizePolicy
This property holds the default layout behavior of the widget.
If there is a QLayout that manages this widget’s children, the size policy specified by that layout is used. If there is no such QLayout, the result of this function is used.

QLayout
sizeConstraint
This property holds the resize mode of the layout.

QLayout::SetDefaultConstraint
The main widget’s minimum size is set to minimumSize(), unless the widget already has a minimum size.

* Be able to develop own dialog with layouts

Creating your own (custom) dialogs

* Learn how to subclass a QDialog
* Understand the usage of buttons in a dialog

autoDefault (is used when focused) and default (whenever user hits Enter if no autoDefault is focused).
Connect buttons to either one of these SLOTS: accept()/reject()
QDialog::result() Returns the modal dialog’s result code, Accepted or Rejected.

* Be able to launch dialogs (not-) modal

application modal vs. window modal

Qt::ApplicationModal – The window is modal to the application and blocks input to all windows.
Qt::WindowModal – The window is modal to a single window hierarchy and blocks input to its parent window, all grandparent windows, and all siblings of its parent and grandparent windows

exec() – Shows the dialog as a modal dialog, blocking until the user closes it.
open() – Shows the dialog as a window modal dialog, returning immediately.
show() – depending on modal()/setModal() attribute shows as either application modal or modeless.

* Know the deletion options for dialogs

Qt::WA_DeleteOnClose
void QWidget::setAttribute(…)

* Be able to create your own dialogs with user interactions