Mobile
Article

Developing Cross Platform Applications with Qt

By Jay Raj

Qt is a cross platform application development framework with a long history and now maintained by the Qt Project. It enables developers to create applications and UIs for desktop, embedded and mobile operating systems. It provides a GUI (Graphical User Interface) for ease of development and allows creation of hybrid applications. Applications can be developed using C++ or the QML language, a JavaScript like language.

In this tutorial, we’ll get started with Qt framework and create a beginner’s application.

Source code from this tutorial is available on GitHub.

Setting up Qt

To get started with Qt, download the Qt installer for your operating system from the download page and run it. You can find more details related to installing Qt on various platforms in the official docs.

Once the installation is complete, open the application and here is how it should look:

Qt Create screen

Configure Qt for Android Development

To get started with developing Android applications or widgets using Qt, we need to configure a few things first. Open the Tools -> Options (Application Menu -> Preferences on Mac) menu and you should see the screen below.

Setting Qt options

From the left hand side menu, select Android and configure the required paths to JDK location, Android SDK location, Android NDK location (you may need to download this) and Ant executable.

Setting Qt configuration

What we’ll be creating

In this tutorial we’ll create a simple calculator for Android. It will support addition, subtraction, multiplication and division.

Getting started

From the Qt Creator, open the File -> New File or Project menu item. From the window that opens, select an Applications project and then Qt Widgets Application as shown below:

Creating Qt project

Click Choose… to proceed and on the next screen, name your widget as CalWidget and click next. On the next screen, select the Android kit and proceed (On some OSs, the ‘next’ button may be ‘continue’).

Selecting Android

Next you’ll see the class information details screen. Rename the Class name to CalWidget. Click next to configure version control which is not required at the moment. Click Next and then Finish to create the project structure. Here is how the project structure should look now:

Code Overview

Some of the files we should see in the project are calwidget.h, calwidget.cpp, main.cpp and calwidget.ui. All these files already have some boiler plate code. First, we’ll create our UI and then return to these files to add our required functionality.

Creating the UI

Qt Creator provides an interface where we can drag and drop controls on to the screen and create our UI. Double click on the calwidget.ui file (inside the Forms folder) and it will open up a screen with controls. Here is how it should look:

qt UI designer

From the list of controls on the left hand side, try dragging and dropping controls onto the widget screen. We’ll need an input text control, label control and button control to create our UI. So drag and drop several Push Button, Label andLine Edit controls onto the widget screen to create a screen as shown:

Interface overview

To run the widget press Ctrl/Cmd+R and you should be able to see the widget running in the emulator.

If you get errors regarding missing button functions when building, Qt seems to hold on to old object names from the last build if you have renamed them. Open Headers -> calwidget.h and delete their references.

Implementing functionality

Next we’ll try to read data from the input text boxes and display the result based on the operation clicked.

To attach a click event to the push buttons, right click on the button and select go to slot, from the signals listed select the clicked signal. As you do, click event functions like below are generated in calwidget.cpp:

void CalWidget::on_btnAdd_clicked()
{
    // Code for Addition logic
}

When the operation button is clicked, we need to read the text value from the input text boxes. To access the elements in the UI, we’ll make use of the ui variable declared above. So the code to access any ui element by id is as follows:

ui->(*elementId*)->text()

Inside the add button click, read the input text box values, sum it and display the result in the lblResult label. Here is my add button click code:

void CalWidget::on_btnAdd_clicked()
{
    int input1,input2,result;

    // reading from input boxes
    input1 = ui->txtNum1->text().toInt();
    input2 = ui->txtNum2->text().toInt();

    // summing it up
    result = input1+input2;

    // Create a QString using the result
    QString qString = QString::number(result);

    // Assign result qString to lblResult label
    ui->lblResult->setText(qString);

}

Save your code and press Ctrl/Cmd+R to run the code. Input values into the text boxes, click Add and you should be able to see the output.

Here is the code for all the four click events :

// Add operation click event
void CalWidget::on_btnAdd_clicked()
{
    int input1,input2,result;
     // reading from input boxes
    input1 = ui->txtNum1->text().toInt();
    input2 = ui->txtNum2->text().toInt();
    result = input1+input2;

    // Assign result to lblResult label
    QString qString = QString::number(result);
    ui->lblResult->setText(qString);

}

// Sub operation click event
void CalWidget::on_btnSub_clicked()
{
    int input1,input2,result;
     // reading from input boxes
    input1 = ui->txtNum1->text().toInt();
    input2 = ui->txtNum2->text().toInt();
    result = input1-input2;

    // Assign result to lblResult label
    QString qString = QString::number(result);
    ui->lblResult->setText(qString);
}

// Mul operation click event
void CalWidget::on_btnMul_clicked()
{
    int input1,input2,result;
     // reading from input boxes
    input1 = ui->txtNum1->text().toInt();
    input2 = ui->txtNum2->text().toInt();
    result = input1*input2;

    // Assign result to lblResult label
    QString qString = QString::number(result);
    ui->lblResult->setText(qString);
}

// Div operation click event
void CalWidget::on_btnDiv_clicked()
{
    int input1,input2,result;
     // reading from input boxes
    input1 = ui->txtNum1->text().toInt();
    input2 = ui->txtNum2->text().toInt();
    result = input1/input2;

    // Assign result to lblResult label
    QString qString = QString::number(result);
    ui->lblResult->setText(qString);
}

Try running the app and check the output for all the implemented operations.

Next, we’ll add validation to our code to check for empty and non numeric values. An approach for checking validation is using QString. It provides certain built in libraries which makes validations easier. Instead of reading the input text values into integer variables, we’ll use QString variables. QString has an inbuilt function called isEmpty which we can use to check for empty values. To validate for both non numeric values and empty values, we’ll use the toInt() and toFloat() functions. Both the functions return 0 on trying to convert non-numeric strings.

Here is the modified code with validations included:

void CalWidget::on_btnAdd_clicked()
{
    QString input1,input2;
    int result;
    QString qString = NULL;

    // Read from input text 
    input1 = ui->txtNum1->text();
    input2 = ui->txtNum2->text();


    int isNumber1 = input1.toInt();
    int isNumber2 = input2.toInt();

    // Check if numeric
    if(isNumber1 && isNumber2){
        result = input1.toInt()+input2.toInt();
        qString = QString::number(result);
        ui->lblResult->setText(qString);
    }
    else{
        qString = QString::fromStdString("Enter Valid Numbers");
        ui->lblResult->setText(qString);
    }

}

void CalWidget::on_btnSub_clicked()
{
    QString input1,input2;
    int result;
    QString qString = NULL;

    // Read from input text 
    input1 = ui->txtNum1->text();
    input2 = ui->txtNum2->text();


    int isNumber1 = input1.toInt();
    int isNumber2 = input2.toInt();

    // Check if numeric
    if(isNumber1 && isNumber2){
        result = input1.toInt()-input2.toInt();
        qString = QString::number(result);
        ui->lblResult->setText(qString);
    }
    else{
        qString = QString::fromStdString("Enter Valid Numbers");
        ui->lblResult->setText(qString);
    }
}

void CalWidget::on_btnMul_clicked()
{
    QString input1,input2;
    int result;
    QString qString = NULL;

    // Read from input text 
    input1 = ui->txtNum1->text();
    input2 = ui->txtNum2->text();


    int isNumber1 = input1.toInt();
    int isNumber2 = input2.toInt();

     // Check if numeric
    if(isNumber1 && isNumber2){
        result = input1.toInt()*input2.toInt();
        qString = QString::number(result);
        ui->lblResult->setText(qString);
    }
    else{
        qString = QString::fromStdString("Enter Valid Numbers");
        ui->lblResult->setText(qString);
    }
}

void CalWidget::on_btnDiv_clicked()
{
    QString input1,input2;
    float result;
    QString qString = NULL;

    // Read from input text 
    input1 = ui->txtNum1->text();
    input2 = ui->txtNum2->text();


    float isNumber1 = input1.toFloat();
    float isNumber2 = input2.toFloat();

    // Check if numeric
    if(isNumber1 && isNumber2){
        result = input1.toFloat() / input2.toFloat();
        qString = QString::number(result);
        ui->lblResult->setText(qString);
    }
    else{
        qString = QString::fromStdString("Enter Valid Numbers");
        ui->lblResult->setText(qString);
    }
}

Conclusion

In this tutorial, we looked at how to get started with Qt by creating a simple application for the android platform. We only used some basic features of Qt, for in-depth information on Qt and its features, have a look at their official docs.

Would you use Qt? Do you feel it offers any advantages over other cross platform development options?

  • https://www.viewneo.com/ Ron Gonzalez Lobo

    Hey,

    great tutorial.

    Could you make a series out of this and indroduce the use of the unreal engine with Qt here?

    Thanks in advance

    • Chris Ward

      I’m sure we can have more!

      • bluehenmountain

        If I develop in Qt, I then have my binary code to submit myself via iTunes Connect. But that means I’ve spent another $99 on the Apple Development Portal to get access to iTunes Connect. Does Qt have direct submission that bypasses the need for iTunes Connect?

  • Foobar

    Using QT for commercial android application costs money, doesn’t it ?
    I know that the NDK alone is a pure shit and that QT is truly amazing.
    But as a junior developer I can’t pay for commercial licence…

  • Chris Ward

    A lot of these ‘high end’ cross platform tools are typically commercial for commercial releases sadly, as a freelancer I often have the same problem. You have to weigh up your development time vs the cost, sometimes it can be a better deal.

  • Adriano Garcez

    Do I have any chance to do a decent GUI for android using QT Designer?
    The apk is functional, but impossible to use due to its poor interface.

    • Chris Ward

      Do you mean, do you have a chance to make one? If so, I think you do!

      • Adriano Garcez

        Sorry, English is not my first language.

        I managed to make a android app fixed at 1280×720 using qtdesigner, so I can’t scroll down. It’s working fine, ugly as hell, but I can use it now.

        • Chris Ward

          OK, Qt is cross platform, that can sadly lead to some unattractive interfaces at times.

        • Chris Ward

          OK, Qt is cross platform, that can sadly lead to some unattractive interfaces at times.

          • Adriano Garcez

            I read that QML is normally used to develop cross platform on QT, but I didn’t figured out how it works with signal and slots yet… =/

Recommended

Learn Coding Online
Learn Web Development

Start learning web development and design for free with SitePoint Premium!

Get the latest in Mobile, once a week, for free.