Today I’m going to share with you how to use Qt to create a program launcher.

Operation effect:

Making links:

Github.com/alamminsalo…

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

Here’s how to do it.

1. Create a QML application

In Qt Creator click:

-> File -> New File or Project

-> Applications -> Qt Quick Application

Then click Next all the way until Finish.

2. Parse the configuration file

For the applications that have been installed on Linux,

There are configuration files in /usr/share/applications,

Describes how to start the application, as follows:

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

Take bcompare.desktop as an example:

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

Copy the code

Parameter Meaning:

  • The Name field is the Name of the application,

  • The Exec field is the startup command for the application,

  • The Icon field is the name of the app’s Icon,

Parsing configuration files:

// 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); BeginGroup (DESKTOP_ENTRY_STRING); // Locate [Desktop Entry] 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[]) { [...] RootContext ()->setContextProperty("apps", apps()); [...]. }Copy the code

The core is to iterate through all the files in a directory, and the QSettings is responsible for parsing configuration files.

Operation effect:

Exec: "xpad" icon: "xpad" name: "xpad" [...]Copy the code

3. Realize the overall layout

We use SwipeView to realize the function of swiping pages. Refer to my previous article:

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

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

Repeater allows us to generate duplicate content, and here we have a maximum of 24 apps on a page.

SwipeView + Repeater layout:

// 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" } } } } } }Copy the code

The first Repeater is used to implement generating all the pages,

The second Repeater is used to generate all APP ICONS on the page, using the Qt logo instead of the real APP icon.

Operation effect:

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

4. Display application ICONS

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

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

Copy the code

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 // app name text: app[0] [... }}}}Copy the code

Very few changes.

Operation effect:

Only ICONS can be displayed, but mouse selection is still not supported.

5. Select an application

Selecting the application requires adding handling of the mouse hover event.

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

We extracted the interface code of the APP and put it in appentry. QML to make it a separate control.

Then add handling of the mouse hover event to it.

Icon control: appentry.qml

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

When a hovered signal is received from an AppEntry control in main. QML,

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

QML Repeater {model: page. Length AppEntry {app: page[index] [...] Swipeview. selectedIndex === index onHovered: {swipeview. select(index)} [...] }}Copy the code

Operation effect:

This shows the selected status, but it still can’t start the application.

6. Supports application startup

In Qt, you can use QProcess to create processes.

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

Subclasses of QProcess:

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[]) {// Pass an instance of Process to the front-end engine.rootContext()->setContextProperty("proc", new Process(&engine)); }Copy the code

The front end handles click events:

QML Signal clicked() MouseArea {[...]  onClicked: { root.clicked() } }Copy the code

When the user clicks on the icon, the AppEntry control emits a Clicked () signal.

// File: main.qml AppEntry {app: page[index] [... APP onClicked: {exec(APP [2])} [...]  } function exec(program) { console.debug("Exec: " + program) proc.start(program) Qt.quit(); }Copy the code

Finally, Process::start() is called to start the APP.

Operation effect:

So, did you guys 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 networking group?

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