Qt浅谈之三十系统托盘(QSystemTrayIcon)

一、简介

       Qt自带的例子/usr/lib64/qt4/examples/desktop/systray中详尽介绍了系统托盘的功能,在其基础上进行拓展,定制适合自己的系统托盘。
       托盘菜单实现:QSystemTrayIcon+QMenu+QAction,有时需要加入QWidgetAction。

二、详解

 

1、代码

 

(1)systemtray.h

 

#ifndef SYSTEMTRAY_H
#define SYSTEMTRAY_H
#include <QSystemTrayIcon>
#include <QMenu>
#include <QAction>
#include <QApplication>
#include <QWidgetAction>
#include <QtGui>

class SystemTray : public QSystemTrayIcon
{
    Q_OBJECT
public:
    explicit SystemTray(QWidget *parent = 0);
    ~SystemTray();
    void setParentWidget(QWidget *parent);
    void setMiddleClickText(const QString &tips);
    void setHideText(const QString &text);
    void setToolTips(const QString &tips);
    void startHideTips();

private:
    void createActions();
    void createTopWidget();

private slots:
    void slotActivated(QSystemTrayIcon::ActivationReason reason);
    void showParentWidget();
    void slotHelpAction();
    void slotClicked();

private:
    QMenu *trayIconMenu;
    QAction *showAction;
    QAction *helpAction;
    QAction *quitAction;
    QWidget *parentWidget;
    QString middleText;
    QString toolTils;
    QString hideText;
    QMenu *funMenu;
    QWidget *topWidget;
    QWidgetAction *topWidgetAction;
    QPushButton *showButton;
    QPushButton *hideButton;
};

#endif // SYSTEMTRAY_H

(2)systemtray.cpp

#include <QUrl>
#include <QDebug>
#include <QDesktopServices>
#include "systemtray.h"

SystemTray::SystemTray(QWidget *parent)
    : QSystemTrayIcon(parent)
    , middleText("")
    , toolTils("")
    , hideText("")
{
    parentWidget = parent;
    createActions();
    connect(this, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(slotActivated(QSystemTrayIcon::ActivationReason)));
}

SystemTray::~SystemTray()
{

}

void SystemTray::setParentWidget(QWidget *parent)
{
    parentWidget = parent;
}

void SystemTray::setMiddleClickText(const QString &tips)
{
    middleText = tips;
}

void SystemTray::setHideText(const QString &text)
{
    hideText = text;
}

void SystemTray::setToolTips(const QString &tips)
{
    this->setToolTip(tips);
}

void SystemTray::startHideTips()
{
    this->showMessage(tr("提示信息:"), hideText, QSystemTrayIcon::Information, 2000);
}

void SystemTray::createActions()
{
    this->setIcon(QIcon(":/tray.png"));
    trayIconMenu = new QMenu();
    createTopWidget();

    funMenu = new QMenu();
    showAction = new QAction(this);
    helpAction = new QAction(this);
    quitAction = new QAction(this);

    funMenu->setIcon(QIcon(":/fun.png"));
    showAction->setIcon(QIcon(":/show.png"));
    helpAction->setIcon(QIcon(":/help.png"));
    quitAction->setIcon(QIcon(":/quit.png"));

    funMenu->setTitle(tr("功能"));
    showAction->setText(tr("显示"));
    helpAction->setText(tr("帮助"));
    quitAction->setText(tr("退出"));

    trayIconMenu->addAction(topWidgetAction);
    //trayIconMenu->setFixedWidth(250);
    trayIconMenu->addAction(showAction);
    funMenu->addAction(helpAction);
    trayIconMenu->addMenu(funMenu);
    trayIconMenu->addSeparator();
    trayIconMenu->addAction(quitAction);



    this->setContextMenu(trayIconMenu);
    connect(showAction, SIGNAL(triggered()), this, SLOT(showParentWidget()));
    connect(helpAction, SIGNAL(triggered()), this, SLOT(slotHelpAction()));
    connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
}

void SystemTray::createTopWidget()
{
    topWidget = new QWidget();
    topWidget->setStyleSheet("QWidget{background:#2FC77B;color:#000000}QPushButton:hover{color:#FFFFFF}QPushButton:disabled{color:#666666;border-style:flat;}");
    topWidgetAction = new QWidgetAction(trayIconMenu);
    QLabel *titleLabel = new QLabel();
    titleLabel->setText(tr("系统托盘显示"));
    showButton = new QPushButton();
    showButton->setText(tr("显示"));
    showButton->setFocusPolicy(Qt::NoFocus);
    hideButton = new QPushButton();
    hideButton->setText(tr("隐藏"));
    hideButton->setFocusPolicy(Qt::NoFocus);
    showButton->setCursor(Qt::PointingHandCursor);
    hideButton->setCursor(Qt::PointingHandCursor);
    QHBoxLayout *hLayout = new QHBoxLayout();
    hLayout->addWidget(showButton);
    hLayout->addStretch();
    hLayout->addWidget(hideButton);
    hLayout->setSpacing(10);
    hLayout->setContentsMargins(0, 0, 0, 0);

    QVBoxLayout *vLayout = new QVBoxLayout();
    vLayout->addWidget(titleLabel);
    vLayout->addLayout(hLayout);
    vLayout->setSpacing(10);
    vLayout->setContentsMargins(10, 5, 10, 5);
    topWidget->setLayout(vLayout);
    topWidgetAction->setDefaultWidget(topWidget);
    connect(showButton, SIGNAL(clicked()), this, SLOT(slotClicked()));
    connect(hideButton, SIGNAL(clicked()), this, SLOT(slotClicked()));
}

void SystemTray::slotActivated(QSystemTrayIcon::ActivationReason reason)
{
    if (parentWidget) {
        switch (reason) {
            case QSystemTrayIcon::Trigger:
            case QSystemTrayIcon::DoubleClick: {
                if (parentWidget->isHidden() || parentWidget->windowState() == Qt::WindowMinimized) {
                    //showNormal(),showMinimized(),showMaxmized(),showFullScreen()
                    parentWidget->showNormal();
                    parentWidget->raise();
                    parentWidget->activateWindow();
                }
                else {
                    parentWidget->hide();
                    startHideTips();
                }
                break;
            }
            case QSystemTrayIcon::MiddleClick: {
                if (!middleText.isEmpty()) {
                    this->showMessage(tr("提示信息:"), middleText, QSystemTrayIcon::Information, 3000);
                }
                break;
            }
            case QSystemTrayIcon::Context: {
                if (parentWidget->isHidden() || parentWidget->windowState() == Qt::WindowMinimized) {
                    showAction->setText(tr("显示"));
                    showButton->setEnabled(true);
                    hideButton->setEnabled(false);
                }
                else {
                    showAction->setText(tr("隐藏"));
                    showButton->setEnabled(false);
                    hideButton->setEnabled(true);
                }
                break;
            }
            default:
                break;
        }
    }
}

void SystemTray::showParentWidget()
{
    if (showAction->text() == tr("显示")) {
        parentWidget->showNormal();
        parentWidget->raise();
        parentWidget->activateWindow();
    }
    else {
        parentWidget->hide();
        startHideTips();
    }
}

void SystemTray::slotHelpAction()
{
    const QUrl AuthorUrl("https://www.gotosearch.info/");
    //qDebug() << AuthorUrl.scheme();
    //qDebug() << AuthorUrl.port();
    QDesktopServices::openUrl(AuthorUrl);
}

void SystemTray::slotClicked()
{
    QPushButton *button = qobject_cast<QPushButton *>(sender());
    if (button == showButton) {
        parentWidget->showNormal();
        parentWidget->raise();
        parentWidget->activateWindow();
    }
    else {
        parentWidget->hide();
        startHideTips();
    }
}
 

(3)widget.h

#ifndef WIDGET_H
#define WIDGET_H
#include <QtGui>
#include "systemtray.h"

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = 0);
    ~Widget();

protected:
    void closeEvent(QCloseEvent *event);

private:
    SystemTray *systemTray;
};

#endif // WIDGET_H

(4)widget.cpp

#include "widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent, Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint)
{
    setWindowTitle(tr("系统托盘"));
    resize(400, 400);
    move((QApplication::desktop()->width() - width())/2,  (QApplication::desktop()->height() - height())/2);

    systemTray = new SystemTray(this);
    systemTray->setMiddleClickText(tr("系统托盘"));
    systemTray->setToolTips(tr("应用程序系统托盘"));
    systemTray->setHideText(tr("应用程序隐藏在系统托盘"));
    systemTray->show();
}

Widget::~Widget()
{

}

void Widget::closeEvent(QCloseEvent *event)
{
    if (systemTray->isVisible()) {
        systemTray->startHideTips();
        hide();
        event->ignore();
    }
}

(5)main.cpp

 

#include "widget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QTextCodec *codec = QTextCodec::codecForName("utf8");
    QTextCodec::setCodecForLocale(codec);
    QTextCodec::setCodecForCStrings(codec);
    QTextCodec::setCodecForTr(codec);
    if (!QSystemTrayIcon::isSystemTrayAvailable()) {
        QMessageBox::critical(NULL, QObject::tr("系统托盘"), QObject::tr("不支持系统托盘"));
        return 1;
    }
    Widget w;
    w.show();

    return a.exec();
}

 

2、运行效果图

 

四、总结

(1)注:系统托盘在centos下无法显示QAction的图标,并且提示message出现后鼠标滑过message在规定时间内不会消失。
(2)SystemTray是一个对QSystemTrayIcon的封装,可以直接拿到其他地方使用,但注意父类对象的传递。
(3)源码已经打包上传到csdn上(源码中有些问题在SystemTray::createActions()函数中,可对照文章修改),可登录下载(http://download.csdn.net/detail/taiyang1987912/8915693)。
(4)若有建议,请留言,在此先感谢! 

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
Qt是一个跨平台的C++图形用户界面应用程序开发框架。定制个性化系统托盘菜单需要使用Qt的相关类和方法来实现。 首先,需要创建一个QSystemTrayIcon对象,用于在系统托盘中显示图标和相关菜单。可以通过设置图标、提示信息等属性来定制托盘图标的外观。例如,可以使用setIcon()函数设置托盘图标,setToolTip()函数设置提示信息。 其次,为了实现托盘菜单,需要使用QMenu和QAction类。可以使用addAction()函数向菜单中添加动作(QAction),例如打开某个功能窗口、显示关于界面或退出程序。可以使用addSeparator()函数在菜单中插入分隔符。可以使用setEnabled()函数设置动作的启用状态。 此外,还可以使用addMenu()函数在菜单中添加子菜单。子菜单可以通过添加动作的方式来进一步定制菜单内容。例如,可以创建一个子菜单,用于显示不同的主题选择。 当用户点击菜单项时,可以连接对应的槽函数来执行相应的操作。例如,可以使用connect()函数将菜单项的triggered()信号与对应的槽函数连接起来。 最后,调用show()函数显示托盘菜单,然后通过exec()函数进入主事件循环,等待用户操作。 总之,通过使用Qt的相关类和方法,可以方便地定制个性化系统托盘菜单。仿照360安全卫士的托盘菜单,只需要根据具体需求创建对应的菜单项和子菜单即可。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乌托邦2号

博文不易,支持的请给予小小打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值