Today, I'd like to share with you how to implement a launcher (program launcher) with Qt.
Operation effect:
github link:
https://github.com/alamminsalo/qml-launcher
There is little code, and the C + + part is about 100 lines of code.
The following is the implementation process.
1. Create 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
Applications installed in Linux system,
There will be corresponding configuration files in / usr/share/applications directory,
It is used to explain how to start the application, as follows:
# ls -1X /usr/share/applications/ apport-gtk.desktop apturl.desktop arduino.desktop audacity.desktop bcompare.desktop ...
Bcompare Take 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 start command of the application,
-
Icon field is the icon name of the application,
Resolve profile:
//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); //Navigate to [Desktop Entry] desktopFile.beginGroup(DESKTOP_ENTRY_STRING); //Extract app information 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 parsed app information to the QML front end engine.rootContext()->setContextProperty("apps", apps()); [...] }
The core is to traverse all files in a directory, and QSettings is responsible for parsing configuration files.
Operation effect:
//Print out all app startup information exec: "xpad" icon: "xpad" name: "Xpad" [...]
3. Realize the overall layout
We use SwipeView to realize the function of sliding page turning. Refer to my previous article:
"Official example of Qt - have you learned these QML versions of HelloWorld?"
As for the layout of a single page, we can use the Repeater control.
Repeater can help us generate duplicate content. Here we specify that a page can display up to 24 app s.
Layout through 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 generate all pages,
The second Repeater is used to generate all APP icons in the page. Here, we first use Qt logo to replace the real APP icon.
Operation effect:
At this time, left-right sliding is supported, but the APP information has not been filled in.
4. Support the display of application icons
In main(), we set an attribute called apps, which contains the information of all apps:
engine.rootContext()->setContextProperty("apps", apps());
We need to replace Qt logo with APP icon in the front-end interface.
Display APP Icon:
//File: main qml Grid { [...] Repeater { model: page !== undefined ? page.length : 0 Column { Image { property var app: page[index] //APP Icon source: "image://icons/" + app[1] [...] } Label { property var app: page[index] id: label //APP name text: app[0] [...] } } } }
Very few changes.
Operation effect:
At this time, only icons are supported, but mouse selection is still not supported.
5. Support selected applications
The selected application needs to add processing for mouse hover events.
When the mouse moves over an icon, Qt will capture the mouse hover event and pass it to the control where the current focus is located.
We extract the interface code of APP and put it separately in appentry QML, making it a separate control,
Then add the processing of mouse hover event.
Icon control: appentry qml
///File: appentry qml Pane { id: root property var app [...] //When the mouse moves to the icon, the signal {hovered() is sent signal hovered() MouseArea { [...] onHoveredChanged: { if (hovered) { root.hovered() } } } Column { anchors.fill: parent Image { source: "image://icons/" + app[1] [...] } Label { [...] } } }
In main When the hovered signal of the AppEntry control is received in QML,
The background color needs to be changed to prompt the user that the icon has been selected.
//File: main qml Repeater { model: page.length AppEntry { app: page[index] [...] //When selected , changes, the background color will change selected: swipeView.selectedIndex === index onHovered: { swipeView.select(index) } [...] } }
Operation effect:
The selected status can be displayed, but the application cannot be started.
6. Support application startup
In Qt, you can use qpprocess to create processes.
Here we create a subclass of qpprocess to run APP.
Subclass of qpprocess:
//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[]) { //Pass the instance of # Process # to the front end engine.rootContext()->setContextProperty("proc", new Process(&engine)); }
Front end processing click event:
//File: appentry qml signal clicked() MouseArea { [...] onClicked: { root.clicked() } }
When the user clicks the icon, the AppEntry control sends a clicked() signal.
//File: main qml AppEntry { app: page[index] [...] //Main window start APP onClicked: { exec(app[2]) } [...] } function exec(program) { console.debug("Exec: " + program) proc.start(program) Qt.quit(); }
Finally call to Process::start(), start APP.
Operation effect:
How's it going? Have you learned it?
- The End -
Recommended reading:
Album | Linux driver development
Album | Linux system programming
Album | one o'clock every day C
Want to join the communication group?
Backstage reply [add group], I'll pull you into the group.