Ответ 1
Я боюсь, что на данный момент Qt5 не поддерживается sni-qt, поэтому вам придется либо ждать нового релиза, который будет его поддерживать, либо использовать его с помощью gtk + и libappindicator, используя это руководство. Есть даже примеры для разных языков. Так как Qt5 также распространяет события GLib, это делает интеграцию намного проще. Сначала вам нужно выяснить, работаете ли вы на Unity или нет (для поддержки большего количества рабочих столов, чем единство), что вы можете сделать, извлекая переменную окружения XDG_CURRENT_DESKTOP, и если она вернет Unity, вы создаете appindicator, в противном случае создадите QSystemTrayIcon.
Сначала вам нужно включить требуемые заголовки:
#undefine signals
extern "C" {
#include <libappindicator/app-indicator.h>
#include <gtk/gtk.h>
}
#define signals public
Так как app-indicator напрямую использует имя "сигналы", нам нужно определить стандартные сигналы ключевого слова Qt, которые обычно переводится на общедоступные. Тогда, поскольку мы кодируем С++, а libappindicator закодирован в C, нам нужно использовать extern "C", чтобы не использовать хэндлинг имени С++.
Затем создайте AppIndicator/QSystemTrayIcon на основе того, на каком рабочем столе мы находимся:
QString desktop;
bool is_unity;
desktop = getenv("XDG_CURRENT_DESKTOP");
is_unity = (desktop.toLower() == "unity");
if (is_unity) {
AppIndicator *indicator;
GtkWidget *menu, *item;
menu = gtk_menu_new();
item = gtk_menu_item_new_with_label("Quit");
gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
g_signal_connect(item, "activate",
G_CALLBACK(quitIndicator), qApp); // We cannot connect
// gtk signal and qt slot so we need to create proxy
// function later on, we pass qApp pointer as an argument.
// This is useful when we need to call signals on "this"
//object so external function can access current object
gtk_widget_show(item);
indicator = app_indicator_new(
"unique-application-name",
"indicator-messages",
APP_INDICATOR_CATEGORY_APPLICATION_STATUS
);
app_indicator_set_status(indicator, APP_INDICATOR_STATUS_ACTIVE);
app_indicator_set_menu(indicator, GTK_MENU(menu));
} else {
QSystemTrayIcon *icon;
QMenu *m = new QMenu();
m->addAction(tr("Quit"), qApp, SLOT(quit()));
}
Наконец, мы создаем прокси-функцию для вызова сигнала Qt из нее, чтобы объявить функцию, которую нам нужно использовать extern "C", поэтому не будет никакого поведения undefined.
extern "C" {
void quitIndicator(GtkMenu *, gpointer);
}
Теперь прокси-функция:
void quitIndicator(GtkMenu *menu, gpointer data) {
Q_UNUSED(menu);
QApplication *self = static_cast<QApplication *>(data);
self->quit();
}