- 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 - вот это вопрос ))