简述
QSystemTrayIcon类为应用程序在系统托盘中提供一个图标。
现代操作系统通常在桌面上提供一个特殊的区域,称为系统托盘或通知区域,长时间运行的应用程序可以显示图标和短消息。
内容
详细描述
要检查系统托盘是否存在在用户的桌面上,调用QSystemTrayIcon::isSystemTrayAvailable()静态函数。
要添加系统托盘项,首先,需要创建一个QSystemTrayIcon对象,并调用setContextMenu()为图标提供上下文菜单,然后,调用show()使其在系统托盘中可见。状态通知消息(“气球消息”)可以在任何时候使用showMessage()来进行显示。
当用户激活托盘图标时,activated()信号会被发射。
只有在X11上时,当发出一个tooltip请求时,QSystemTrayIcon会接收一个QEvent::ToolTip类型的QHelpEvent事件。此外,QSystemTrayIcon会接收QEvent::Wheel类型的滚轮事件。这些都是不支持任何其它平台。
共有类型
枚举
QSystemTrayIcon::ActivationReason
:
此枚举描述了系统托盘被激活的原因。
| 常量 | 值 | 描述 | | :—-: | :—-: | :—-: | | QSystemTrayIcon::Unknown | 0 | 未知原因 | | QSystemTrayIcon::Context | 1 | 系统托盘的上下文菜单请求 | | QSystemTrayIcon::DoubleClick | 2 | 双击系统托盘 | | QSystemTrayIcon::Trigger | 3 | 单击系统托盘 | | QSystemTrayIcon::MiddleClick | 4 | 鼠标中键点击系统托盘 |枚举
QSystemTrayIcon::MessageIcon
:
此枚举描述了显示气球消息时所显示的图标。 | 常量 | 值 | 描述 | | :—-: | :—-: | :—-: | | QSystemTrayIcon::NoIcon | 0 | 无图标显示 | | QSystemTrayIcon::Information | 1 | 一个信息图标显示 | | QSystemTrayIcon::Warning | 2 | 一个标准的警告图标显示 | | QSystemTrayIcon::Critical | 3 | 一个严重的警告图标显示 |
共有函数
- QMenu * contextMenu() const
返回系统托盘的当前上下文菜单。 - void setContextMenu(QMenu menu)
设置指定菜单为系统托盘的上下文菜单。
当用户通过点击鼠标请求系统托盘的上下文菜单时,菜单会弹出。
在OS X中,一般转换为一个NSMenu,所以aboutToHide()信号不会发出。
*注意:系统托盘菜单并不对菜单有所有权,必须确保在恰当的时候删除菜单,例如:创造一个具有合适父对象的菜单。 - QRect QSystemTrayIcon::geometry() const
返回系统托盘图标在屏幕上的几何坐标。 - QIcon icon() const
- void setIcon(const QIcon & icon)
icon : QIcon
这个属性保存了系统托盘的图标。
在Windows中,系统任务栏图标的大小是16×16;X11中,首选大小为22x22。必要时该图标将被调整到合适大小。 - void setToolTip(const QString & tip)
- QString toolTip() const
toolTip : QString
这个属性保存了系统托盘的提示信息。
在一些系统中,tooltip的长度是有限的,在必要时tooltip将被截断。 bool isVisible() const
返回系统托盘是否可见。
公有槽函数
void hide()
隐藏系统托盘。- void setVisible(bool visible)
设置系统托盘是否可见。
设置为true或调用show()使系统托盘图标可见;设置为false或调用hide()隐藏它。 - void show()
显示系统托盘。 - void showMessage(const QString & title, const QString & message, QSystemTrayIcon::MessageIcon icon = QSystemTrayIcon::Information, int millisecondsTimeoutHint = 10000)
显示一个气球消息,使用所给出的标题、消息、图标和指定的时间,标题和消息必须是纯文本字符串。
消息可以被用户点击,当用户点击时发出messageClicked()信号 。
信号
- void activated(QSystemTrayIcon::ActivationReason reason)
当用户激活系统托盘图标,这个信号被发射。reason指定激活的原因, QSystemTrayIcon::ActivationReason列举了各种原因。 void messageClicked()
当使用showMessage()显示的消息被用户点击时,此信号被发射。
目前,这个信号不会在OS X中发射。
静态共有函数
bool isSystemTrayAvailable() [static]
如果系统托盘可用,返回true;否则,返回false。
如果系统盘是当前不可用,但以后变为可用,若QSystemTrayIcon可见,它就会自动在系统托盘中添加条目。- bool supportsMessages() [static]
如果系统托盘支持气球消息,则返回true;否则,返回false。
例子
头文件
#ifndef WINDOW_H
#define WINDOW_H
#include <QSystemTrayIcon>
#ifndef QT_NO_SYSTEMTRAYICON
#include <QDialog>
QT_BEGIN_NAMESPACE
class QAction;
class QCheckBox;
class QComboBox;
class QGroupBox;
class QLabel;
class QLineEdit;
class QMenu;
class QPushButton;
class QSpinBox;
class QTextEdit;
QT_END_NAMESPACE
class Window : public QDialog {
Q_OBJECT
public:
Window();
void setVisible(bool visible) override;
protected:
void closeEvent(QCloseEvent* event) override;
private slots:
void setIcon(int index);
void iconActivated(QSystemTrayIcon::ActivationReason reason);
void showMessage();
void messageClicked();
private:
void createIconGroupBox();
void createMessageGroupBox();
void createActions();
void createTrayIcon();
QGroupBox* iconGroupBox;
QLabel* iconLabel;
QComboBox* iconComboBox;
QCheckBox* showIconCheckBox;
QGroupBox* messageGroupBox;
QLabel* typeLabel;
QLabel* durationLabel;
QLabel* durationWarningLabel;
QLabel* titleLabel;
QLabel* bodyLabel;
QComboBox* typeComboBox;
QSpinBox* durationSpinBox;
QLineEdit* titleEdit;
QTextEdit* bodyEdit;
QPushButton* showMessageButton;
QAction* minimizeAction;
QAction* maximizeAction;
QAction* restoreAction;
QAction* quitAction;
QSystemTrayIcon* trayIcon;
QMenu* trayIconMenu;
};
//! [0]
#endif // QT_NO_SYSTEMTRAYICON
#endif
实现
#include "window.h"
#ifndef QT_NO_SYSTEMTRAYICON
#include <QAction>
#include <QCheckBox>
#include <QCloseEvent>
#include <QComboBox>
#include <QCoreApplication>
#include <QGroupBox>
#include <QLabel>
#include <QLineEdit>
#include <QMenu>
#include <QMessageBox>
#include <QPushButton>
#include <QSpinBox>
#include <QTextEdit>
#include <QVBoxLayout>
Window::Window()
{
createIconGroupBox();
createMessageGroupBox();
iconLabel->setMinimumWidth(durationLabel->sizeHint().width());
createActions();
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);
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(1);
trayIcon->show();
setWindowTitle(tr("Systray"));
resize(400, 300);
}
// 设置托盘菜单显隐状态
void Window::setVisible(bool visible)
{
minimizeAction->setEnabled(visible);
maximizeAction->setEnabled(!isMaximized());
restoreAction->setEnabled(isMaximized() || !visible);
QDialog::setVisible(visible);
}
// 关闭事件重写
void Window::closeEvent(QCloseEvent* event)
{
#ifdef Q_OS_MACOS
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();
}
}
// 设置托盘图标
void Window::setIcon(int index)
{
QIcon icon = iconComboBox->itemIcon(index);
trayIcon->setIcon(icon);
setWindowIcon(icon);
trayIcon->setToolTip(iconComboBox->itemText(index));
}
// 托盘响应鼠标事件
void Window::iconActivated(QSystemTrayIcon::ActivationReason reason)
{
switch (reason) {
case QSystemTrayIcon::Trigger:
case QSystemTrayIcon::DoubleClick:
iconComboBox->setCurrentIndex((iconComboBox->currentIndex() + 1) % iconComboBox->count());
break;
case QSystemTrayIcon::MiddleClick:
showMessage();
break;
default:;
}
}
// 设置系统提示框
void Window::showMessage()
{
showIconCheckBox->setChecked(true);
int selectedIcon = typeComboBox->itemData(typeComboBox->currentIndex()).toInt();
QSystemTrayIcon::MessageIcon msgIcon = QSystemTrayIcon::MessageIcon(selectedIcon);
if (selectedIcon == -1) { // custom icon
QIcon icon(iconComboBox->itemIcon(iconComboBox->currentIndex()));
trayIcon->showMessage(titleEdit->text(), bodyEdit->toPlainText(), icon, durationSpinBox->value() * 1000);
} else {
trayIcon->showMessage(titleEdit->text(), bodyEdit->toPlainText(), msgIcon, durationSpinBox->value() * 1000);
}
}
// 弹出提示(系统提示框点击后的弹窗)
void Window::messageClicked()
{
QMessageBox::information(nullptr, tr("Systray"),
tr("Sorry, I already gave what help I could.\nMaybe you should try asking a human?"));
}
// 创建布局
void Window::createIconGroupBox()
{
iconGroupBox = new QGroupBox(tr("Tray Icon"));
iconLabel = new QLabel("Icon:");
iconComboBox = new QComboBox;
iconComboBox->addItem(QIcon(":/images/bad.png"), tr("Bad"));
iconComboBox->addItem(QIcon(":/images/heart.png"), tr("Heart"));
iconComboBox->addItem(QIcon(":/images/trash.png"), tr("Trash"));
showIconCheckBox = new QCheckBox(tr("Show icon"));
showIconCheckBox->setChecked(true);
QHBoxLayout* iconLayout = new QHBoxLayout;
iconLayout->addWidget(iconLabel);
iconLayout->addWidget(iconComboBox);
iconLayout->addStretch();
iconLayout->addWidget(showIconCheckBox);
iconGroupBox->setLayout(iconLayout);
}
// 创建布局
void Window::createMessageGroupBox()
{
messageGroupBox = new QGroupBox(tr("Balloon Message"));
typeLabel = new QLabel(tr("Type:"));
typeComboBox = new QComboBox;
typeComboBox->addItem(tr("None"), QSystemTrayIcon::NoIcon);
typeComboBox->addItem(style()->standardIcon(QStyle::SP_MessageBoxInformation), tr("Information"), QSystemTrayIcon::Information);
typeComboBox->addItem(style()->standardIcon(QStyle::SP_MessageBoxWarning), tr("Warning"), QSystemTrayIcon::Warning);
typeComboBox->addItem(style()->standardIcon(QStyle::SP_MessageBoxCritical), tr("Critical"), QSystemTrayIcon::Critical);
typeComboBox->addItem(QIcon(), tr("Custom icon"), -1);
typeComboBox->setCurrentIndex(1);
durationLabel = new QLabel(tr("Duration:"));
durationSpinBox = new QSpinBox;
durationSpinBox->setRange(5, 60);
durationSpinBox->setSuffix(" s");
durationSpinBox->setValue(15);
durationWarningLabel = new QLabel(tr("(some systems might ignore this "
"hint)"));
durationWarningLabel->setIndent(10);
titleLabel = new QLabel(tr("Title:"));
titleEdit = new QLineEdit(tr("Cannot connect to network"));
bodyLabel = new QLabel(tr("Body:"));
bodyEdit = new QTextEdit;
bodyEdit->setPlainText(tr("Don't believe me. Honestly, I don't have a clue.\nClick this balloon for details."));
showMessageButton = new QPushButton(tr("Show Message"));
showMessageButton->setDefault(true);
QGridLayout* messageLayout = new QGridLayout;
messageLayout->addWidget(typeLabel, 0, 0);
messageLayout->addWidget(typeComboBox, 0, 1, 1, 2);
messageLayout->addWidget(durationLabel, 1, 0);
messageLayout->addWidget(durationSpinBox, 1, 1);
messageLayout->addWidget(durationWarningLabel, 1, 2, 1, 3);
messageLayout->addWidget(titleLabel, 2, 0);
messageLayout->addWidget(titleEdit, 2, 1, 1, 4);
messageLayout->addWidget(bodyLabel, 3, 0);
messageLayout->addWidget(bodyEdit, 3, 1, 2, 4);
messageLayout->addWidget(showMessageButton, 5, 4);
messageLayout->setColumnStretch(3, 1);
messageLayout->setRowStretch(4, 1);
messageGroupBox->setLayout(messageLayout);
}
// 托盘菜单绑定事件
void Window::createActions()
{
minimizeAction = new QAction(tr("Mi&nimize"), this);
connect(minimizeAction, &QAction::triggered, this, &QWidget::hide);
maximizeAction = new QAction(tr("Ma&ximize"), this);
connect(maximizeAction, &QAction::triggered, this, &QWidget::showMaximized);
restoreAction = new QAction(tr("&Restore"), this);
connect(restoreAction, &QAction::triggered, this, &QWidget::showNormal);
quitAction = new QAction(tr("&Quit"), this);
connect(quitAction, &QAction::triggered, qApp, &QCoreApplication::quit);
}
// 添加托盘菜单选项
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);
}
#endif
main函数
#include <QApplication>
#ifndef QT_NO_SYSTEMTRAYICON
#include "window.h"
#include <QMessageBox>
int main(int argc, char* argv[])
{
Q_INIT_RESOURCE(systray);
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
QApplication app(argc, argv);
if (!QSystemTrayIcon::isSystemTrayAvailable()) {
QMessageBox::critical(nullptr, QObject::tr("Systray"),
QObject::tr("I couldn't detect any system tray "
"on this system."));
return 1;
}
QApplication::setQuitOnLastWindowClosed(false);
Window window;
window.show();
return app.exec();
}
#else
#include <QDebug>
#include <QLabel>
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
QString text("QSystemTrayIcon is not supported on this platform");
QLabel* label = new QLabel(text);
label->setWordWrap(true);
label->show();
qDebug() << text;
app.exec();
}
#endif
图片
bad.png
heart.png
trash.png
https://waleon.blog.csdn.net/article/details/52014110 Qt自带例子 Qt5.15\5.15.2\Src\qtbase\examples\widgets\desktop\systray