QT之系统托盘图标

理论摘自网友:https://blog.csdn.net/zhuyunfei/article/details/51433822

1.功能说明

对于GUI程序,如果想要实现当最小化时,程序从任务栏消失,在系统托盘显示一个图标,表示此程序,并能在托盘内通过双击或者菜单使程序界面恢复。

2.使用的类

主要使用的此类:QSystemTrayIcon。 
其中QSystemTrayIcon是主要操作系统托盘的操作类,通过此类,可以在托盘显示指定程序的图标,响应用户鼠标的单击,双击,或wheel操作(好像只对X11系统有用),显示指定消息,显示菜单等。 
此类中有两个枚举类型,分别如下: 
enum QSystemTrayIcon::ActivationReason 表述托盘上图标的触发缘由

常量 描述
QSystemTrayIcon::Unknown 0 未知原因
QSystemTrayIcon::Context 1 请求系统托盘的上下文菜单
QSystemTrayIcon::DoubleClick 2 鼠标双击
QSystemTrayIcon::Trigger 3 鼠标单击
QSystemTrayIcon::MiddleClick 4 鼠标中间按键

enum QSystemTrayIcon::MessageIcon 当显示气球消息时显示的图片

常量 描述
QSystemTrayIcon::NoIcon 0 不显示图标
QSystemTrayIcon::Information 1 显示信息图标
QSystemTrayIcon::Warning 2 显示告警图标
QSystemTrayIcon::Critical 3 显示致命图标

3.QSystemTrayIcon常用函数

void setIcon(const QIcon& icon) 
设置系统托盘的图标 
void setToolTip(const QString &tip) 
设置鼠标放到图标上的提示文字 
void setContextMenu(QMenu* menu); 
设置当点击图标弹出的菜单 
void show() 
显示系统托盘图标

4、实现步骤:

1)添加成员变量:

QSystemTrayIcon m_systray;

2)构造函数里面初始化:1、提示文字 2、设置图标 3、右键菜单 4、show显示

// 设置提示文字 
	m_systray.setToolTip(GBK::ToUnicode("JTV手动改名工具..."));
	// 设置托盘图标
	m_systray.setIcon(QIcon(":/JTVManualRename/Resources/Rename.ico"));
	// 设置托盘菜单
	QMenu* menu = new QMenu();
	menu->addAction(ui.actionExit);
	m_systray.setContextMenu(menu);
	// 显示托盘菜单
	m_systray.show();

3)为右键退出菜单添加一个槽函数:

// 托盘菜单命令的处理
	connect(ui.actionExit,SIGNAL(triggered()),this,SLOT(OnExit()));
/*
    托盘退出命令
*/
int CZZCMainFrame::OnExit()
{
	QApplication::exit(0);
	return 0;
}

4)点击图标时,显示主窗口:(关联托盘事件)

// 关联托盘事件
	connect(&m_systray,SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
		this,SLOT(OnSystemTrayClicked(QSystemTrayIcon::ActivationReason)));
/*
    单击/双击托盘图标,显示主程序
*/
int CZZCMainFrame::OnSystemTrayClicked(QSystemTrayIcon::ActivationReason reason)
{
	if(reason == QSystemTrayIcon::Trigger 
		|| reason == QSystemTrayIcon::DoubleClick)
	{
		// 显示主窗口
		this->showNormal();
		//this->showMaximized();
	}

	return 0;
}

5)点击最小化按钮时,加入系统托盘:(重写ChangeEvent事件)

/*
    点击最小化时图标到托盘
*/
void CZZCMainFrame::changeEvent(QEvent* event)
{
	if(event->type() == QEvent::WindowStateChange){  
		if(windowState() & Qt::WindowMinimized){  
			QTimer::singleShot(0, this, SLOT(hide())); 
			m_systray.show();  
		}  
		QWidget::changeEvent(event);  
	}
}

6)点击红X时,弹出选择对话框,最小化托盘或是退出主程序:(重写CloseEvent事件)

/*点击红X,最小到托盘*/
void CZZCMainFrame::closeEvent(QCloseEvent *event)
{
	//如果不设置父窗口会出现两个图标
	CloseInfoDlg dlg(this);

	if (dlg.exec() == QDialog::Accepted)
	{
		if (dlg.m_nCFlag == 1)
		{
			this->hide();
			event->ignore();
		} 
		else
		{
			event->accept();
		}
	}
	else
	{
		event->ignore();
	}
}

同时添加一个对话框类:

#ifndef CLOSEINFODLG_H
#define CLOSEINFODLG_H

#include <QDialog>
#include "ui_CloseInfoDlg.h"
#include <QButtonGroup>
#include <QDebug>

class CloseInfoDlg : public QDialog
{
	Q_OBJECT

public:
	CloseInfoDlg(QWidget *parent = 0);
	~CloseInfoDlg();

private:
	Ui::CloseInfoDlg ui;
	QButtonGroup *btnGroup;

public:
	int m_nCFlag;

private slots:
	void OnRadioClicked();
};

#endif // CLOSEINFODLG_H
#include "CloseInfoDlg.h"

CloseInfoDlg::CloseInfoDlg(QWidget *parent)
	: QDialog(parent)
{
	ui.setupUi(this);

	setWindowTitle(QString::fromLocal8Bit("关闭窗口"));

	m_nCFlag = 1;

	btnGroup = new QButtonGroup(this);
	btnGroup->addButton(ui.radiosystray,0);
	btnGroup->addButton(ui.radioexit,1);
	ui.radiosystray->setChecked(true);

	/*
	    多个radio共享一个槽函数
	*/
	connect(ui.radiosystray,SIGNAL(clicked()),this,SLOT(OnRadioClicked()));
	connect(ui.radioexit,SIGNAL(clicked()),this,SLOT(OnRadioClicked()));

	connect(ui.btnOk,SIGNAL(clicked()),this,SLOT(accept()));
	connect(ui.btnCancel,SIGNAL(clicked()),this,SLOT(reject()));
}

CloseInfoDlg::~CloseInfoDlg()
{

}

void CloseInfoDlg::OnRadioClicked()
{
	switch (btnGroup->checkedId())
	{
	case 0:
		m_nCFlag = 1;
		break;
	case 1:
		m_nCFlag = 2;
		break;
	default:
		break;
	}
}

猜你喜欢

转载自blog.csdn.net/u012372584/article/details/81298031