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.
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 Applicationand 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.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
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.)
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
