Qt5.6文档翻译:系统托盘图标示例,System Tray Icon Example
现代操作系统通常都会在桌面上提供一个特定区域,名为 系统托盘 或 通知区域 ,长时间运行的应用程序可在该区域显示图标及简短的消息。
这个示例中,包含了一个单独的类, Window , 它实现的是应用程序的主窗口 ( 即,针对系统托盘图标的一个编辑器 ) 和相关联的图标。
通过这个编辑器,用户可以选择要显示的图标,还可以设置气泡消息的类型和持续时间。用户还可以编辑所显示消息的标题和主体内容。最后,这个编辑器还提供了一个复选框,可用来控制,是否要在系统托盘中显示图标。
Window 类继承了 QWidget 类:
class Window : public QDialog
{
Q_OBJECT
public:
Window();
void setVisible(bool visible) Q_DECL_OVERRIDE;
protected:
void closeEvent( QCloseEvent *event) Q_DECL_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;
};
我们实现了若干个私有信号槽,以对用户的操作做出响应。另外的那些私有函数,只是一些便利函数,用来简化构造函数的代码。
托盘图标 ,是 QSystemTrayIcon 类的一个实例。 要想检查用户当前使用的桌面是否带有系统托盘的话,则调用静态的 QSystemTrayIcon::isSystemTrayAvailable ()函数。针对 该图标,我们提供了一个相关联的菜单,其中包含了经典的最小化( minimize )、最大化( maximize )、恢复( restore )和退出( quit )命令。 我们覆盖了 QWidget::setVisible ()函数, 这样就可以在编辑器窗口的外观发生变化时更新托盘图标的菜单,例如, 将主窗口最大化或最小化就属于外观变化。
最后 ,我们覆盖了 QWidget 的 closeEvent() 函数, 这样, 就可以( 在用户关闭编辑器窗口时 )告知用户, 该应用程序仍会在系统托盘中继续运行,直到用户点击了图标的上下文菜单中的退出( Quit )命令为止。
在构造编辑器部件时,我们首先创建编辑器中的各个元素,之后再创建实际的系统托盘图标:
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);
typedef void ( QComboBox ::* QComboIntSignal )( int );
connect(iconComboBox, static_cast< QComboIntSignal >(& 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);
}
我们会确保该应用程序会对用户的操作做出响应,具体做法就是, 将该编辑器中大部分输入部件(包括系统托盘图标)都连接到该应用程序的私有信号槽。但是,注意 一个例外,控制可见性(visibility)的那个复选框; 它的 toggled() 信号被连接到托盘图标( icon )的 setVisible() 函数。
void Window::setIcon( int index)
{
QIcon icon = iconComboBox->itemIcon(index);
trayIcon->setIcon(icon);
setWindowIcon(icon);
trayIcon->setToolTip(iconComboBox->itemText(index));
}
setIcon() 信号 槽, 会在图标选择组合框的当前下标发生变化时被触发,换句话说, 当用户在编辑器窗口中选择不同的图标时触发。注意 , 当用户用鼠标左键点击托盘图标,导致触发 activated() 信号时,也会调用这个函数。 我们稍后会再说明这个信号的相关细节。
QSystemTrayIcon::setIcon ()函数 ,会设置它的 icon 属性, 该属性就是实际显示的系统托盘图标。 在 X11 中,托盘图标的最佳尺寸是22x22。图标 会在必要的情况下被缩放到适当的尺寸。
注意,在X11中,由于系统托盘标准中的一个限制,在图标的透明区域发生的鼠标点击事件,会被传递到系统托盘本身。如果妳认为这种行为不可接受的话,那么,我们建议使用一个不带透明区域的图标。
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:
;
}
}
当用户激活系统托盘图标时,它就会发射 activated() 信号,并且 将触发原因作为参数传递。 QSystemTrayIcon 提供 了 ActivationReason 枚举 ,用来说明图标被激活的种种可能原因。
在构造函数中,我们将图标的 activated() 信号连接到了自定义的 iconActivated() 信号槽上:如果用户使用鼠标左键 来点击托盘图标,那么,这个函数会改变要显示的图标,具体做法就是,增加图标选择组合 框的当前下标值, 这样就会触发之前提到的 setIcon() 信号槽。如果用户使用鼠标 中键来激活托盘图标,那么,会调用自定义的 showMessage() 信号槽:
void Window::showMessage()
{
showIconCheckBox->setChecked(true);
QSystemTrayIcon ::MessageIcon icon = QSystemTrayIcon ::MessageIcon(
typeComboBox->itemData(typeComboBox->currentIndex()).toInt());
trayIcon->showMessage(titleEdit->text(), bodyEdit->toPlainText(), icon,
durationSpinBox->value() * 1000);
}
当 showMessage() 信号槽被触发时,我们首先根据当前选中 的消息类型来获取对应的消息图标。 QSystemTrayIcon::MessageIcon 枚举 ,列举的是,在显示气泡消息时, 要跟随着显示的图标 。然后 ,我们调用 QSystemTrayIcon 的 showMessage() 函数, 以显示这条消息,并且会指明标题、正文、图标和以毫秒为单位的持续时间。
QSystemTrayIcon 还有一个对应的 messageClicked() 信号, 当用户点击之前通过 showMessage() 显示的消息时就会被发射。
void Window::messageClicked()
{
QMessageBox ::information(0, tr("Systray"),
tr("Sorry, I already gave what help I could.\n"
"Maybe you should try asking a human?"));
}
在构造函数中,我们将 messageClicked() 信号连接到了自定义的 messageClicked() 信号槽上, 它所做的就是使用 QMessageBox 类来显示一条消息。
QMessageBox 提供 了一个模态对话框,其中 包含了 : 一条简短的消息;一个图标;以及,根据系统当前风格而排 列的多个按钮。 它支持四种重要程度级别:问题( "Question" );信息( "Information" );警告 ( "Warning" );和致命( "Critical" )。 在Qt 中,弹出消息对话框的最简单方法就是,调用其中 一个相关的静态函数,例如 QMessageBox::information ()。
之前已经提到 过,我们覆盖了 QWidget 的多个虚函数:
void Window::setVisible(bool visible)
{
minimizeAction->setEnabled(visible);
maximizeAction->setEnabled(!isMaximized());
restoreAction->setEnabled(isMaximized() || !visible);
QDialog ::setVisible(visible);
}
在覆盖的 QWidget::setVisible ()函数中, 我们会在编辑器窗口的外观发生变化时更新托盘图标的菜单,然后再调用基类的实现函数。例如, 对主窗口进行最大化或最小化,就属于外观变化。
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();
}
}
我们覆盖了 QWidget::closeEvent ()这个事件处理函数, 以接收到部件关闭的事件 。这样,就可以在用户关闭编辑器窗口时显示上面代码中的那条消息。
除了上面说明的这些函数之外, 我们还定义了若干 个便利函数, 以简化构造函数: createIconGroupBox() 、 createMessageGroupBox() 、 createActions() 和 createTrayIcon() 。阅读 window.cpp 文件 以了解细节。
文件:
图片:
未知美人
Your opinionsHxLauncher: Launch Android applications by voice commands