2013-06-19 7 views
10

QTが新しく、アプリケーションインジケータでアプリケーションをビルドする必要があります。 QTはGTK +よりも簡単に見えるので、私はQTで作っています。QT Systrayアイコンは、パネル上ではなくUbuntuのランチャーの横に表示されます。

私はsni-qtがインストールされており、vlcとskypeのアプリケーションインジケータはパネル上で正常に表示されていると言います。私はUbuntu 13.04 64ビットでQT5を使用しています。

私はステップによって、このチュートリアルのステップに続く:http://qt-project.org/doc/qt-4.8/desktop-systray.html

をしかし、私はそれを実行すると、ここで(クロスは、私が使用しているアイコンです)、それが表示される方法は次のとおりです。

私はどのように

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

これを修正しますか?

+1

バージョンです:

それにQDialogで新しいプロジェクトを作成し、下図のように変更します。

Proファイルをそれ?あなたは最新バージョン(5.1.0-rc1)を試しましたか? – peppe

答えて

13

現時点ではQt5はsni-qtでサポートされていないので、サポートする新しいリリースを待つか、this guideを使用してgtk +とlibappindicatorを使用してコードを作成する必要があります。さまざまな言語の例があります。 Since Qt5 also distributes GLib eventsを使用すると、統合がずっと簡単になります。最初にUnity上で実行しているかどうかを確認する必要があります(単一のものより多くのデスクトップをサポートするため)、XDG_CURRENT_DESKTOP環境変数を取得して行うことができ、Unityを返す場合はappindicatorを作成し、そうでなければQSystemTrayIconを作成します。アプリ・インジケータは、直接私たちは通常、公衆に変換され、デフォルトのQt「キーワード」の信号を未定義する必要があり、「信号」の名前を使用するので

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

まず、必要なヘッダファイルをインクルードする必要があります。次に、C++をコーディングするので、libappindicatorがC言語でコード化されているので、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()));      
}                    

最後に、我々はにextern「C」を使用する必要がある関数を宣言し、それからQtの信号を呼び出すためにプロキシ機能を作成しますしたがって、未定義の動作はありません。

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+でアプリインジケーターを表示しようとしている誰もが言及しているためSNI-qtのではなく、追加したいです上記の返信を使って動作するQtアプリを作ることができましたが、まだアイコンを変更してポップアップメッセージを表示しようとしましたが、これは素晴らしいスタートです。それは私のサイトにありますVoidrealms.com

必ずmain.cppには

#------------------------------------------------- 
# 
# 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 

のQtの

#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(); 
} 
関連する問題