How To Create a Linux Desktop App In 14 Minutes For Beginners (Using QDevelop and Qt4)
Create this application by following this tutorial


Overview

This tutorial is designed for absolute beginners, even if you have programmed in other languages and are new to Linux and C++ then this tutorial will help get you up and running with Qt and C++.

Who am I?
My name is Clive and I am 54 years old and I have been programming for over 25 years but it has mostly been under DOS/Windows. My main programming languages have been Pascal, C, Assembler, Basic, PIC.
I have only been programming in Ubuntu and C++ using Qt4 for a few months.
It took me a lot of reading and messing around to finally get to the point where I could produce an application.
Qt4 is cross-platform, personally I have no interest in the cross-platform concept at all, I just wanted to produce a few minor applications for myself to use in Ubuntu.
I have created this tutorial to teach a friend who wants to learn to write Qt applications in Ubuntu.
If you have any comments/suggestions about this tutorial you can email me at the following email address


Things you will need in order to complete this tutorial.
I am running Ubuntu edgy v6.10 Linux with the Gnome desktop, if your setup is different from this then you will need to fathom out for yourself how to install Qt4 and Exuberant CTags.

1.. The C++ compiler.
Bring up a terminal window and type sudo apt-get install build-essential this will install the C++ compiler and the Linux header files.

2.. Qt4
In synaptic package manager search for qt4 and check the following items for install.

libqt4-core
libqt4-debug
libqt4-gui
libqt4-qt3support
libqt4-sql
qt4-designer
qt4-dev-tools
qt4-doc
qt4-qtconfig

To be honest I don't know if all those items are required so feel free to experiment or just install them all to be sure.

3.. Exuberant CTags
In synaptic package manager just do a search for ctags and check exuberant-ctags for install.

4.. QDevelop
QDevelop is a work in progress and as such it does have a few bugs, nothing major but it is best that you get into the habit of saving your programming code often.
Next you need to visit the QDevelop website and download the latest version of QDevelop.
http://www.qdevelop.org
QDevelop will need to be compiled, if you are running the same version of Ubuntu as I am you can try the ready compiled version I am using from here.
You need to setup a directory structure for programming, this is simple, in your home directory create a directory called qdevelop and in the qdevelop directory create another directory called apps.
The apps directory will be your default project directory, QDevelop will create directories for each of your projects in this directory.
Copy the compiled version of qdevelop into the qdevelop directory and set it to executable.
Create a desktop launcher for qdevelop and you are ready to start the tutorial.


Start QDevelop
Creating a new project
From the QDevelop main menu

    Select Project>New Project
In the window that appears....
Under Template....
    Select "Application with main window"
Under Properties....
    Set the location to your apps development directory. (This will be remembered in future)
    Set the project name to myfirst or whatever name you want.
Under Version....
    Select debug version
Leave the rest as it is and click OK.
QDevelop will create all the necessary directories and files for a complete working X11 Qt application.

Testing the project
On the QDevelop main menu....
    Select Build>Build
Notice the build messages in the Output section at the bottom of QDevelop.
When it is completed it should say Build finished without error you should not get any errors at this stage.
Whenever you build your project you should keep an eye on this output window making sure that the build completes before you try running your project.

On the QDevelop main menu....
   select Debug>Debug or it may be Debug>Start, this item seems to change its name now and again.
   be patient, wait a few moments and your application will run.
All you have is a blank X11 window application that does nothing, but it's the starting point of a project.
Just click the cross in the top right corner to close your new application and also select Debug>Stop from the main menu if it is available. Sometimes when you stop your application the debugger doesn't release it correctly and they is why you need to check if Debug>Stop is available and select it if it is.

Designing our project's main window
We are now ready to turn our project into an application that does something.

The first thing we need to do is to design and layout our main user interface (the main window)

In the project explorer on the left under dialogs double click the ui/mainwindow.ui entry.
Be patient while the Qt Designer loads and you will be presented with your project's main window in Qt Designer ready for design.

The first thing we need to do is setup Qt Designer as a single application rather than having a number of individual windows. On the main menu select Edit>User Interface Mode>Docked Window.
You may prefer to keep Qt Designer as it is with separate windows but this is how it is being setup for this tutorial.

Next undock the Property Editor from the right hand side and dock it on the left with the Widget Box.
Here is an Image of what Qt Designer now looks like on my PC. (click the image to see it full size)


Designing our window

QDevelop created a default main window for us that has an empty main menu and a status bar.
We will not need either of these, so right click on each item and select to remove/delete them.
Also you can resize your application window to whatever size you want it.

A Widget is what we call all of the objects like PushButtons and LineEdits that can be placed on a window.

Next we are going to add some widgets to our window and setup the window to look how we want it to look.
For the purposes of this tutorial I am going to use a LineEdit, ListWidget and a PushButton.
The idea behind this application is that the user will enter text into the LineEdit, then they will click on the PushButton and this will add their text to the ListWidget.

To add these widgets to our window just click and hold on the widget from the Widget Box on the left and drop
The widgets onto our window. Your window should now look similar to image1.

Window with widgets
Image 1.
Note: Qt has a Widget called a ListView and one called a ListWidget, we are using the ListWidget.


Now we need to place our widgets on the window in such a way that when the window is resized the widgets all
resize neatly and automatically for us, so this is what we do....
Click and drag the mouse pointer on the window and you will see a dotted line box appear, extend the box so that
it touches the LineEdit and the PushButton but NOT the ListWidget and then let go of the mouse button.
Both the LineEdit and the PushButton are now selected just like in Image 2.
Selected Items One
Image 2
We want these items to remain side by side rather than one above the other so we click on the toolbar button

to layout horizontally. see Image 3.

Image 3
A red line appears around the LineEdit and PushButton joining them together horizontally. As in Image 4.


Image 4
Next click and drag the mouse pointer on the window again and select all the widgets. As in Image 5.


Image 5
This time we want the ListWidget to be above our LineEdit and PushButton widgets so we click the toolbar

button to layout vertically. See Image 6.

Image 6
You may need to resize your window so you can see the complete layout.

Next we need to make the widgets fix themselves to the size of the window, to do this click once on the actual
window background so that none of the widgets are selected.
Now click the toolbar button to layout in a grid. See Image 7.

Image 7
Your window should now look something like this. Image 8.


Image 8
If you now resize your window the widgets will automatically resize with the window.

To see a preview of what your window will look for press Ctrl-R, to close the preview just close it like you would
with any other application by clicking on the X in the top right corner.

So now we have the design of our window, next we need to set some of the properties for our widgets.
To do this we use the property editor on the left.
Select the PushButton by clicking on it in the window.
The properties for a PushButton are now displayed in the property editor, the item at the top is the Object Name.
Change the name to btAdd.
Next scroll down the property editor until you come to the text property and enter &Add. See Image 9 below.

Image 9

Next select the LineEdit on the main window and set its Object Name to edText.

Next select the ListWidget and change its Object Name to lbMyList.

Being fussy
If you are anything like me you will be thinking that the border between the widgets and the window itself is just too damn big. Not a problem, we can just change it.
In the Object Inspector select the item called centralwidget, now scroll to the bottom of the Property Editor and change the margin from 9 to about 2 or whatever you prefer.
You can also change the spacing for the QVBoxLayout and QHBoxLayout, this will reduce the spacing between the widgets. Here in Image 10 is the final layout.

Image 10
Our window's title bar text is MainWindow, by now you should be proficient enough to work out how to change it to whatever you want.

There are lots of other properties for all the widgets and the main window itself, you can experiment by changing them later to become familiar with using Qt Designer and understanding the properties of the widgets.
From Qt Designer's main menu select File>Save Form.
We are finished with Qt Designer for now so just close it and go back to QDevelop.

Checking our designed window compiles okay
In QDevelop select Build>Build from the main menu and when the build is complete select Debug>Start and our
Application will run and you should see the window laid out just as you did it in Qt Designer.
Resize and play with your new application if you wish and then close it.

Now we can write some source code

I am not going to tell you how to write C++ programs, I am no expert by any stretch of the imagination. My intention is to show you how I write my code.
C++ is a case sensitive language, so "Hello" is not the same as "hello". This is often the most common reason for compilation errors. basically you need to work out a format for doing things and "Stick To It".

Naming convention
All variable and function names begin with a lowercase character and if they consist of more than one word then each consecutive word begins with a capital letter. i.e. myLittleString    tinyLittleInteger   extractFileName()

Style
void testing()
{
  int f;
  f = 11;
  while(f < 20)
    f++;
  if(f == 19)
  {
    t = f;
  }
}

The function above is just nonsense code but it is used to display my style, there are many ways to write C++ code. I suggest you find what works for you and stick to it.

You do not need to be a C/C++ programmer
When writing Qt applications you are mainly writing Qt code and very little in the way of C or C++. If you want some help with the basics of C/C++ then click this link for a very basic tutorial. Most C/C++ tutorials will go into the detail and structure of C/C++ but if you are just having a bit of fun producing Qt applications for your own use then 99% of what you should know about C/C++ is of no real use to you. So my little tutorial on C/C++ just gives you enough to get by.

Interacting with the main window
One of the first things we need to understand about Qt is its SIGNAL and SLOT, various widgets emit signals and you can tie these signals to slots. A slot can be a standard function in your application.
For example one of the signals emitted by a button is called 'clicked' and if we want to do something when the button is clicked we can create a function of our own and connect the 'clicked' signal to that slot.
Here is the code to create a signal/slot.

connect(btAdd, SIGNAL(clicked()), this, SLOT(addClicked()));

This is pretty much self explanatory but basically it connects the clicked() signal emitted by a button called btAdd to a function called addClicked(). The word 'this' is a pointer to our application and it just says that the slot we are connecting to is in this application. Like I say I am no expert on C++ or Qt and I do not have all the answers but this explanation of 'this' will suffice until I know better.

Writing the code
Slots need to be declared as slots in the .h header file, here is the .h file with the slot declaration added.

#ifndef MAINWINDOWIMPL_H
#define MAINWINDOWIMPL_H

#include "ui_mainwindow.h"

class MainWindowImpl : public QMainWindow, public Ui::MainWindow
{
Q_OBJECT
    public:
        MainWindowImpl( QWidget * parent = 0, Qt::WFlags f = 0 );
    private slots:
        void addClicked();
};
#endif


A word of caution at this point, every C++ file wether it's a .h or a .cpp file should always have a blank line at the end, if it doesn't the compiler will complain.

Next we add the connection and the slot itself to the .cpp file, the slot is empty, we have yet to write the code for it.
#include "mainwindowimpl.h"

MainWindowImpl::MainWindowImpl( QWidget * parent, Qt::WFlags f)
    : QMainWindow(parent, f)
{
    setupUi(this);
    connect(btAdd, SIGNAL(clicked()), this, SLOT(addClicked()));
}

void MainWindowImpl::addClicked()
{

}


Save and test regularly
At this point it is a good idea to build the project just to make sure there are no errors, it is much easier to write small pieces of your application and building it as you go rather than writing hundreds of lines of code and then having to wade through ten or twenty errors. So try to get into the habit of building your application often and solving the errors as you go.

Writing our first function
Now we will write the code for our slot, this code will run every time the button is pressed.
So let us think about what we want to happen when the button is clicked and perhaps more importantly we need to think about what could happen when the button is clicked.
For example, the idea is that the user enters some text in the LineEdit and then they click the button. Our program is going to add what they typed to the ListWidget, but what if they press the button without entering any text at all?
These are the kinds of things that programmers have to think about, the what if?
Always try to think about what a user of your application may do.
So let's write the code for the slot.

void MainWindowImpl::addClicked()
{
    if(edText->text() == "")    // If there is no text then exit this function
    {
        return;
    }
    lbMyList->addItem(edText->text()); // Add the text typed to the list
    edText->setText("");    // erase the text from the box they typed in
    edText->setFocus();    // set the focus back to the LineEdit from the button
}

This is the completed function with lots of comments explaining what things do.
If you add this text to the function and build and run your application you should find it works.

A project for you to play around with
I have created a small application that allows you to change the time stamp of files, basically it is a frontend for the touch utility in Linux. Feel free to download this project and look through the code, you can even change the way it works if you wish.
Click here to download it.

Credits.
My hat is off to the guys at Trolltech, Qt4 is an excellent API that comes with enough documentation to sink a battleship. The documentation can be a little difficult to get used to at first but persistence wins in the end.
The Qt forums are an excellent source of help but please try to find your answers from the Qt4 documentation first.
The Qt Centre also has a massive forum and is another place to find answers to questions and general knowledge and information about Qt.

QDevelop really does make working with Qt easy, I have tried many other IDE's to work with Qt4 and none of them come even close to making things as simple as QDevelop does.

I am intending to put together a website dedicated to code snippets and how-to's for Qt4, I will place a link here as soon as the website is ready, so please check back later.

Comments received

Addition :- 6th June 2007
Email received from Stephan.......

With reference to the following text....

"A word of caution at this point, every C++ file wether it's a .h or a .cpp file should always have a blank line at the end, if it doesn't the compiler will complain."

That's a bit misleading. What the file needs is a trailing newline at the end of the final line, which isn't quite the same as a blank line at the end of the file.

The reason for this is that "text file" has a technical definition and part of that definition is that each line ends with a trailing newline (or carriage-return/newline on Windows). It often happens that the last line of a file is missing that character, and when this happens the file is violating the technical definition of "text file". That's why gcc, cvs, and some other tools complain about this type of error.

Thanks for the explanation Stephan.

Addition :- 6th June 2007
Email received from Clint Webb

"The word 'this ' is a pointer to our application and it just says that the slot we are connecting to is in this application. Like I say I am no expert on C++ or Qt and I do not have all the answers but this explanation of 'this' will suffice until I know better."


I just wanted to clarify that what you said is true in the example you give, but can be misleading.  'this' actually refers to the current object.  If you are calling that connect() from the application object, then 'this' does indeed refer to the application.   However, you can also call connect() from other objects (from the form itself for example), and in that case you would also probably want to pass 'this' to the connect() function, but in this case its not referring to the application but to the form.

I haven't read the whole article yet, but looks like a pretty good primer. Thanks.


Thanks Clint.

Copyright 2007 Clive Cooper