Build a Qt Launcher with QML: A Complete Step‑by‑Step Guide

This tutorial walks you through creating a Qt‑based application launcher using QML and C++, covering project setup, parsing Linux .desktop files, designing a swipeable UI, displaying icons, handling selection, and launching applications via QProcess.

Liangxu Linux
Liangxu Linux
Liangxu Linux
Build a Qt Launcher with QML: A Complete Step‑by‑Step Guide

Introduction

This article demonstrates how to build a simple program launcher on Linux using Qt Quick (QML) and a small amount of C++ code (about 100 lines). The source code is available at

https://github.com/alamminsalo/qml-launcher

.

1. Create a QML Application

In Qt Creator choose

File → New File or Project → Applications → Qt Quick Application

and follow the wizard until finish.

2. Parse .desktop Configuration Files

Installed applications provide a .desktop file under /usr/share/applications. Important fields are Name , Exec , and Icon . Example (bcompare.desktop):

[Desktop Entry]
Name=Beyond Compare
Exec=bcompare
Icon=bcompare
...

The C++ function apps() iterates over the directory, reads each file with QSettings, extracts the three fields, and returns a list of {name, icon, exec} tuples:

// file: main.cpp
QVariantList apps() {
    QVariantList ret;
    QDirIterator it(DESKTOP_FILE_SYSTEM_DIR, ...);
    while (it.hasNext()) {
        const auto filename = it.next();
        QSettings desktopFile(filename, QSettings::IniFormat);
        desktopFile.beginGroup(DESKTOP_ENTRY_STRING);
        AppInfo app;
        app.exec = desktopFile.value("Exec").toString().remove("\"").remove(QRegExp(" %.*"));
        app.icon = desktopFile.value("Icon").toString();
        app.name = desktopFile.value("Name").toString();
        ret.append(QStringList{app.name, app.icon, app.exec});
    }
    return ret;
}

int main(int argc, char *argv[]) {
    ...
    engine.rootContext()->setContextProperty("apps", apps());
    ...
}

3. Implement the Overall Layout

The UI uses SwipeView for horizontal paging and a nested Repeater to generate pages and the icons inside each page. Each page shows up to 24 apps in a 6‑column grid.

// file: main.qml
SwipeView {
    property int selectedIndex: 0
    Repeater {
        id: pageRepeater
        model: appPages.length
        Item {
            property var page: appPages[index]
            Grid {
                columns: 6
                Repeater {
                    model: page.length
                    Image { source: "qrc:/images/qtlogo.png" }
                }
            }
        }
    }
}

4. Show Application Icons

The C++ side passes the apps list to QML. In the grid each item displays the real icon using the image://icons/ provider:

// file: main.qml (excerpt)
Grid {
    Repeater {
        model: page !== undefined ? page.length : 0
        Column {
            Image {
                property var app: page[index]
                source: "image://icons/" + app[1]
            }
            Label { text: app[0] }
        }
    }
}

5. Enable Selection with Hover

A dedicated component AppEntry.qml emits a hovered signal when the mouse hovers over an icon. The main view changes the background of the selected item based on selectedIndex.

// file: AppEntry.qml
Pane {
    id: root
    property var app
    signal hovered()
    MouseArea {
        onHoveredChanged: if (hovered) root.hovered()
    }
    Column {
        Image { source: "image://icons/" + app[1] }
        Label { text: app[0] }
    }
}
// file: main.qml (usage)
Repeater {
    model: page.length
    AppEntry {
        app: page[index]
        selected: swipeView.selectedIndex === index
        onHovered: swipeView.select(index)
    }
}

6. Launch Applications

Launching is handled by a Process class derived from QProcess. The instance is exposed to QML as proc. Clicking an icon calls a JavaScript exec() function that invokes proc.start() and then quits the launcher.

// file: process.h
class Process : public QProcess {
    Q_OBJECT
public:
    Process(QObject *parent = nullptr);
    Q_INVOKABLE void start(const QString &program, const QVariantList &arguments = {});
};

// file: process.cpp
void Process::start(const QString &program, const QVariantList &) {
    QProcess::startDetached(program);
}
// file: AppEntry.qml (click handling)
signal clicked()
MouseArea { onClicked: root.clicked() }
// file: main.qml (click handling)
AppEntry {
    app: page[index]
    onClicked: exec(app[2])
}
function exec(program) {
    console.debug("Exec: " + program);
    proc.start(program);
    Qt.quit();
}

Result

The final launcher displays icons in swipeable pages, highlights the hovered item, and launches the selected program when clicked. Screenshots throughout the article illustrate each development stage.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

QtC++QMLlauncherQt QuickDesktop IntegrationQProcess
Liangxu Linux
Written by

Liangxu Linux

Liangxu, a self‑taught IT professional now working as a Linux development engineer at a Fortune 500 multinational, shares extensive Linux knowledge—fundamentals, applications, tools, plus Git, databases, Raspberry Pi, etc. (Reply “Linux” to receive essential resources.)

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.