QT系统托盘应用程序

时间:2024-01-15 12:08:14

在QT中QSystemTrayIcon类提供了创建系统托盘程序的功能。

QSystemTrayIcon类为系统托盘中的应用程序提供图标。
现代操作系统通常会在桌面上提供一个称为系统托盘(system tray)或通知(notification)区域的特殊区域,其中长时间运行的应用程序可以显示图标和短消息。

QT系统托盘应用程序

QSystemTrayIcon类可以在以下平台上使用:

  • 所有受支持的Windows版本。
  • X11的所有窗口管理器和独立托盘实现,实现了XEmbed系统托盘规范。
  • 所有实现D-Bus的X11桌面环境规范,包括最新版本的KDE和Unity。
  • 所有受支持的macOS版本。

要检查用户桌面上是否存在系统托盘,请调用QSystemTrayIcon :: isSystemTrayAvailable()静态函数。

要添加系统托盘条目,请创建QSystemTrayIcon对象,调用setContextMenu()以提供图标的上下文菜单,并调用show()以使其在系统托盘中可见。可以使用showMessage()随时显示状态通知消息(“气球消息”)。

如果在构建系统托盘图标时系统托盘不可用,但稍后可用,则QSystemTrayIcon将自动为系统托盘中的应用程序添加条目(如果图标可见)。

当用户激活图标时,会发出activate()信号。

仅在X11上,当请求工具提示时,QSystemTrayIcon接收QEvent ::ToolTip类型的QHelpEvent。此外,QSystemTrayIcon接收QEvent :: Wheel类型的wheel事件。任何其他平台都不支持这些。

QT自带一个例子systray,可学习一下!

QT系统托盘应用程序

该程序是一个基于QDialog的应用程序,只有一个继承于QDialog的Window类。

主要代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
 
int main(int argc, char *argv[])
{
    // Initializes the resources specified by the .qrc file with the specified base name. Normally, when resources are built as part of the application, the resources are loaded automatically at startup. 
    // The Q_INIT_RESOURCE() macro is necessary on some platforms for resources stored in a static library.
    Q_INIT_RESOURCE(systray);
    QApplication app(argc, argv);
    // Returns true if the system tray is available; otherwise returns false.
    if (!QSystemTrayIcon::isSystemTrayAvailable())
    {
        QMessageBox::critical(, QObject::tr("Systray"),
                              QObject::tr("I couldn't detect any system tray  on this system."));
        ;
    }
    QApplication::setQuitOnLastWindowClosed(false);

Window window;
    window.show();
    return app.exec();
}

Window::Window()
{
    // Tray Icon Group Box(采用HBox布局)
    createIconGroupBox();
    // Ballon Message Group Box(采用Grid布局)
    createMessageGroupBox();
    iconLabel->setMinimumWidth(durationLabel->sizeHint().width());
    // Tray right button menu
    createActions();
    // Create Tray Icon
    createTrayIcon();
    // 信号与槽的连接
    connect(showMessageButton, &QAbstractButton::clicked,
            this, &Window::showMessage);
    connect(showIconCheckBox, &QAbstractButton::toggled,
            trayIcon, &QSystemTrayIcon::setVisible);
    connect(iconComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
            this, &Window::setIcon);
    // Tray 信号槽
    connect(trayIcon, &QSystemTrayIcon::messageClicked,
            this, &Window::messageClicked);
    connect(trayIcon, &QSystemTrayIcon::activated,
            this, &Window::iconActivated);

QVBoxLayout *mainLayout = new QVBoxLayout;
    mainLayout->addWidget(iconGroupBox);
    mainLayout->addWidget(messageGroupBox);
    setLayout(mainLayout);

iconComboBox->setCurrentIndex();
    trayIcon->show();

setWindowTitle(tr("Systray"));
    resize();
}

void Window::createTrayIcon()
{
    trayIconMenu = new QMenu(this);
    trayIconMenu->addAction(minimizeAction);
    trayIconMenu->addAction(maximizeAction);
    trayIconMenu->addAction(restoreAction);
    trayIconMenu->addSeparator();
    trayIconMenu->addAction(quitAction);

trayIcon = new QSystemTrayIcon(this);
    trayIcon->setContextMenu(trayIconMenu);
}

// 重写closeEvent实现关闭时隐藏到托盘
void Window::closeEvent(QCloseEvent *event)
{
#ifdef Q_OS_OSX
    if (!event->spontaneous() || !isVisible())
    {
        return;
    }
#endif
    if (trayIcon->isVisible())
    {
        QMessageBox::information(this, tr("Systray"),
                                 tr("The program will keep running in the "
                                    "system tray. To terminate the program, "
                                    "choose <b>Quit</b> in the context menu "
                                    "of the system tray entry."));
        hide();
        event->ignore();
    }
}

// 重写setVisible实现右键菜单的动态变化
void Window::setVisible(bool visible)
{
    minimizeAction->setEnabled(visible);
    maximizeAction->setEnabled(!isMaximized());
    restoreAction->setEnabled(isMaximized() || !visible);
    QDialog::setVisible(visible);
}

// 单击或双击托盘图标动态改变图标,点击滚轮显示气泡信息
void Window::iconActivated(QSystemTrayIcon::ActivationReason reason)
{
    switch (reason)
    {
    case QSystemTrayIcon::Trigger:
    case QSystemTrayIcon::DoubleClick:
        iconComboBox->setCurrentIndex((iconComboBox->currentIndex() + ) %
                                      iconComboBox->count());
        break;
    case QSystemTrayIcon::MiddleClick:
        showMessage();
        break;
    default:
        break;
    }
}

void Window::showMessage()
{
    showIconCheckBox->setChecked(true);
    QSystemTrayIcon::MessageIcon msgIcon = QSystemTrayIcon::MessageIcon(typeComboBox->itemData(typeComboBox->currentIndex()).toInt());
    if (msgIcon == QSystemTrayIcon::NoIcon)
    {
        QIcon icon(iconComboBox->itemIcon(iconComboBox->currentIndex()));
        trayIcon->showMessage(titleEdit->text(), bodyEdit->toPlainText(), icon, durationSpinBox->value() * );
    }
    else
    {
        trayIcon->showMessage(titleEdit->text(), bodyEdit->toPlainText(), msgIcon, durationSpinBox->value() * );
    }
}