StupidBeauty
Read times:3754Posted at: - no title specified

Qt5.6文档翻译:系统托盘图标示例,System Tray Icon Example

现代操作系统通常都会在桌面上提供一个特定区域,名为 系统托盘 通知区域 ,长时间运行的应用程序可在该区域显示图标及简短的消息。

这个示例中,包含了一个单独的类, Window 它实现的是应用程序的主窗口 ( 即,针对系统托盘图标的一个编辑器 ) 和相关联的图标。

通过这个编辑器,用户可以选择要显示的图标,还可以设置气泡消息的类型和持续时间。用户还可以编辑所显示消息的标题和主体内容。最后,这个编辑器还提供了一个复选框,可用来控制,是否要在系统托盘中显示图标。

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::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 opinions
Your name:Email:Website url:Opinion content:
- no title specified

HxLauncher: Launch Android applications by voice commands