Qt for s60 (Part I) -Mrudul V. Pendharkar
Introduction • Qt (pronounced cute) is a cross platform application framework. Using Qt one can write application once and deploy on various platforms. • Back in 2008 Nokia bought the Norwegian company called Trolltech and with it brought Qt to s60 ( Nokia’s platform on top of symbian for smartphone) • According to recent roadmap published by Symbian Foundation, Qt would eventually replace Avkon widget set of Symbian Os in the Symbian v4 release.( Release Plan review). • Integration of Qt on s60 is still in a nascent stage. In January 2009, we the first pre-release called Temple. In June 2009, we saw release called Tower.
Installation • •
Installation of Qt on s60 is a 3 stage process. Choosing an Sdk – It is recommended that one installs 3.2 and above sdk so that the Qt release can be directly used. – If 3.1 sdk is selected, you need to also install open C/C++ sdk plugin on top of 3.1 sdk. Similarly Open C/C++ sdk plugin binaries need to be installed on the phone. For detailed installation steps refer Forum Nokia-3.1sdk.
•
Choosing Qt release. – It is recommended one selects the latest pre-release, which is the Tower release. – One can either choose to install only the binaries or download source code and then build into on top of the sdk, so that various binaries are installed on top of the sdk. For more info refer QtSoftware-Prerelease
•
Setting up Carbide for Qt – Install Carbide 2.0 and get an update to update Carbide to 2.02 version. – Configure Carbide to point to the Qt installation. Refer Forum Nokia-Carbide for more information
Learning Qt - Basic • • • • • • •
Hello World Build System Qt Object Model Signals & Slots QtEvent & EventLoop Qt Widgets and Main Window Menus – Cascaded Menus – Menu Shortcuts
• ToolBar • StatusBar
Hello World • Code: //FileName: HelloWorld.cpp //Location: c:\Qt\Helloworld #include
#include int main(int argc, char *argv[]){ //Create QApp and pass arguments to it. QApplication a(argc, argv); //Create QLabel to display Text QLabel* label = new QLabel("Hello World"); //Show Label label->show(); return a.exec(); } •
Building: c:\Qt\Helloworld> qmake –pro c:\Qt\Helloworld> qmake c:\Qt\Helloworld> make
Understanding the Build Commands •
qmake –project ? – Qmake creates a platform independent project file. • Note source files should be present before running this command, other wise you need to manually edit this file(.pro), if new source files are added after this command is given.
– Generally this command is given only once, when one is sure all source files are ready. • Note: If you give this command after manually editing this file(.pro), your changes would be lost.
•
Qmake? – This creates platform specific makefile. If the folder/directory contains multiple .pro files, then you can tell qmake which file to pick/use. For Eg: qmake hello2.pro
•
Make? – This command does a two step process. They are :• Bldmake bldfiles • Abld build ( == winscw udeb on Emulator; == armv5 urel )
Under the Build System Hood • Qt is nothing but a simple C++ program. Where it differs is the way it handles all the extra stuff like resources, Ui & Signal/Slots. • How it does it by generating C++ code for the extra stuff mentioned above and then adding extra compilers to the C++ build system. • Lets look at the C++ build system at a higher level. Fig 1(ref: http://thelins.se/learnqt/2009/04/the-qt-build-system/ )
Under the Build System Hood
• • •
As can be seen above: Sources(*.cpp) are compiled into Objects(*.o) which are further linked to create executable. Sources include headers which could be of type *.h, *.hrh, *.hpp etc.
Under the Build System Hood
• •
•
•
Qt adds moc compiler, resource compiler and Ui compiler to the regular C++ build system. Lets look at each one in the following sections: Moc_Compiler(moc) – The moc compiler takes all the files containing Q_Object macro and generates a moc_*.cpp file. This contains information about the class being moced like class Name, Inheritance Tree and implementation of signal/Slot. Resource Compiler(Rcc) – The rcc tool is used to embed resources into a Qt application during the build process. It works by generating a C++ source file containing data specified in a Qt resource (.qrc) file. Ui Compiler(uic) - The uic reads an XML format user interface definition (.ui) file as
generated by Qt Designer and creates a corresponding C++ header file. •
NOTE: In s60 we donot see the moc_* files being generated.
Qt Object Model • Qt is based around the Qt object model. • It is all based around the QObject class and the moc tool. • By deriving from Q_Object a number of benefits are inherited : – Easy Memory Management. • When you create a QObject with another object as parent, the object will automatically add itself to the parent's children() list. • The parent takes ownership of the object i.e. it will automatically delete its children in its destructor. – Seamless object communication • You can connect a signal to a slot with connect() and destroy the connection with disconnect(). • Any object which uses Signals & slots must declare Q_Object macro in his class.
Signals & Slots • •
In GUI programming, when we change one widget, we often want another widget to be notified. Older Toolkits achieve this communication by using callback mechanism. A callback is a pointer to a function. But callbacks have two fundamental problems – – They are Not Type Safe – We cannot be certain that the processing functions will call the callback function with correct parameters – They are strongly coupled to the processing function, since the processing function must know which callback to call.
•
Signals & Slots – – This provides Seamless object communication.
Signals & Slots •
Signals are emitted by widgets when something happens.
•
Slots are used to handle the signals.
•
The signals are delivered to the slots by the event loops started by QCoreApplication::exec() or QThread::exec().
•
Signals and slots neither know or care which slots or signals are catching/emitting.
•
Thus Signal/Slot mechanism are loosely coupled reigning in flexibility to declare signals and slots for objects.
•
Similarly Signal/Slot mechanism is type safe. The signature of the Signal must match with the signature of the receiving slot. The compiler helps in detecting these type mismatches.
•
It is possible to connect as many signals to a slot and vice versa. Also it is possible to connect one signal to another signal.
•
QObject::connect is used to connect signals and slots.
QtEvent & EventLoop •
Qt class QEvent encapsulates the notion of an event.
•
It is the base class for all event classes.
•
Qt application enters event loop when QApplication::exec() is called.
•
The event loop receives events from window system and dispatches this to the application widgets.
•
The event loop keeps on running until terminating event occurs.(for eg: user clicks Quit).
•
Eg: int main(int argc, char * argv[]) { QApplication myapp(argc, argv); - 1 QWidget rootWidget; setGui(&rootWidget); rootWidget.show(); - 2 return myapp.exec(); - 3 }; 2. 3. 4.
Every GUI, multithreaded, or event-driven Qt Application must have a QApplication object defined at the top of main(). Show the widget on the screen. Enter an event loop.
Widgets & Main Window •
UI controls in Qt are called widgets.
•
All widgets derive from QWiget class and thus share the properties and functionality defined by QWidget.
•
A Widget that isn’t embedded is called a window. In Qt, QMainWindow and QDialog are most common types of window types.
•
The properties and functionality defined in QWidget class include. – Size and Layout information. – Event Handling for mouse, key & paint events. – Information on possible parent & Children.
•
For a list of widgets available in Qt visit Qt documentation and under it Qt Widget Gallery.
Widgets and Main Window • Now lets look at the example for widget. //Main.cpp #include #include “mywidget.h” int main(int argc, char* argv[]){
QApplication app(argc, argv); QWidget* widget = new MyWidget; widget->show(); return app.exec(); } //MyWidget.h #include class MyWidget: public QWidget{ public: MyWidget(); ~MyWidget(); public slots: void slt_textChanged(); private: QTextEdit* iText; QLabel* iLlbl; }; //MyWidget.cpp #include “MyWidget.h” MyWidget::MyWidget(){ iText = new QTextEdit; iLbl = new QLabel; QVBoxLayout* layout = new QVBoxLayout; layout->addWidget(iText); layout->addWidget(iLbl); setLayout(layout); connect(iText, SIGNAL(textChanged()), this, SLOT(slt_textChanged)); } MyWidget::~MyWidget(){ if(iText) delete iText; if(iLbl) delete iLbl; } MyWidget::slt_textChanged(){ iLbl.setText(iText.Text()); }
Widgets and Main Window
• • •
Main windows are most often used to provide menus, toolbars and a status bar around a large central widget. A general approach to Main Windows would be to create a custom widget with desired layout etc. and then add the widget to the Main Window. The code from previous example would now look as follows:
//Main.cpp #include #include “mywidget.h” #include int main(int argc, char* argv[]){ QApplication app(argc, argv); QMainWindow mw; QWidget* widget = new MyWidget; mw.setCentralWidget(widget); mw.show(); return app.exec(); }
References • • • •
Independent Qt tutorials http://cartan.cas.suffolk.edu/oopdocbook/html/ http://thelins.se/learnqt/2009/04/the-qt-build-sy http://cartan.cas.suffolk.edu/qtdocs/index.html