Download presentation
Presentation is loading. Please wait.
Published byDortha Freeman Modified over 7 years ago
1
Introduction to Qt4 Diego Iastrubni - (only 71 slides!)
2
Topics in this lecture Why do we need a multi-platform Toolkit/framework? Build system CS 101 – lists, strings, threads, timers GUI basics Tools shipped with Qt4 More reading
3
Why do we need a multi-platform Toolkit/framework?
Qt started back in 1997, when STL was not that "stable" Even now, not all STL implementations have the same features Boost is nice, but does not maintain a stable API/ABI – Qt is always API/ABI stable Qt still always feels consistent – the same terms are used in the whole API Boost/STL do not provide a GUI toolkit, not a sound toolkit, HTML renderer ...
4
Qt history Qt 1.4 Qt 2.0 – Unicode support, theme support
Qt 3.0 – BiDi support ;-) Qt 4.0 – fully double buffered, MVC, Scribe Qt 4.1 – SVG, PDF Qt 4.2 – CSS native support, QGraphicsView Qt 4.3 – Qt Script, SVG file generation Qt 4.4 – Phonon, WebKit, concurrency framework Trolltech released Qt 4.0 on June 28, 2005 and introduced five new technologies in the framework: Tulip A set of template container classes. Interview A model/view architecture for item views. Arthur A 2D painting framework. Scribe A Unicode text renderer with a public API for performing low-level text layout. MainWindow A modern action-based main window, toolbar, menu, and docking architecture. Qt 4.1, released on December 19, 2005, introduced integrated SVG Tiny support, a PDF backend to Qt's printing system, and a few other features. Qt 4.2, released on October 4, 2006, introduced Windows Vista support, introduced native CSS support for widget styling, as well as the QGraphicsView framework for efficient rendering of thousands of 2D objects onscreen, to replace Qt 3.x's QCanvas class. Qt 4.3, released on May 30, 2007, improved Windows Vista support, improved OpenGL engine, SVG file generation, added QtScript (ECMAScript scripting engine based on QSA).[22] Qt 4.4, released on May 6, Features included are improved multimedia support using Phonon, enhanced XML support, a concurrency framework to ease the development of multi-threaded applications, an IPC framework with a focus on shared memory, and WebKit integration. Qt 4.5, released on March 3, Major included features are QtCreator, improved graphical engine, improved integration with WebKit, OpenDocument Format write support and new licensing options, as well as Mac OS X Cocoa framework support.
5
Qt4 build system (7 slides)
6
Build system (1/7) First problem we see when we have a big project: foo.cpp/foo.h – contains foo_func() bar.cpp/bar.h – contains class bar main.cpp – the entry point in my application HOW DO I BUILD THIS??!?
7
Build system (2/7) > cat build.sh #! /bin/sh
g++ foo.cpp -o foo g++ bar.cpp -o bar g++ main.cpp -o main g++ foo.o bar.o main.o -o my_cool_app
8
Build system (3/7) > cat build.sh #! /bin/sh
FILES="foo bar main" for i in $FILES; do $CXX $i.cpp -o $i $CXX_FLAGS OBJS="$OBJS $i.o" done $CXX $OBJS -o my_cool_app
9
Build system (4/7) > cat Makefile
ALL=my_cool_app OBJS=main.o foo.o bar.o my_cool_app: $OBJS $(CXX) $OBJS -o my_cool_app main.o: main.cpp foo.o: foo.cpp bar.o: bar.cpp
10
Build system (5/7) Still too ugly, still maintains logic about, not portable (MSVC? MacOsX Xcode? Other beast?) Lets build a project definition, and from it we generate the build system specific files (usually Makefiles, but can be also projects for MSVC, Xcode, whatever) Will help us in the near future compiling files for the MOC and the UI (also the translation system)
11
Build system (6/7) Creating a new project from a directory containing sources: qmake -project qmake make > cat cool-project.pro TARGET=my-cool-project TEMPLATE=app SOURCES=foo.cpp bar.cpp main.cpp # not needed yet # HEADERS=foo.h bar.h
12
Build system - conclusion
qmake does something similar to auto* qmake is a not properly documented, and it contains many hacks qmake can build libraries, can contain sub projects, it handles building the UI files, handles the MOC, handles also the i18n aspects of the building qmake is a toy, don't use it in real life. Use CMake or auto*. Please. RTFM -
13
CS 101: lists, threads C/C++ basics (12 slides)
14
CS 101 – lists (1/12) QString str1; – a Unicode string
QVector<int32> v1; - an array based implementation QList<QString> strList1; - also array based, use this one "always", this one is FAST, see also QStringList QLinkedList<byte> ll; – always uses iterators QQueue<float> q1; QStack<uchar> s1;
15
CS 101 – lists - (2/12) QMap<int, float> map1; map1[12] = 0.12; map1.insert( -9, ); float a = map.value(12); float b = map[-9]; QHash<QString,QString> hash1; QString s = … contents of file ... hash1[qChecksum(s)] = s; More RTMF: oc/4.5/qbytearray.html#qChecksum QMap<Key, T> This provides a dictionary (associative array) that maps keys of type Key to values of type T. Normally each key is associated with a single value. QMap stores its data in Key order; if order doesn't matter QHash is a faster alternative. QHash<Key, T> This has almost the same API as QMap, but provides significantly faster lookups. QHash stores its data in an arbitrary order.
16
CS 101 – list iteration: JAVA (3/12)
Java Style QList<QString> list; list << "A" << "B" << "C" << "D"; QListIterator<QString> i(list); while (i.hasNext()) qDebug() << i.next();
17
CS 101 – list iteration: STL (4/12)
STL style QList<QString> list; list << "A" << "B" << "C" << "D"; QList<QString>::iterator i; for (i = list.begin(); i != list.end(); ++i) qDebug() << (*i).toLower();
18
CS 101: list iteration: foreach() (5/12)
foreach() style QList<QString> list; list << "A" << "B" << "C" << "D"; foreach (QString s, list) qDebug() << s; I use only this style. Don't waste time writing code, let the framework deal with iterators.
19
Threads (6/12) #inclue <QThread> class MyThread : public QThread
{ Q_OBJECT protected: void run(); }; void MyThread::run() ... }
20
Threads – Locking: Mutex (7/12)
QMutex provides a mutual exclusion lock, or mutex.
21
Threads – Mutex example (8/12)
QMutex mutex; int number = 6; void method1() { mutex.lock(); number *= 5; number /= 4; mutex.unlock(); } void method2() { number *= 3; number /= 2;
22
Threads – more locking (9/12)
QMutexLocker is a convenience class that automatically locks and unlocks a QMutex. QReadWriteLock provides a lock that allows simultaneous read access. QReadLocker and QWriteLocker are convenience classes that automatically lock and unlock a QReadWriteLock. QSemaphore provides an integer semaphore (a generalization of a mutex).
23
int complexFunction(int flag) {
mutex.lock(); int retVal = 0; switch (flag) { case 0: case 1: mutex.unlock(); return moreComplexFunction(flag); case 2: { int status = anotherFunction(); if (status < 0) { return -2; } retVal = status + flag; } break; default: if (flag > 10) { return -1; return retVal;
24
int complexFunction(int flag) {
QMutexLocker locker(&mutex); int retVal = 0; switch (flag) { case 0: case 1: return moreComplexFunction(flag); case 2: { int status = anotherFunction(); if (status < 0) return -2; retVal = status + flag; } break; default: if (flag > 10) return -1; return retVal;
25
Timers (last!) In a while, we need to understand what's a QObject, signals, slots...
26
GUI basics – basics (15 slides, no countdown)
27
QObject – the mother of all classes
In Qt(1/2/3/4) all classes inherit QObject. QObject has several interesting features Has run-time properties which can be read/write Translation via the method QObject::tr() Parent/siblings relationship (when parent is destroyed, it destroys also it's siblings) Each QObject has it's own timer Signals/Slots (to be discussed soon) RTFM:
28
QWidget – the mother of all GUI
QWidget inherits QObject In Qt(1/2/3/4) all GUI classes inherit QWidget. Everything you see is a QWidget.
29
First GUI application – Hello, world!
30
#include <QtGui/QApplication>
#include <QtGui/QMainWindow> #include <QtGui/QPushButton> class MainWindow : public QMainWindow { public: MainWindow(QWidget *parent = 0){ button = new QPushButton("Hello, world!", this); } private: QPushButton *button; }; int main(int argc, char *argv[]){ QApplication a(argc, argv); MainWindow w; w.show(); return a.exec();
31
#include <QApplication>
#include <QMainWindow> #include <QPushButton> class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = 0){ button = new QPushButton(tr("Hello, world!"),this); } private: QPushButton *button; }; int main(int argc, char *argv[]){ QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); #include "main.moc"
32
Second GUI application - let's QMessageBox on button click
Lets remember how it's done in various frameworks: JS/HTML – we modify the element's onclick property C# - delegates C: Gtk/Win32 – pointer to callback functions C++: MCF (Turbo Vision) - inheritance
33
Side note Question: WTF is this? char *(*(**foo [][8])())[];
Answer: foo is array of array of 8 pointer to pointer to function returning pointer to array of pointer to char. Question: Ok, pointers to functions. Now how about pointer to a method? To a method of an object?
34
C++ sux – no pointers to methods
In C you have pointers to functions In C++ there are no pointers to object's methods. You should do an abstract class, and then derive new classes. Too much code for a single thing. Qt uses a new mechanism – Signals + Slots.
35
Signals + Slots Each QObject defines a set of signals it can emit.
Each QObject can connect slots to different signals (even from other objects) When a QObject emits a signal, all connected slots get invoked. One signal calls many slots. One slot may be connected to many signals. (is this a many to many relationship?)
36
void do_button_click(){
#include <QApplication> #include <QMainWindow> #include <QPushButton> #include <QtGui/QMessageBox> class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = 0){ button = new QPushButton("Hello, world!", this); connect( button, SIGNAL(clicked()), this, SLOT(do_button_click()) ); } public slots: void do_button_click(){ QMessageBox::information( this, "Message", "Button clicked" ); private: QPushButton *button; }; int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); #include "main.moc"
37
Using slots Slots are "normal" methods
They must defined using the "slots" keyword, as demonstrated before The class definition should also include the Q_OBJECT macro. The headers which contain the slots definition must be in the *.pro file For each *.cpp/h file which contains the Q_OBJECT macro, all slots will be expanded as needed by the MOC into a *.moc file, which will be compiled as well All this voodoo is handled by qmake – as defined in the *.pro file
38
Using signals Add the Q_OBJECT macro to your class
Add the header to the project file Declare it as a normal method: signals: void valueChanged(int newValue); Don't implement it! To emit the signal use: emit valueChanged(12);
39
Using timers – 1st option
t1 = new QTimer( this ); t1->setSingleShot( true ); t1->setInterval( 2000 ); t1->start(); connect( t1, SIGNAL(timeout()), this, SLOT(do_timeout()) );
40
Using timers – 2nd option
QTimer::singleShot( 2000, this, SLOT(do_timeout()) ); In constructors I usually do: foo::foo() { Qtimer::singleShot(0, this, SLOT(init()); } foo::init(){ ....
41
Using timers – 3rd option
When deriving QObject (almost always) you can call int QObject::setTimer(int) Then you need to re-implement virtual void timerEvent(QTimerEvent *event)
42
GUI basics – the fun begins (19 slides, no countdown)
43
Using the designer You can write GUIs in code as we did before
Qt 4 has a application for building GUIs Designer saves the GUIs into XML, and in build time it's compiled into C++ (by UIC) and linked into the application. All handled automagically by QMake
44
Using the designer to edit GUI
45
Step 1 – add widgets
46
Step 2 – change widgets texts
47
Step 3 – position widgets, and add first layout to the buttons
48
Step 4 – add a new layout on the left, and arround the listbox + buttons
49
Step 5 – change properties
Right click on the window, and set an internal layout of "grid" Left layout is set to "fixed size" All other elements are set to: Size policy: horizontal=expanding Size policy: vertical=fixed Buttons are set to horizontal=maximum Disable the listbox container Set the first button as "checked"
50
Step 6 disable the pages list
Edit->Signals/Slots (F4) Now we are in Signals/slot editing mode Click the last radio, and drag the mouse to the container of the listbox+buttons When the radio button emits a signal, which slot of the container will get executed connect( radioButton3, SIGNAL(toggled(bool)), frame, SLOT(setEnabled(bool)) )
51
Step 7 - Edit signals
52
Step 8 - Connect signals to slots
53
Step 9 – test it Press control+R to live preview the window
The window is resizable When we choose different radio buttons – the window behaves as expeced
54
Use the dialog in C++ code
3 Methods: The Direct Approach The Single Inheritance Approach The Multiple Inheritance Approach 2 more (undiscussed) Load the UI file, and connect slots/signals manually Using Qt Script
55
The Direct Approach Project file TEMPLATE = app
FORMS = calculatorform.ui SOURCES = main.cpp
56
The Direct Approach #include "ui_calculatorform.h"
int main(int argc, char *argv[]) { QApplication app(argc, argv); QWidget *widget = new QWidget; Ui::CalculatorForm ui; ui.setupUi(widget); widget->show(); return app.exec(); }
57
The Single Inheritance Approach
#include "ui_mainwindow.h" class mainGUI: public QMainWindow{ Q_OBJECT public: mainGUI( QWidget *p=0): QMainWindow(p){ ui.setupUi(this); connect( ui.button1, SIGNAL(clicked()), this, SLOT(do_quit())); } public slots: void do_quit(){ this->close() }; private: Ui::mainWindow ui;
58
The Single Inheritance Approach
Each time I save the UI file, the whole project gets rebuild. Why? Since every file in the project includes the maingui.h , and ui_mainwindow.h gets modified frequently due to design. The design of the window is an implementation detail, and should not be in the header file
59
The Single Inheritance Approach
// file maingui.h namespace Ui{ class mainWindow }; class mainGUI: public QMainWindow{ .... private Ui:mainWindow *ui } // file maingui.cpp #include "maingui.h" #include "ui_mainwindow.h" mainGUI::mainGUI() { ui = new Ui::mainWindow(); ui->setupUi( this );
60
The Multiple Inheritance Approach
class CalculatorForm : public QWidget, private Ui::CalculatorForm { Q_OBJECT public: CalculatorForm(QWidget *parent = 0); private slots: void on_inputSpinBox1_valueChanged(int value); void on_inputSpinBox2_valueChanged(int value); };
61
Slot auto-connection // note this!! private slots:
void on_inputSpinBox1_valueChanged(int value); void on_inputSpinBox2_valueChanged(int value); // this is not needed in the constructor! connect( inputSpinBox1, signal(valueChanged(int)), this, SLOT(on_inputSpinBox2_valueChanged(int))); connect( inputSpinBox2, signal(valueChanged(int)),
62
Tools provided with Qt4 – 4 slides
63
Qt Assistant
64
Qt Designer
65
Qt Linguist
66
Qt Creator - NEW!!!!11
67
More reading
68
What this lecture does not cover?
More QMake tricks (making libs, making plugins, subdirs, pch) More QObject tricks (deleteLater(), qobject_cast ) QMetaObject trikcs (run time introspection in C++) I18n – lupdate, lrelease + Linguist Phonon QtWebKit QtScript
69
More RTFM Qt with autotools, Cross compiling, Debugging Tips, Building static, Qt4 with Visual Studio, GLib Event Loop ARGB-Widgets, Model-view framework, Using custom data types with Qt, Deploying Qt Applications, Reducing compilation times, Undocumented qmake
70
Projects I contributed to
Based on libhocr from Dr. Kobi Zamir w t :-)
71
Thank you
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.