2013-06-19 3 views
10

Я новичок в QT и мне нужно создать приложение с индикатором приложения. Поскольку QT кажется проще, чем GTK +, я делаю это в QT.Значок QT Systray появляется рядом с пусковой установкой на Ubuntu, а не на панели

Я бы упомянул, что у меня установлен sni-qt, а индикаторы приложения vlc и skype отображаются нормально на панели. Я использую QT5 на Ubuntu 13.04 64-бит.

Я последовал за этот учебник шаг за шагом: http://qt-project.org/doc/qt-4.8/desktop-systray.html

Но когда я запускаю его, вот как это выглядит (Крест значок я использую):

http://i.stack.imgur.com/4bT33.png

Как я почини это?

+1

Какая версия Qt является что? Вы пробовали последнюю версию (5.1.0-rc1)? – peppe

ответ

13

Я боюсь, что в настоящий момент Qt5 не поддерживается sni-qt, поэтому вам придется либо ждать нового релиза, который будет поддерживать его, либо закодировать его с помощью gtk + и libappindicator, используя this guide. Есть даже примеры для разных языков. Since Qt5 also distributes GLib events, что делает интеграцию намного проще. Сначала вам нужно выяснить, используете ли вы Unity или нет (для поддержки большего количества рабочих столов, чем единство), что вы можете сделать, извлекая переменную окружения XDG_CURRENT_DESKTOP, и если она вернет Unity, вы создаете appindicator, иначе создайте QSystemTrayIcon.

Прежде всего, необходимо включить необходимые заголовки:

#undefine signals             
extern "C" {                 
    #include <libappindicator/app-indicator.h>         
    #include <gtk/gtk.h>              
}                    
#define signals public              

Поскольку приложение-индикатор непосредственно использует название «сигналы» нам нужно неопределенные сигналы «ключевое слово» по умолчанию Qt на который обычно переводит к общественности. Затем, поскольку мы кодируем C++, а libappindicator закодирован в C, нам нужно использовать extern «C», чтобы не использовать кодирование имен 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 от него, чтобы объявить функцию, мы должны использовать Экстерн «C» поэтому не будет никакого неопределенного поведения.

extern "C" {                  
    void quitIndicator(GtkMenu *, gpointer);            
}                    

Теперь функция прокси:

void quitIndicator(GtkMenu *menu, gpointer data) {          
    Q_UNUSED(menu);                
    QApplication *self = static_cast<QApplication *>(data);      

    self->quit();                 
} 
+0

haha ​​nice one .. – Goddard

+0

Я не думаю, что GTK + объекты играют хорошо с циклом событий Qt. [Этот образец] (http://paste.ubuntu.com/7687674/) приводит к [этим ошибкам] (http://paste.ubuntu.com/7687666/). –

5

Просто хотел бы добавить, для тех, кто использует Qt и пытается показать индикатор приложения в Ubuntu 13+, как уже упоминалось сни-кварты не работая, я смог использовать приведенный выше ответ, чтобы создать приложение Qt, которое все еще пытается получить значок для изменения и отображения всплывающих сообщений, но это отличный старт, как только я получу значок и сообщение для работы, я могу опубликовать его на моем сайте Voidrealms.com:

Обязательно сделайте sudo apt-get install libappindicator-dev

Создайте новый проект с QDialog в нем и модифицировать, как показано ниже:

Pro файл:

#------------------------------------------------- 
# 
# Project created by QtCreator 2014-03-28T20:34:54 
# 
#------------------------------------------------- 

QT  += core gui 

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 

TARGET = PluginServiceGUI 
TEMPLATE = app 

# includes for the libappindicator 
# /usr/lib/x86_64-linux-gnu libglib-2.0.a 

INCLUDEPATH += "/usr/include/libappindicator-0.1" 
INCLUDEPATH += "/usr/include/gtk-2.0" 
INCLUDEPATH += "/usr/include/glib-2.0" 
INCLUDEPATH += "/usr/lib/x86_64-linux-gnu/glib-2.0/include" 
INCLUDEPATH += "/usr/include/cairo" 
INCLUDEPATH += "/usr/include/pango-1.0" 
INCLUDEPATH += "/usr/lib/x86_64-linux-gnu/gtk-2.0/include" 
INCLUDEPATH += "/usr/include/gdk-pixbuf-2.0" 
INCLUDEPATH += "/usr/include/atk-1.0" 

LIBS += -L/usr/lib/x86_64-linux-gnu -lgobject-2.0 
LIBS += -L/usr/lib/x86_64-linux-gnu -lappindicator 
LIBS += -L/usr/lib/x86_64-linux-gnu -lgtk-x11-2.0 

#These seem to not be needed 
#LIBS += -L/usr/lib/x86_64-linux-gnu -lcairo 
#LIBS += -L/usr/lib/x86_64-linux-gnu -lpango-1.0 
#LIBS += -L/usr/lib/x86_64-linux-gnu -lglib-2.0 

# end incudes for libappindicator 


SOURCES += main.cpp\ 
     dialog.cpp 

HEADERS += dialog.h 

FORMS += dialog.ui 

RESOURCES += \ 
    resources.qrc 

В main.cpp

#include "dialog.h" 
#include <QApplication> 
#include <QtGui> 
#include <QSystemTrayIcon> 
#include <QMessageBox> 
#include <QSystemTrayIcon> 
#include <QMenu> 

// http://stackoverflow.com/questions/17193307/qt-systray-icon-appears-next-to-launcher-on-ubuntu-instead-of-on-the-panel 
// requires libappindicator-dev 
// sudo apt-get install libappindicator-dev 
// installs the headers in: /usr/include/libappindicator-0.1/libappindicator 

#undef signals 
extern "C" { 
    #include <libappindicator/app-indicator.h> 
    #include <gtk/gtk.h> 

    void quitIndicator(GtkMenu *, gpointer); 

} 
#define signals public 

void quitIndicator(GtkMenu *menu, gpointer data) { 
    Q_UNUSED(menu); 
    QApplication *self = static_cast<QApplication *>(data); 

    self->quit(); 
} 

void ShowUnityAppIndicator() 
{ 
    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)); 
} 



void ShowQtSysTray(QApplication* app, QDialog* dialog) 
{ 

    Q_INIT_RESOURCE(resources); 

    if (!QSystemTrayIcon::isSystemTrayAvailable()) { 
     QMessageBox::critical(0, QObject::tr("Systray"), 
           QObject::tr("I couldn't detect any system tray " 
              "on this system.")); 
    } 
    QApplication::setQuitOnLastWindowClosed(false); 


    QSystemTrayIcon* trayIcon = new QSystemTrayIcon(dialog); 
    QAction* Action = new QAction("hello", dialog); 
    QMenu* trayIconMenu = new QMenu(dialog); 

    trayIconMenu->addAction("Quit", app, SLOT(quit())); 

    trayIconMenu->addAction(Action); 
    trayIcon->setContextMenu(trayIconMenu); 
    trayIcon->setIcon(QIcon (":/icons/Icons/accept.png")); 

    trayIcon->show(); 
    trayIcon->showMessage("Title","Message"); 
} 



int main(int argc, char *argv[]) 
{ 



     QApplication a(argc, argv); 
     Dialog w; 

     //Determine the desktop type 
     QString desktop; 
     bool is_unity; 

     desktop = getenv("XDG_CURRENT_DESKTOP"); 
     is_unity = (desktop.toLower() == "unity"); 

     if(is_unity) 
     { 
      ShowUnityAppIndicator(); 
     } 
     else 
     { 
      //Show the SystemTrayIcon the Qt way 
      ShowQtSysTray(&a, &w); 
     } 

    // w.show(); 

    return a.exec(); 
} 
Смежные вопросы