Qt Linux - Lesson 001. Autorun Qt application under Linux

Qt, Linux, Ubuntu, autorun, автозапуск

Let's talk about how you can add functionality in Qt application to configure startup of the application. For example, we have a settings window, and we want to make the ability to customize the dialog box Autorun application.

In contrast to the autorun in Windows , where you can use QSettings and make changes to the registry on Linux you need to create a custom executable file that will be responsible for autostart applications when a user logs into the operating system.

Say the name of the project and hence the name of the executable file will AutorunLinux , then you need to create an executable file AutorunLinux.desktop the following path:

~/.config/autostart/AutorunLinux.desktop

The contents of the executable file to do the same to other startup files of other applications that are guaranteed to get the desired result. In the case of Ubuntu Linux 15.04 / 15.10 contents of the file will receive the following:

[Desktop Entry]
Type=Application
Exec=/home/dekadent/QT/Projects/build-AutorunLinux-Desktop_Qt_5_5_1_GCC_64bit-Debug/AutorunLinux
Hidden=false
NoDisplay=false
X-GNOME-Autostart-enabled=true
Name[en_GB]=AutorunLinux
Name=AutorunLinux
Comment[en_GB]=AutorunLinux
Comment=AutorunLinux

Where Exec parameter specifies the path to the executable file.

Also, do not forget to make the file executable:

chmod +x ~/.config/autostart/AutorunLinux.desktop

To be guaranteed to ensure correct startup file contents being prepared, I recommend to start to add your application to autostart with a standard utility Startup Applications .

This utility will create a guaranteed working version of the file for your application. Then you just need to add content through the code with an automatic modification of the path to the executable file.

Project structure

To demonstrate the code, I suggest the following to create a project with the following contents:

  • AutorunLinux.pro - the profile of the project;
  • widget.h - header file of the main application window;
  • widget.cpp - file source code of the main application window;
  • widget.ui - form the main application window;
  • main.cpp - the main file of the application source code.

This application will be a checkbox, as we will delete and add applications to the startup by pressing the PushButton button. When running the application will pop up a message that the application is running. The appearance of the application as follows:

widget.h

In the header file of all the changes will be only ad slot to press the button:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

private slots:
    void on_pushButton_clicked();

private:
    Ui::Widget *ui;
};

#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QMessageBox>
#include <QDir>
#include <QFile>
#include <QTextStream>
#include <QStandardPaths>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    QMessageBox::information(this,"AutoRun","Apllication is started!");
}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_pushButton_clicked()
{
    // Path to the autorun folder
    QString autostartPath = QStandardPaths::standardLocations(QStandardPaths::ConfigLocation).at(0) + QLatin1String("/autostart");
    /* Check whether there is a directory in which to store the autorun file.
     * And then you never know ... user deleted ...
     * */
    QDir autorunDir(autostartPath);
    if(!autorunDir.exists()){
        // Если не существует, то создаём
        autorunDir.mkpath(autostartPath);
    }
    QFile autorunFile(autostartPath + QLatin1String("/AutorunLinux.desktop"));
    /* Check the state of the checkbox, if checked, adds the application to the startup.
     * Otherwise remove
     * */
    if(ui->checkBox->isChecked()) {
        // Next, check the availability of the startup file
        if(!autorunFile.exists()){

            /* Next, open the file and writes the necessary data
             * with the path to the executable file, using QCoreApplication::applicationFilePath()
             * */
            if(autorunFile.open(QFile::WriteOnly)){

                QString autorunContent("[Desktop Entry]\n"
                                       "Type=Application\n"
                                       "Exec=" + QCoreApplication::applicationFilePath() + "\n"
                                       "Hidden=false\n"
                                       "NoDisplay=false\n"
                                       "X-GNOME-Autostart-enabled=true\n"
                                       "Name[en_GB]=AutorunLinux\n"
                                       "Name=AutorunLinux\n"
                                       "Comment[en_GB]=AutorunLinux\n"
                                       "Comment=AutorunLinux\n");
                QTextStream outStream(&autorunFile);
                outStream << autorunContent;
                // Set access rights, including on the performance of the file, otherwise the autorun does not work
                autorunFile.setPermissions(QFileDevice::ExeUser|QFileDevice::ExeOwner|QFileDevice::ExeOther|QFileDevice::ExeGroup|
                                       QFileDevice::WriteUser|QFileDevice::ReadUser);
                autorunFile.close();
            }
        }
    } else {
        // Delete the startup file
        if(autorunFile.exists()) autorunFile.remove();
    }
}

Conclusion

As a result of the application of this code will make itself to the startup and run when a user logs into the system. To test performance, create an application using the autorun file, log out and log in again (Log Out/ Log In).

The source code of the project: AutorunLinux

We recommend hosting TIMEWEB
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.
Support the author Donate
a

Спасибо за статью!

Пример рабочий! Со своим проектом тоже получилось!


Наткнулся на эту статью когда решал задачу запуска Qt app с помощью .

Когда пробовал с помощью получилось запустить простой проект Qt с QCoreApplication. Т.е. без gui.

Для этого оказалось достаточно создать файл (в моем случае) в /etc/systemd/system/

[Unit]
Description=qt_console_app service desription

[Service]
ExecStart=/home/user/cpp_examples/build/build_qt_console_app/qt_console_app
Restart=always

[Install]
WantedBy=graphical.target

И запустить:


Но если хочу запускать проект Qt с gui - не получается!

С помощью видно ошибку:

QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-root'
сен 21 11:29:44 debian systemd-demo[11389]: qt.qpa.screen: QXcbConnection: Could not connect to display
сен 21 11:29:44 debian systemd-demo[11389]: Could not connect to any X display.

Пытался играться с переменными DISPLAY и с Xauthority. Но воз и ныне там.

Только что на линуксовой форуме прочитал, что не для приложений с gui. Там советуют пользоваться средствами автозапуска. Это, скорее-всего, и есть тема данной статьи, которая сработало.

Не подскажете, может ли есть какой-то путь, хитрости, чтобы, всё-таки, запустить проект Qt с GUI с помощью ?


И второй вопрос. Через пробовал в том числе потому что нужен рестарт приложения, если упадет. Там всего-лишь дописывается одна строчка в вышеприведенный файл.

И с помощью Вашего подхода можно ли как-то дописать авторестарт при падение программы?

Если я вас правильно понял, то авторестарт сюда дописывается  QString autorunContent.
Не могли бы вы не выделять пока слова жирным текстом, в комментариях сломан парсинг тегов, завтра буду чинить. Поэтому съедаются жирные слова.

a

Не могли бы подробнее рассказать об этой возможности? Я докопался до запросов Desktop Entry Files + restart, но до сих пор не найду autorunContent, о котором Вы писали...

Ну я имел ввиду, что дописать в коде вот сюда то, о чём вы говорили про рестарт

QString autorunContent("[Desktop Entry]\n"
                                       "Type=Application\n"
                                       "Exec=" + QCoreApplication::applicationFilePath() + "\n"
                                       "Hidden=false\n"
                                       "NoDisplay=false\n"
                                       "X-GNOME-Autostart-enabled=true\n"
                                       "Name[en_GB]=AutorunLinux\n"
                                       "Name=AutorunLinux\n"
                                       "Comment[en_GB]=AutorunLinux\n"
                                       "Comment=AutorunLinux\n");
a

Просто сейчас правлю сам файл example.desktop. Пытаюсь понять какую пару key=value мне нужно дописать.

Если честно, то я не уверен, что это вообще можно реализовать через *.desktop файл. Я сделал предположение на основе того, что вы сказали про *.desktop и рестарт.

Все варианты, которые встречаются на форумах, предполагают наличие демона, который следит за тем, чтобы программа была онлайн.

Например я использую supervisor для автостарта сервисов сайта. Поэтому перезагрузка скриптов сайта у меня делается через killall. Грубовато, но supervisor ещё ни разу не подводил.



a

Не могли бы дать ссылку на пример? Какое-то рабочее использование. Т.е. у меня есть Qt Gui App, которое я бы хотел запускать при старте системы и в случае, если оно грохнется. Если о чем Вы говорите это поможет сделать, не могли бы просвятить в виде ссылки или примерного направление копания))

А вот здесь у меня есть пример использования supervisor.

https://evileg.com/ru/post/3/

Вся статья вам там не интересна, интересен только шаг с настройкой supervisor. Он получается будет у вас как зависимость к вашему приложению, но вопрос зависимостей - это уже отдельная тема для разговора. В данном случае к самому программированию supervisor отношения не имеет. Это настройка демона.


a

Спасибо! На данный момент выбор пал в сторону скрипта с бесконечным циклом, перегружающим программу при падение.

Здесь подробнее описал.

Comments

Only authorized users can post comments.
Please, Log in or Sign up
Donate

Hello, Dear Users of EVILEG!!!

If the site helped you, then support the development of the site financially, please.

You can do it by following ways:

Thank you, Evgenii Legotckoi

AF
April 7, 2020, 9:15 a.m.
Andrey Fedorov

C++ - Тест 003. Условия и циклы

  • Result:71points,
  • Rating points1
A
April 6, 2020, 5:24 a.m.
Alexey

C++ - Test 001. The first program and data types

  • Result:86points,
  • Rating points6
R
April 5, 2020, 2:32 p.m.
Roman

C++ - Test 002. Constants

  • Result:91points,
  • Rating points8
Last comments
K
April 7, 2020, 8:55 a.m.
KULINAR847

А вот уже и на python... #!/usr/bin/env python# -'''- coding: utf-8 -'''-import sysfrom PySide2.QtWidgets import *from PySide2.QtQuick import *from PySide2.QtCore import *from PySide2.…
April 3, 2020, 8:06 a.m.
Konstantin Grudnitskiy

Я надеюсь вы уже разобрались в чем дело, но если вдруг нет, то проблема состоит в том, что вы пытаетесь запустить программу из интерпретатора питона. Файл main.py это уже готова…
April 3, 2020, 6:18 a.m.
Konstantin Grudnitskiy

>>> text = 'hello world'>>> ' '.join(word for word in text.split()[:-1])'hello'>>> def remove_last_word(text):... return text and ' '.join(word for word in text.s…
March 27, 2020, 2:40 p.m.
Evgenij Legotskoj

Добрый день. В конце пятой статьи скачать можете.
March 27, 2020, 2:28 p.m.
mkdir _

Здравствуйте, а можно, пожалуйста, ссылку на целые исходники, если есть?
Now discuss on the forum
s
April 6, 2020, 8:06 a.m.
shuric

Добрый день. Объясните пожалуйста ... ... допиливать стилевое оформление в прокси классе ... где именно копать ? В каком виртуальном методе лучше допиливать (если можно н…
April 6, 2020, 4:19 a.m.
Evgenij Legotskoj

Попробуй не переустанавливать материал, а просто менять цвет
April 5, 2020, 11:38 a.m.
Mihailll

Так работает windeployqt --qmldir E:\QTProject\testQmlAndCpp E:\test\build-testQmlAndCpp-Desktop_Qt_5_14_1_MinGW_32_bit-Release
April 5, 2020, 2:35 a.m.
Mihailll

Так работает console.log(textEmail.text) var str = textEmail.text; var n = str.search(/^((([0-9A-Za-z]{1}[-0-9A-z\.]{1,}[0-9A-Za-z]{1})|([0-9А-Яа-я]{1}[-0-9А-я\.]{1,}[…
April 3, 2020, 8:48 a.m.
Intruder

Евгений, добрый день. Спасибо!
EVILEG
About
Services
© EVILEG 2015-2019
Recommend hosting TIMEWEB