First, a quick recap. Last time we created three versions of Qt: Qt/X11, Qt/QVFb and Qt/target. The two first versions are for your development machine, while the later is for building Qt applications for your target platform. If you don’t have a target platform, you can still play along, this entry is only about the virtual framebuffer. Next time, we’ll look at the target version.
The virtual framebuffer is a tool that you built as a part of the Qt/X11 install. The binary, called qvfb, and is located in the /usr/local/Trolltech/Qt-version/bin directory.
As you have several instances of Qt, where the tools have the same name, you cannot simply add the bin directories to your PATH. Instead, I suggest creating a local bin directory and then create symbol links to each tool. For instance, qvfb-451 could point to the qvfb of your Qt 4.5.1 install. In a similar manner, qmake-version-x11, qmake-version-qvfb and qmake-version-target are handy names for the different qmake instances.
Having started QVFb, you get the boring window shown above. To remedy this, select File – Configure…. The dialog (below) lets you setup everything about QVFb – resolution, bit-depth, skins, and more.
By selecting one of the skins (Trolltech-Touchscreen from Qt 4.5.0 in my case – I guess they forgot to change that name to Qt Software) you get a skinned version of the virtual framebuffer. You can move it around by simply dragging and dropping, the buttons work and it looks generally good.
Notice that you can alter the settings of QVFb from the command prompt as well. The argument -skin lets you specify a skin while -width, -height and -depth does what they are expected to do.
Another useful aspect of skinning QVFb is that is is a great tool for creating screenshots for your end user documentation. This generally requires custom skins – something that we will look at later on in this series.
Now, all that is left is to run an application. Go to the source tree of your Qt/QVFb and locate examples/widgets/wiggly. To get this running inside the QVFb, first start an instace of the virtual framebuffer and configure it, then run ./wiggly -qws. The argument tells wiggly that it is the Qt Windowing Server, i.e. that it handles the framebuffer device. Without it, it will complain about not being able to connect.
If you can get wiggly running, then you have a proper setup. Now try your own applications. To build your project for QVFb, use the qmake from Qt/QVFb and recompile. To change to Qt/X11, run a make distclean, then the qmake from Qt/X11 and recompile. The distclean part is important, to avoid confusing the build system.
Big thanks to Alexis and Lykurg for helping me with the css issues when viewing a single article at a time. I hope that all the pages should look better now.
When developing applications for an embedded Linux platform, you need to setup a development machine. That machine needs to be running Linux (if you only have Windows boxes, try running a virtual machine). You also need a few key components. There are a few pre-requisites that you need to have in place:
A cross compiler for your target. I.e. a set of tools to build applications for your target environment. If that environment uses the same CPU, glibc and OS as your development machine, this is the same compiler as you are using there. The more likely case is that you will have a specific compiler for your target called something like arm-linux-gcc.
A target with a framebuffer.
If you want to play with embedded Qt without an actual device. You can skip this part and just build the Qt/X11 and Qt/QVFb versions described below.
If you have those two parts, we can start building a Qt environment. First, start by downloading the latest versions of Qt/X11 and Qt for embedded Linux. While that downloads, let’s look into what we are trying to do.
Qt keeps the configuration of the Qt version being used in the qmake utility. The qmake utility is built when Qt is being configured, i.e. before you even compile Qt. We are aiming at building three versions of Qt, so you will have three different instances of qmake. Your job is to keep them apart. We will build the following Qt configurations:
Qt/X11, qmake-x11. This is the Qt version that you will be using on your PC. It is also used for building the tools, such as Designer and Linguist.
Qt/QVFb, qmake-qvfb. This is an embedded Qt configuration that runs on host, but works with the virtual framebuffer instead of the actual screen. The let’s you emulate the target system, but run your code on your host machine.
Qt/target, qmake-target. This is the embedded Qt configuration that runs on your target platform. This is what you use to build and actual application running on your embedded device.
Target or host? The host machine is your development PC, i.e the machine hosting all the source and tools. The target is the device that you are targetting, i.e. the device that is supposed to run your embedded application.
The Qt/X11 build can usually be the Qt installed by default on your distro. I, however, still prefer to build my own Qt. The commands usually goes like ./configure && make -jN, where N is the number of CPUs on your system plus one. When the build is complete (it takes a long time), you need to install it, and you will probably have to do that as root. On ubuntu and derivates, run sudo make install, on non-sudo-distros, run su to become root, then run make install from your root command prompt. The installation will end up in the /usr/local/Trolltech/Qt-<version> directory. You can change this by specifying a prefix when configuring.
You will also have to build the QVFb tool, i.e. the viewer part of the Qt Virtual Framebuffer. We will use this look later, but first, enter the tools/qvfb directory, and run make, then make install (with sudo or su, as when installing all of Qt).
The next step is to build the Qt/QVFb version. This is a variant of embedded Qt, so start by unpacking the embedded Qt source code, then rename the directory to qt-embedded-linux-opensource-src-version to qt-qvfb-version. This is to prevent the other embedded variant that we will build from overwriting this source code.
To build Qt/QVFb, we will need a slightly more complex configure line. The following options is really a minimum, you can add the -help option to configure to learn more.
- -qt-gfx-qvfb, the graphics driver will be for QVFb, i.e. the virtual framebuffer.
- -qt-kbd-qvfb, the keyboard input will come from the QVFb.
- -qt-mouse-qvfb, the mouse input will come from the QVFb.
- -prefix /usr/local/Trolltech/Qt-qvfb-version, the prefix is used to separate the QVFb version of embedded Qt from the target version.
Having configured the environment, building and installing this version of Qt is no different from the Qt/X11 build (and it takes just as long).
The final version of Qt to build is Qt/target – in my case Qt/arm. This is slightly more complex, as you will have to tell Qt how to cross compile itself for your target. Start by uncompressing the embedded Qt source code again. This time, let’s rename the directory qt-target-version (e.g. qt-arm-version).
Configuring Qt for an embedded target involves two steps (at least). You will need to create a mkspec, helping Qt understanding how to build for your system. Then you need to configure Qt for your target.
So, first things first. The mkspecs for embedded systems are kept in the mkspecs/qws directory. Here, you can usually find a good starting point. For instance, in my case the mkspecs/qws/linux-arm-g++ looks about right. Opening the qmake.conf file, I can verify that the name of the compiler, linker, and all the other tools look right. The default, arm-linux-*, looks right, so I can use this file right away.
The next step is to configure Qt, both to understand the embedded target, to reduce size and to use the right mkspec. I generally start by running ./configure -help, to get an overview of the available options. Below follows a list of the configure options that I recommend using:
First of all, you need to get the cross compilation right:
- -embedded arm
- -xplatform qws/linux-arm-g++
Then, we want a release build for target, and we want a prefix:
- -prefix /usr/local/Trolltech/Qt-target-version
You need to know the colour depth of your screen:
- -depth 16
Finally, there are a number of libraries that you can build into Qt, to avoid having to deploy them separately. If you have no other need for the libraries, I generally compile them as a part of Qt:
In a similar manner, some options can be turned off (make sure to go through the entire help message to disable anything that you won’t be using):
Finally, we need to make sure that Qt uses the right keyboard, mouse and screen drivers:
This will give you a fairly long configuration line. It might be good to know that the file config.status is created when you configure Qt and contains your last attempt. I say last attempt, because this process can take some tweaking.
Now, all you need to do is to make and make install as with the previous Qt versions. This should give you a nicely configured Qt for your target environment. Next time, we will take all the Qt versions you’ve built for a test ride.
There is just loads of issues that one can run into when deploying across multiple platforms. So much to take into account, and so many details to handle.
As Qt supports tree desktop platforms, there are at least three deployment methods. However, the Linux platform is pretty fragmented when it comes to this, so here, reading the local packaging rules might be a good idea.
For Windows, I’ve used mingw in combination with InnoSetup. InnoSetup is free (as in beer), but solves the task nicely. Downloading the dependency walker helps figuring out which Qt dll’s that are needed (not deploying all of Qt can save loads of megs). If you’re using mingw, do not forget the mingwm10.dll, and make sure that you actually build a release version of your software (debug symbols are heavy).
When it comes to the OS X platform, my experience is very limited (I’ve used a MacMini to play music from iTunes… that’s about it). To the rescue comes the blog entry Deploying Qt-based frameworks made simple by Dominik Kapusta. He tells us about the little script macdeployqt that seems to do the job.
When designing forms using Qt, you do not place the widgets at static locations. Instead, you place them in layouts. This makes the user interfaces stretchable and allows them to adapt to the current screen and contents.
There are many arguments for using flexible layouts instead of fixed locations – especially if you are planning to use Qt’s cross platform capabilities. Different systems use different fonts and different users prefer different styles.
There are a few common issues that you tend to run into when using fixed locations and sizes. The first example involves a poor translator that needs to work around small widgets by using awkward words. For instance, below, you can see the English word Previous over the Swedish translation Föregående. Let’s just hope for understanding Swedish users – or we can let the button stretch with the text.
Another really annoying situation is when the contents of a dialog box simply is too large. For instance, the list of names below. Being able to stretch the dialog and see the full names could really help.
So, how do you get started with layouts? First, let’s look at the four basic types of layouts available.
Horizontal layouts simply places the contained widgets next to each other in a horizontal line.
Vertical layouts places the contained widgets over each other in a vertical line.
Grid layouts lets you place your widgets in a stretchable grid. You can even have widget spanning over several rows and columns.
Form layout is used when creating property forms. This is a special case of the grid layout with only two columns. The alignment of the labels as well as the sizing of the actual fields to fill out depends on the platform. For instance, the picture below shows the GTK+ and Plastique style (look at the labels and the size of the QComboBox).
You find these four in the Designer toolbar in QtCreator. So, how do you design a form using layouts? I prefer to place the widgets roughly as I want them, then to apply layouts from the inside out. That means, starting with then inner group boxes and frames, working my way out until I finally apply a layout to the form itself.
Let’s look at an example. First, the widgets are placed.
The next step is to apply a vertical layout to the group box. Simply select the group box in the form and apply the layout using the toolbar button.
Then, we apply a grid layout to the dialog. Make sure to stretch the group box to make it wider before selecting the form itself and applying the layout. If you don’t stretch the dialog, it will not span both columns, meaning that you’ll have an empty upper right corner.
As you can tell from the picture above, this does not give us a perfect result. There is one more thing to keep in mind. An important factor that you need to master is the use of spacers (the springs in the widget box). They work just as invisible springs, so they have a big impact on how dialogs stretch.
Let’s break the layout of the form. Simply select the form and click the break layout button in the toolbar. Then we add some springs to the dialog. We need one vertical spring to keep the group box from expanding too much, and one horizontal spring to keep the buttons from growing too wide.
Do not use the layouts in the widget box, instead, place widgets on the form and apply layouts. This is usually much easier.
Then we have places the buttons together with the horizontal spring in a horizontal layout (simply drag to select multiple widgets, or press shift and click). Before applying a vertical layout to the entire form.
The result is a stretchable dialog that looks good both small and large.
There is more to this topic – size policies being the most important factor not mentioned here. We will return to the subject later on. In the mean time, practice on creating dialogs using layouts. It is a craft and you need to practice to master it.
The Unlikely Source
Qt is Open Source, the code is available for us to peak inside and learn. But let be honest it’s unlikely that we do that. I have for once found the need to do so, to find if the implementation took ownership of the memory allocation or not. The Source is the ultimate source from where one can learn.
Assistant is the collection of Qt Documentation shipped along with Qt SDK. The documentation catalogs all classes and modules. It offers API description, code snippets on API usage. Assistant should be the first place where one should head to when in doubt. Look at the appropriate class, ask yourself if your looking for an expected SIGNAL that should be emitted, or a SLOT for a setter function. Assistant allows user to search the documentation. Since Qt classes names are intuitive, just try searching for what you are looking. A year or two down the line of constant Qt usage you can recall few API in sleep.
I recommend all Qt Newbies execute/run each and every examples/sample shipped with QT once. Fiddle with it see how they work.
Why ? you ask.
2) Next time you have a new requirement you know which example you should look at, ( if you need to that is )
3) Studying Qt example would expose you to C++/Qt specifies idioms.
Once again RUN ALL QT EXAMPLES see what they do.
Spoon feeding please
Lets accept it, most us would just want to ask our problem and be answered. Lucky you if you have a mentor/senior in your team to answer it. If not then head straight to the qt-interest-mailing list , QtForum, QtCenter, stackoverflow. Qt Interest Mailing List is where you can ask your questions by sending an email and the same is send to all subscribers. Mostly someone out there answers your question.
I would suggest to newbies before they ask their questions
1) See if Assistant/Qt Documentation already answers your question,
2) Search the mailing list archive for someone must have asked the same question.
I subscribe to Qt/C++ tags on open source hosting sites Why ? Well the same logic behind running Qt Examples applies here. Here is a real life example How it helped me ?. I completed this visual programming language with my team. My Boss the CEO looked at it and said “Well it works and all, that’s good but …. uhmmm … something is missing ….. uhmm …. it’s doesn’t look cool”. He uses mac, and a blackberry what can you say. So the visual designer redesigned the UI. Here I the programmer who is color blind and thinks he completed the requirement met his deadlines. I know stylesheets but somehow the whole visual redesign sounded boring. So like all good managers I choose to delegate the non exciting part. Asked my subordinate to study couple of qt OSS projects hosted at qt-apps.org that made decent usage of stylesheet, and custom widget painting. The subordinates coded the stylesheet and application now looked like mirror image of the mocks.
Point is the subordinate eliminated the hit and trial process of learning. He became more productive and achieves the end result faster. So keep a tab on qt OSS that come out, run them or see their screenshots.
Here is the list of Qt Books you can learn from. I have read Foundations of Qt Development , C++ GUI Programming with Qt 4 (2nd Edition) – The official C++/Qt book , read selective chapters from An Introduction to Design Patterns in C++ with Qt 4 . In my personal opinion Foundations of Qt Development is better suited to newbies than other books. Design Patterns is a very helpful book if you ever work on a enterprise size product / large OOPS codebase with loads of design patterns being used. One can download the source code that comes along with these books for free too.”
Blogs and Feeds
Blog is the new It thing isn’t it. We have Qt Labs Blogs where the Trolls (Nokia employees working on Qt) blog. I highly recommend you subscribe to Qt Planet. It does the noble task of aggregating Qt specific blogs, so you don’t have to go and find Qt specific blogs.
I personally have benefited at lot from Qt. Knowledge of which got me my first job 3 years back. Since then I have been learning it from the above avenues. Hope if help you too.
Author Information: Ankur is Yet another Indian Software Engineer. He stays with his parents in Mumbai. He is passionate about anything computers, sci-fi, entrepreneurship. He wishes to start his own product based Micro-ISV someday and live happily ever after. You can contact him at versesane -> gmail.
Qt Software has provided the site with a new top banner.Personally, I like it and the latest Qt styling more and more. Also, any graphics created by a designer is by far better than anything created by me. 🙂
One aspect of using Qt is to understand how it works. Signals and slots are great – and there are more nice features: resources, properties, meta types, etc. What is important here is that Qt is still all about C++. Writing a Qt application means writing a C++ application – Qt does not change the language.
So, how does all of this work? Let’s start by having a look at how a C++ application is built.
The source code of a C++ application can be divided into headers (*.h) and sources (*.cpp). There are other extensions such as hxx, hpp, hh, cc, cxx and so on, but I hope that you get the picture. The headers are included by the sources, the sources are compiled into objects and these objects are linked to a executable (or library, etc).
So, what does Qt add to this to let us write nice things as signals and slots? First, macros, meaning that what you write is transformed into plain vanilla C++. Secondly, code generators, completing your application with the C++ code needed to make things work smoothly. Let’s start by looking at the big picture.
Comparing the C++ build system to the Qt build system, you can see that the C++ build system, i.e. the gray boxes, are left unmodified. We are still building C++ code here. However, we add more sources and headers. There are three code generators involved here:
The meta-object compiler (moc in the illustration) – the meta-object compiler takes all classes starting with the Q_OBJECT macro and generates a moc_*.cpp C++ source file. This file contains information about the class being moc’ed such as class name, inheritance tree, etc, but also implementation of the signals. This means that when you emit a signal, you actually call a function generated by the moc.
The user interface compiler (uic in the illustration) – The user interface compiler takes designs from Designer and creates header files. These header files are then included into source files as usual, making it possible to call setupUi to instanciate a user interface design.
The Qt resource compiler (rcc in the illustration) – The resource compiler is something we have not talked about yet. It makes it possible to embedd images, text files, etc into your executable, but still to access them as files. We will look at this later, I just want to include it in this picture where it belongs.
I hope these two illustrations clarifies what Qt really does to add new nice keywords to C++. If you are curious – feel free to read some of the generated files. Just don’t alter them – they are regenerated each time you build your application.
If you are using QtCreator, the moc files are generated in the debug and release sub-directories of your project directory. The uic files are stored in the root of the project directory. The rcc files are generally boring, but I’m sure that you can find them in your project directory hierarcy somewhere.
When I blogged about Qt and BASIC, I was told that Qt and Python is the way to go. I can only agree to this. Riverbank Computing has done a tremendous job, providing Python bindings and tools for Qt to the community. For the Python coders out there, you can get your PyQt4 module from here.
from PyQt4.QtCore import * from PyQt4.QtGui import * if __name__ == "__main__": app = QApplication(sys.argv) w = QWidget() w.show(); app.exec_()