- 1. Структура проекта
- 2. віджет.h
- 3. widget.cpp
- 4. Підсумок
Поговоримо, про те, як додати в Qt програму функціонал з налаштування автозапуску даної програми. Наприклад, у нас є вікно налаштувань і хочемо зробити можливість налаштування автозапуску програми з цього діалогового вікна.
На відміну від автозапуску у Windows , де можна скористатися QSettings та внести зміни в реєстр, в Linux потрібно створити спеціальний файл, який буде відповідати за автозапуск програми при вході користувача в операційну систему.
Допустимо назву проекту і відповідно назва виконуваного файлу буде AutorunLinux, тоді потрібно буде створити файл AutorunLinux.desktop наступним шляхом:
- ~/.config/autostart/AutorunLinux.desktop
Вміст файлу, що виконується, потрібно зробити аналогічним іншим файлам автозапуску інших програм, щоб гарантовано отримати необхідний результат. У випадку з Ubuntu Linux 15.04/15.10 вміст файлу вийшов так:
- [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
Де параметр Exec вказує шлях до файлу програми, що виконується.
Також не забудьте зробити файл виконуваним:
- chmod +x ~/.config/autostart/AutorunLinux.desktop
Для того, щоб гарантовано бути впевненим у правильності підготовлюваного вмісту файлу автозапуску, рекомендую для початку додати додаток до автозапуску за допомогою стандартної утиліти Startup Applications .
Ця утиліта створить гарантовано робочий варіант файлу для вашої програми. Після чого Вам залишиться тільки додати вміст через програмний код з автоматичною модифікацією шляху до файлу програми, що виконується.
Структура проекта
Для демонстрації програмного коду пропоную створити наступний проект, з таким вмістом:
- AutorunLinux.pro - профайл проекту;
- widget.h - заголовний файл головного вікна програми;
- widget.cpp - файл вихідних кодів головного вікна програми;
- widget.ui - форма головного вікна програми;
- main.cpp - основний файл вихідних кодів програми.
У цьому додатку буде чекбокс, за станом якого ми видалятимемо і додаватимемо програми в автозапуск при натисканні кнопки PushButton. При запуску програми буде вискакувати повідомлення, що програма запущена. Зовнішній вигляд програми:
віджет.h
У заголовному файлі з усіх змін буде лише оголошення слота для натискання кнопки:
- #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()
- {
- // Путь к папке автозапуска
- QString autostartPath = QStandardPaths::standardLocations(QStandardPaths::ConfigLocation).at(0) + QLatin1String("/autostart");
- /* Проверяем, существует ли директория, в которой будет храниться файл автозапуска.
- * А то мало ли... пользователь удалил...
- * */
- QDir autorunDir(autostartPath);
- if(!autorunDir.exists()){
- // Если не существует, то создаём
- autorunDir.mkpath(autostartPath);
- }
- QFile autorunFile(autostartPath + QLatin1String("/AutorunLinux.desktop"));
- /* Проверяем состояние чекбокса, если отмечен, то добавляем приложения в автозапуск.
- * В противном случае удаляем
- * */
- if(ui->checkBox->isChecked()) {
- // Далее проверяем наличие самого файла автозапуска
- if(!autorunFile.exists()){
- /* Далее открываем файл и записываем в него необходимые данные
- * с указанием пути к исполняемому файлу, с помощью 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;
- // Устанавливаем права доступа, в том числе и на исполнение файла, иначе автозапуск не сработает
- autorunFile.setPermissions(QFileDevice::ExeUser|QFileDevice::ExeOwner|QFileDevice::ExeOther|QFileDevice::ExeGroup|
- QFileDevice::WriteUser|QFileDevice::ReadUser);
- autorunFile.close();
- }
- }
- } else {
- // Удаляем файл автозапуска
- if(autorunFile.exists()) autorunFile.remove();
- }
- }
Підсумок
В результаті роботи даного коду програма вноситиме себе в автозапуск і запускатиметься при вході користувача в систему. Для перевірки працездатності, створіть за допомогою програми файл автозапуску, вийдіть із системи та увійдіть знову (Log Out/ Log In).
Вихідний код проекту: AutorunLinux
Спасибо за статью!
Пример рабочий! Со своим проектом тоже получилось!
Наткнулся на эту статью когда решал задачу запуска Qt app с помощью .
Когда пробовал с помощью получилось запустить простой проект Qt с QCoreApplication. Т.е. без gui.
Для этого оказалось достаточно создать файл (в моем случае) в /etc/systemd/system/
И запустить:
Но если хочу запускать проект Qt с gui - не получается!
С помощью видно ошибку:
Пытался играться с переменными DISPLAY и с Xauthority. Но воз и ныне там.
Только что на линуксовой форуме прочитал, что не для приложений с gui. Там советуют пользоваться средствами автозапуска. Это, скорее-всего, и есть тема данной статьи, которая сработало.
Не подскажете, может ли есть какой-то путь, хитрости, чтобы, всё-таки, запустить проект Qt с GUI с помощью ?
И второй вопрос. Через пробовал в том числе потому что нужен рестарт приложения, если упадет. Там всего-лишь дописывается одна строчка в вышеприведенный файл.
И с помощью Вашего подхода можно ли как-то дописать авторестарт при падение программы?
Если я вас правильно понял, то авторестарт сюда дописывается QString autorunContent.
Не могли бы вы не выделять пока слова жирным текстом, в комментариях сломан парсинг тегов, завтра буду чинить. Поэтому съедаются жирные слова.
Не могли бы подробнее рассказать об этой возможности? Я докопался до запросов Desktop Entry Files + restart, но до сих пор не найду autorunContent, о котором Вы писали...
Ну я имел ввиду, что дописать в коде вот сюда то, о чём вы говорили про рестарт
Просто сейчас правлю сам файл example.desktop. Пытаюсь понять какую пару key=value мне нужно дописать.
Если честно, то я не уверен, что это вообще можно реализовать через *.desktop файл. Я сделал предположение на основе того, что вы сказали про *.desktop и рестарт.
Все варианты, которые встречаются на форумах, предполагают наличие демона, который следит за тем, чтобы программа была онлайн.
Например я использую supervisor для автостарта сервисов сайта. Поэтому перезагрузка скриптов сайта у меня делается через killall. Грубовато, но supervisor ещё ни разу не подводил.
Не могли бы дать ссылку на пример? Какое-то рабочее использование. Т.е. у меня есть Qt Gui App, которое я бы хотел запускать при старте системы и в случае, если оно грохнется. Если о чем Вы говорите это поможет сделать, не могли бы просвятить в виде ссылки или примерного направление копания))
А вот здесь у меня есть пример использования supervisor.
https://evileg.com/ru/post/3/
Вся статья вам там не интересна, интересен только шаг с настройкой supervisor. Он получается будет у вас как зависимость к вашему приложению, но вопрос зависимостей - это уже отдельная тема для разговора. В данном случае к самому программированию supervisor отношения не имеет. Это настройка демона.
Спасибо! На данный момент выбор пал в сторону скрипта с бесконечным циклом, перегружающим программу при падение.
Здесь подробнее описал.
как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))