Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
QT Systray图标出现在Ubuntu的启动器旁边,而不是面板上_Qt_Ubuntu_Qt5_Systray_Appindicator - Fatal编程技术网

QT Systray图标出现在Ubuntu的启动器旁边,而不是面板上

QT Systray图标出现在Ubuntu的启动器旁边,而不是面板上,qt,ubuntu,qt5,systray,appindicator,Qt,Ubuntu,Qt5,Systray,Appindicator,我是QT新手,需要构建一个带有应用程序指示器的应用程序。由于QT似乎比GTK+更容易,我正在QT中实现它 我要提到的是,我已经安装了sni qt,vlc和skype的应用程序指示器在面板上显示正常。我在Ubuntu 13.04 64位上使用QT5 我循序渐进地学习了本教程: 但当我运行它时,它是这样显示的(十字架是我正在使用的图标): 如何修复此问题?恐怕sni qt目前不支持Qt5,因此您必须等待支持它的新版本,或者使用gtk+和libappindicator对其进行编码。甚至还有各种语言的

我是QT新手,需要构建一个带有应用程序指示器的应用程序。由于QT似乎比GTK+更容易,我正在QT中实现它

我要提到的是,我已经安装了sni qt,vlc和skype的应用程序指示器在面板上显示正常。我在Ubuntu 13.04 64位上使用QT5

我循序渐进地学习了本教程:

但当我运行它时,它是这样显示的(十字架是我正在使用的图标):


如何修复此问题?

恐怕sni qt目前不支持Qt5,因此您必须等待支持它的新版本,或者使用gtk+和libappindicator对其进行编码。甚至还有各种语言的例子。这使得集成更加容易。首先,您需要确定是否在Unity上运行(以支持更多的桌面而不仅仅是Unity),您可以通过检索XDG_CURRENT_DESKTOP环境变量来实现这一点,如果它返回Unity,则创建appindicator,否则创建QSystemTrayIcon

首先,您需要包括所需的标题:

#undefine signals                                                  
extern "C" {                                                                 
  #include <libappindicator/app-indicator.h>                                 
  #include <gtk/gtk.h>                                                       
}                                                                            
#define signals public                                                       
最后,我们创建一个代理函数,从中调用Qt信号,声明我们需要使用extern“C”的函数,这样就不会有任何未定义的行为

extern "C" {                                                                    
  void quitIndicator(GtkMenu *, gpointer);                                            
}                                                                               
现在,代理函数:

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

  self->quit();                                                                 
}
void quittindicator(GtkMenu*菜单,gpointer数据){
Q_未使用(菜单);
QApplication*self=static_cast(数据);
自我->退出();
}

只是想补充一点,对于任何使用Qt并试图在Ubuntu 13+中显示应用程序指示器的人,正如其他人提到的sni Qt不工作,我能够使用上面的回复来制作一个Qt应用程序,仍然试图更改图标并显示弹出消息,但这是一个很好的开始,一旦图标和消息生效,我可能会将其发布到我的网站上:

确保执行
sudo apt get安装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();
}
#包括“dialog.h”
#包括
#包括
#包括
#包括
#包括
#包括
// http://stackoverflow.com/questions/17193307/qt-systray-icon-appears-next-to-launcher-on-ubuntu-instead-of-on-the-panel
//需要libappindicator dev
//sudo apt get安装libappindicator dev
//在:/usr/include/libappindicator-0.1/libappindicator中安装标头
#未定义信号
外部“C”{
#包括
#包括
无效指示器(GtkMenu*,gpointer);
}
#定义公共信号
无效指示器(GtkMenu*菜单,gpointer数据){
Q_未使用(菜单);
QApplication*self=static_cast(数据);
自我->退出();
}
void ShowUnityAppIndicator()
{
应用指标*指标;
GtkWidget*菜单,*项;
menu=gtk_menu_new();
item=gtk_菜单_item_new_带_标签(“退出”);
gtk_菜单_外壳_附加(gtk_菜单_外壳(菜单),项目);
g_信号连接(项目“激活”,
G_CALLBACK(quittindicator),qApp);//我们无法连接
//gtk信号和qt插槽,所以我们需要创建代理
//函数之后,我们将qApp指针作为参数传递。
//当我们需要调用“This”上的信号时,这很有用
//对象,以便外部函数可以访问当前对象
gtk_widget_show(项目);
指示器=应用程序\指示器\新(
“唯一应用程序名称”,
“指示信息”,
应用程序\指示器\类别\应用程序\状态
);
应用程序指示器设置状态(指示器,应用程序指示器状态激活);
app_指示器_设置_菜单(指示器、GTK_菜单(菜单));
}
void ShowQtSysTray(QApplication*应用程序,QDialog*对话框)
{
Q_INIT_资源(资源);
如果(!QSystemTrayIcon::isSystemTrayAvailable()){
QMessageBox::critical(0,QObject::tr(“Systray”),
tr(“我无法检测到任何系统托盘”
“在这个系统上。”);
}
QApplication::setQuitOnLastWindowClosed(false);
QSystemTrayIcon*trayIcon=新QSystemTrayIcon(对话框);
QAction*Action=新QAction(“你好”,对话框);
QMenu*trayIconMenu=新建QMenu(对话框);
trayIconMenu->addAction(“退出”,应用程序,插槽(退出());
trayIconMenu->addAction(操作);
trayIcon->setContextMenu(trayIconMenu);
trayIcon->setIcon(QIcon(:/icons/icons/accept.png));
trayIcon->show();
trayIcon->showMessage(“标题”、“消息”);
}
int main(int argc,char*argv[])
{
质量保证申请a(argc、argv);
对话w;
//确定桌面类型
QString桌面;
布尔是统一的;
桌面=getenv(“XDG_当前_桌面”);
is_unity=(desktop.toLower()=“unity”);
如果(是统一的)
{
ShowUnityAppIndicator();
}
其他的
{
//以Qt方式显示SystemTrayIcon
showqtstray&a&w;
}
//w.show();
返回a.exec();
}

这是哪个版本的Qt?你试过最新版本(5.1.0-rc1)吗?我认为GTK+对象不能很好地处理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();
}