Today I want to share with you how to implement a Launcher using Qt.

Operation effect:

Making links:

https://github.com/alamminsal…

Very little code, about 100 lines of code in the C++ section.

The following is the implementation process.

1. Create a QML application

In Qt Creator, click:

-> File -> New File or Project

-> Applications -> Qt Quick Application

Then click Next all the way to Finish.

2. Parse the configuration file

Linux installed applications,

Will be available in /usr/share/applications.

To show how to start the application:

# ls -1X /usr/share/applications/ apport-gtk.desktop apturl.desktop arduino.desktop audacity.desktop bcompare.desktop .

Take bCompare. Desktop as an example:

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

Field meaning:

  • The Name field is the Name of the application,
  • The Exec field is the startup command applied,
  • The Icon field is the name of the Icon applied,

Parsing the configuration file:

// 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); [Desktop Entry] DesktopFile.BeginGroup (Desktop_entry_String); // Extract the app info appInfo app; app.exec = desktopFile.value("Exec").toString().remove("\"").remove(QRegExp(" %.")); app.icon = desktopFile.value("Icon").toString(); app.name = desktopFile.value("Name").toString(); // Save app information ret. Append (qStringList {app.name, app.icon, app.exec}); } return ret; } int main(int argc, char *argv[]) { [...] // Pass the app information to the QML front-end engine. RootContext ()->setContextProperty("apps", apps()); [...]. }

The core is to traverse all the files in a directory, and QSettings takes care of parsing the configuration files.

Operation effect:

Exec: "xpad" icon: "xpad" name: "xpad" [...]

3. Achieve the overall layout

We use Swipeview to implement the function of sliding pages, refer to my previous article:

The Qt official sample | this a few QML version of the HelloWorld you learn?”

For a one-page layout, we can use the Repeater control.

Repeater allows us to generate repeated content, and here we specify a maximum of 24 apps to be displayed on a page.

Layout with SwipeView + Repeater:

// 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" } } } } } }

The first Repeater is used to implement generating all pages,

The second Repeater is used to generate the ICONS of all apps on the page, replacing the actual APP ICONS with the Qt logo.

Operation effect:

Swipe left and right is now supported, but APP information is not filled in yet.

4. Support for displaying app ICONS

In main(), we set a property called apps, which contains information about all apps:

engine.rootContext()->setContextProperty("apps", apps());

We need to replace the QT logo with the APP icon in the front interface.

Display APP icon:

// File: main.qml Grid {[...]  Repeater { model: page ! == undefined ? Page. Length: 0 Column {Image {property var app: page[index] // app source: "Image :// ICONS /" + app[1] [...] } Label {property var app: page[index] id: Label // text: app[...] }}}}

Very few changes.

Operation effect:

Only display ICONS are supported, but mouse selection is still not supported.

5. Supports selected apps

Selecting an application adds handling for mouse hover events.

When the mouse moves over an icon, Qt captures the mouse hover event and passes it to the control where the current focus is.

We extracted the interface code of the APP and put it in AppEntry.qml separately to make it an independent control.

It then adds handling for mouse hover events.

Icon control: AppEntry.qml

File: appentry.qml Pane {id: root property var app [...] // send overed() signal overed() MouseArea {[...]  onHoveredChanged: { if (hovered) { root.hovered() } } } Column { anchors.fill: parent Image { source: "image://icons/" + app[1] [...]  } Label { [...] }}}

When you receive the Hovered signal of the AppEntry control in main.qml,

The background color needs to be changed to indicate that the icon has been selected.

// file: main.QML Repeater {model: Page. Length AppEntry {app: Page [index] [...] Select === index onHovered: {swipeView.select(index)} [...] select: swipeView.select(index)} }}

Operation effect:

This shows the selected status, but it still fails to launch the application.

6. Support to launch the application

In Qt, you can use QProcess to create a process.

Here we create a subclass of QProcess to run our APP.

Subclasses of QProcess:

// File: process.cpp void process ::start(const QString &program, const QVariantList &arguments) {[...]  QProcess::startDetached(program); } // 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: Main.cpp int main(int argc, char *argv[]) {// Passing an instance of Process to the front-end engine. RootContext ()->setContextProperty("proc", "proc", new Process(&engine)); }

Front end handling click events:

// file: appEntry.qml sign-clicked () mouseArea {[...]  onClicked: { root.clicked() } }

When a user clicks on an icon, the AppEntry control issues a clicked() signal.

// file: main.qml AppEntry {app: page[index] [...] // Main window starts APP onClicked: {exec(APP [2])} [...]  } function exec(program) { console.debug("Exec: " + program) proc.start(program) Qt.quit(); }

Finally, call Process::start() to start the APP.

Operation effect:

Well, did you get it?

— The End —

Recommended reading:

Album | Linux driver development

Album | Linux system programming

Album | a little C every day

Album | Qt entry

Want to join a communication group?

Backstage reply [add group], I pull you into the group.