您的位置:首页 > 编程语言 > Qt开发

Qt添加系统托盘

2016-03-03 11:59 441 查看
此方法是在主窗口为QMainWindow的窗口中实现的方法,至于其它顶层的窗口没有经过测试。

实现的功能有创建一个托盘图标,在点击主窗口的关闭按钮后会弹出一个对话框,询问用户是最小化到系统托盘还是退出程序。如果用户选择最小化到系统托盘后并点击确定按钮,程序会最小化到系统托盘中。如果用户选择退出程序,程序会退出。如果用户点击的是对话框的取消按钮,不管用户之前是选择的最小化到系统托盘还是退出程序,点击取消按钮后除了关闭对话框外不做任何处理。同时在系统托盘中单双击系统托盘中的图标后会重新显示主窗口,点击右键会弹出一个右键菜单,菜单中有隐藏、最大化、正常、退出程序等选项。

为程序添加系统托盘需要用到QSystemTrayIcon类。可通过setIcon()函数设置按钮图标;通过setContextMenu()函数添加图标的右键菜单栏;setToolTip()函数可设置图标的提示信息(就是鼠标进入按钮区后出现在图标右上方的提示信息);调用show()函数可显示图标,注意,如果不调用show()函数的话是看不到图标的。
不过要想实现点击窗口关闭按钮后最小化到系统托盘中的话还需要重新实现MainWindow窗口的closeEvent(QCloseEvent *event)事件,并在main.cpp中添加如下一行代码:此处等待替换(此行代码的作用是在关闭最后一个可视窗口后不退出程序,这么做的代价就是以后要退出程序需要使用qApp.quit()函数,而并非MainWindow窗口的close()函数)。

下面的addSystemTray ()函数创建了一个托盘图标,并对托盘图标中的图片,右键菜单,提示信息进行了设置:

/*添加系统托盘*/
void MainWindow::addSystemTray()
{
this->createTrayIconMenu ();
systemTrayIcon = new QSystemTrayIcon(this);
systemTrayIcon->setContextMenu(systemTrayMenu);
systemTrayIcon->setToolTip(SYSTEM_NAME);
QIcon systemIcon(":/Icon/systemIcon.png");
systemTrayIcon->setIcon(systemIcon);
systemTrayIcon->show();
connect(systemTrayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this,
SLOT(systemTrayIconActivated(QSystemTrayIcon::ActivationReason)));
}


addSystemTray()函数中调用的createTrayIconMenu ()函数创建了一个右键菜单,activated信号是在点击托盘图标时发送的信号(单击和双击都会发送此信号,需要通过此信号的参数QSystemTrayIcon::ActivationReason的值来判断是单击还是双击)。下面是判断单双击托盘图标的槽函数实现代码:

void MainWindow::systemTrayIconActivated(QSystemTrayIcon::ActivationReason reason)
{
if(reason == QSystemTrayIcon::Trigger)
showNormal ();   //系统托盘中的图标被单击
else if(reason == QSystemTrayIcon::DoubleClick)
showNormal ();   //系统托盘中的图标被双击
}


下面是为托盘图标添加右键菜单的代码:

/*添加系统托盘图标右键菜单*/
void MainWindow::createTrayIconMenu()
{
minimizeAction = new QAction(tr("Mi&nimize"), this);
connect(minimizeAction, SIGNAL(triggered()), this, SLOT(hide()));

maximizeAction = new QAction(tr("Ma&ximize"), this);
connect(maximizeAction, SIGNAL(triggered()), this, SLOT(showMaximized()));

restoreAction = new QAction(tr("打开主界面"), this);
connect(restoreAction, SIGNAL(triggered()), this, SLOT(showNormal()));

quitAction = new QAction(tr("退出程序"), this);
connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));

systemTrayMenu = new QMenu(this);
systemTrayMenu->addAction(minimizeAction);
systemTrayMenu->addAction(maximizeAction);
systemTrayMenu->addAction(restoreAction);
systemTrayMenu->addSeparator();
systemTrayMenu->addAction(quitAction);
}


其中QAction和QMenu就不介绍了,至于qApp,它是一个全局变量,就是在main.cpp文件中用QApplication类定义的变量,要用此全局变量需要包含QApplication类的.h文件。

以下是重新实现的MainWindow窗口的closeEvent(QCloseEvent*event)事件代码:

void MainWindow::closeEvent(QCloseEvent *event)
{
switch (showQuitPromptWindow(this)) {
case 1:
hide();
event->ignore();
break;
case 0:
qApp->quit();
break;
default:
event->ignore();
break;
}
}


showQuitPromptWindow(this)函数的声明是在一个自定义的对话框中,它是一个全局函数。在这个closeEvent事件函数中点击关闭按钮后会调用全局函数showQuitPromptWindow(this),然后获取此全局函数的返回值,如果返回1,则隐藏主窗口。如果返回0,则退出程序,返回其他值忽略此事件。下面是showQuitPromptWindow(this)函数的实现代码:

int showQuitPromptWindow(QWidget *parent) {
QuitPromptWindow quitPromptWindow(parent);
return quitPromptWindow.exec();
}


在此函数中,首先定义了一个对话框quitPromptWindow(自定义的),然后调用exec()函数并返回此对话框的返回值。

注意:quitPromptWindow对话框必须是模态的。如果是非模态的对话框,在打开对话框的同时主窗口也会直接退出,根本获取不到对话框的返回值。

创建一个模态对话框有两种方式(或更多,但我只知道两种)。第一种就是像全局函数showQuitPromptWindow中那样使用exec()函数而非show()函数来显示对话框;第二种方式就是在定义对话框时直接使用setModel函数设为模态的。使用这种方法设置对话框属性后不管使用exec()函数还是show()函数,创建的对话框都会是模态的。

以下是quitPromptWindow对话框的实现代码:

#include "QuitPromptWindow.h"

QuitPromptWindow::QuitPromptWindow(QWidget *parent) : QDialog(parent)
{
this->setWindowTitle(SYSTEM_NAME);
this->setFixedSize(400, 150);

mainLayout = new QVBoxLayout;
this->setLayout(mainLayout);

radioButtonLayou = new QVBoxLayout;
radioButtonLayou->setSpacing(1);
miniButton = new QRadioButton("最小化到系统托盘", this);
miniButton->setChecked(true);
quitButton = new QRadioButton("退出程序", this);
buttonGroup = new QButtonGroup(this);
buttonGroup->addButton(miniButton, 0);
buttonGroup->addButton(quitButton, 1);
radioButtonLayou->addWidget(miniButton);
radioButtonLayou->addWidget(quitButton);

pushButtonLayou = new QHBoxLayout;
determineButton = new QPushButton("确定");
cancelButton = new QPushButton("取消");
pushButtonLayou->addWidget(determineButton, 0, Qt::AlignLeft);
pushButtonLayou->addWidget(cancelButton, 0, Qt::AlignLeft);

mainLayout->addLayout(radioButtonLayou);
mainLayout->addLayout(pushButtonLayou);

connect(determineButton, SIGNAL(clicked()), this, SLOT(determineButtonClicked()));
connect(cancelButton, SIGNAL(clicked()), this, SLOT(cancelButtonClicked()));
}

void QuitPromptWindow::determineButtonClicked()
{
switch(buttonGroup->checkedId())
{
case 0:
done(1);
break;
case 1:
done(0);
break;
}
}

void QuitPromptWindow::cancelButtonClicked()
{
done(-1);
}

int showQuitPromptWindow(QWidget *parent) { QuitPromptWindow quitPromptWindow(parent); return quitPromptWindow.exec(); }


其中,全局函数showQuitPromptWindow(QWidget *parent)就是在此cpp文件中实现的,也是在此类的.h文件中声明的。

在这个类中有一个done()函数,此函数是用来返回一个值,并关闭对话框的。也就是说,调用了此函数后对话框会关闭,并将一个值返回给全局函数showQuitPromptWindow;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: