There was a time when all desktop applications were developed from scratch. Then came the concept of code reuse. Static and shared libraries were created for use in application development, but developers didn’t stop at that; they came up with software frameworks. Though libraries and frameworks seem to functionally be the same, there are some major differences between them, which should be understood:
- Libraries offer reusability of functionality, whereas frameworks offer reusability of behaviour. For example, a library may provide classes for TCP and UDP sockets, while a framework will provide a class for an abstract socket.
- A library may provide functions used for signals/events, but the framework function is how they interact with the system and other components.
- Libraries are called from application code, but the framework calls application code — or, you can say, provides services to the code.
Desktop applications
Desktop applications are very platform-specific. An application compiled for Linux cannot be directly executed on another OS without some sort of emulation, due to differences in system calls and libraries between OSs. A big question was how to write platform-independent applications.
One method was to develop libraries for each platform, keeping application code the same and recompiling for each target platform. This does make life easier for developers — but then everything changed with the revolutionary concept of virtual machines from Sun Microsystems, which gave the world the platform-independent Java programming language. Java applications run on the Java Virtual Machine (JVM). Code developed once can be deployed to every platform that has a JVM for it.
But everything comes with a price. In Java’s case, the price was application performance. The performance of Java applications is not as good as of C/C++ applications compiled to platform-native code. Another problem is the large memory footprint. No doubt Java is still a leading language, but these days we have some really big data applications (for example, in biotech) with very high performance requirements. So again, the need is to develop applications compilable to native code. Application development using C is time-consuming, while C++ is a better option. We have some frameworks that support C++ for application development. The Qt framework is one of them.
Introducing Qt
Qt is a cross-platform application framework developed by Trolltech and presently owned by Nokia. Its APIs are for C++. Qt has been extensively used by application developers to develop cross-platform applications.
Qt can help with graphical application development, network applications, database and multimedia applications, handling XML and 3D, painting, drawing and Web access. As far as platform support is concerned, it supports Linux, Mac OS, Windows, Meego, Embedded Linux and Symbian.
Qt architecture
In Figure 1, you can see a minimal architecture diagram.
The top layer is C++ program code. Below that are Qt classes for GUI, WebKit, databases, etc., and then an OS-specific support layer. Earlier, Qt also supported Java; its Java-based version was called Jambie. As Qt development progressed, it was getting difficult to support both C++ and Java, so the decision was made to support only C++.
Qt installation
Installation methods differ by OS. On Ubuntu 10.04 LTS, I installed Qt via the Synaptic package manager — install the qtcreator
package; dependency resolution will install Qt Assistant, Qt Designer, Qt Linguist and Qt Creator.
If you want to try out the latest Qt release, you can download the offline installer from their official website and install it. Just chmod
the installer file to make it executable and run it, and then follow the prompts.
A ‘Hello World’ program (non-GUI)
Open a terminal. Create a directory (first) and create a simple “Hello World” program with the following code:
#include<QtCore> int main(){ qDebug() << "Hello world\n"; }
The included header file QtCore contains declarations for classes that do not use a GUI. We will look at these in detail in later articles. For now, just use the qDebug
class, which outputs debugging messages to the console and is equivalent to cout
in traditional C++ programming.
So how does one compile it? The Trolltech people came out with an easy solution to support cross-platform compilation. First, a project file should be created, and then a Makefile
is created using it. Then, just run make
to compile the program. When you install QT Creator, a utility called qmake
is also installed. This is a cross-platform Makefile
generator for Qt. Check out its man pages for more. Run qmake -project
to create a project file (.pro
extension, with its name that of the containing directory, i.e., first).
$ cat first.pro ###################################################################### # Automatically generated by qmake (2.01a) Mon Nov 28 05:49:29 2011 ###################################################################### TEMPLATE = app TARGET = DEPENDPATH += . INCLUDEPATH += . # Input SOURCES += main.cpp
You can create both applications and libraries; the value of TEMPLATE
is app
, indicating this is an application. I will cover library development in later articles. The SOURCES
entry lists source files in the project, about which more details appear later in this article series.
Now, let us generate the Makefile
with qmake
. It’s a long file — it may contain up to 200 lines. Run make
to create the executable file:
$ make g++ -c -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I. -I. -o main.o main.cpp make: Circular all <- first dependency dropped. g++ -Wl,-O1 -o first main.o -L/usr/lib -lQtGui -lQtCore -lpthread
In the last line, you can see that our sample program uses the POSIX thread library too. Run the file with ./first
to see the output “Hello world”. It’s done! We have successfully compiled our first program.
Sample GUI program
Qt has an option to create UI files using a drag-and-drop method, which we will explore in the next article. For now, let us hand-code a sample simple GUI program:
#include<QApplication> #include<QLabel> int main(int argc, char *argv[]){ QApplication a(argc, argv); QLabel label; label.setText("Hello World"); label.show(); a.exec(); }
In the first example, there was no GUI. The program terminates when main returns. However, in GUI programs, we can’t do that, or the application will not be usable. We want the GUI to run until the user closes the window. To achieve this, run your program in a loop till this happens, so you use the event-loop-based class QApplication
. When you create an object of this class and call its exec()
function, main never returns. The application keeps on waiting for user input events.
The second header file contains the class QLabel
, a simple widget used to display text. Instantiate it and set its text to “Hello World”. When a widget’s show()
function is called, then it becomes a window. So the widget label will be seen like a window. In Figure 2, you can see the resultant label window with title bar. You can resize the output window simply with the help of the mouse.
In the next articles, we will cover the core classes of Qt. In the meanwhile, I suggest you go through the official documentation.
[…] in Coding, Developers · 3 CommentsIn the previous article in this series we went over the installation and some basic examples of Qt. In this article, we will learn how to use the Qt classes for basic data-types and […]
great tutorials there! plz keep up the good work!
sir,can u pls give the coding for the transmission of messages in qtopia .here ,in our project we are using ARM processor(mini2440) and GSM modem for the data transmission
how can display the system applications using QT?
How proficient I need to be in C++ to develop apps using QT?
I have a good hands on C.