Qt之系统托盘你学清楚了吗?

系统托盘是什么

在这里插入图片描述
右键效果👇
在这里插入图片描述

可以理解成应用程序最小化保存在桌面右下角,比如这个是QQ的系统托盘我们可以通过单击来使QQ显示出来,也可以通过右键产生菜单来对QQ进行操作

系统托盘实现

我这里通过使用一个自制的QQ来演示系统托盘效果,就和我们平时的QQ类似
实现效果:当我们的鼠标移动到该图标后会显示文字
在这里插入图片描述

右键效果👇
在这里插入图片描述

注意

下面重要的还是托盘类以及菜单类,因为这是应用的一个小知识点有时候会牵涉很多其他的方法所以大家还是理解这一知识点就好,我这只是演示下这个怎么用,如果以后大家遇到需要系统托盘时可以参考一下这个

缩小和放大

创建托盘类
sysTray.h

#pragma once

#include <QSystemTrayIcon>
#include<QSystemTrayIcon>
class sysTray : public QSystemTrayIcon
{
	Q_OBJECT

public:
	sysTray(QWidget *parent);
	~sysTray();
public slots:
	void onIconActivated(QSystemTrayIcon::ActivationReason reason);
private:
	void initSystemTray();   //初始化
	void addSystemTrayMenu();//创建菜单
private:
	QWidget*m_parent;//用于保存父类窗口,到时候通过点击托盘时展示的窗口就作为父窗口
};

sysTray.cpp

#include "sysTray.h"
#include<Qwidget>
#include"CustomMenu.h"
sysTray::sysTray(QWidget *parent)
	:m_parent(parent)
	, QSystemTrayIcon(parent)
{
	initSystemTray();
	show();
}

sysTray::~sysTray()
{
}

void sysTray::initSystemTray()
{
	setToolTip(QStringLiteral("QQ-CAccept"));	//设置菜单名字(我们鼠标移到那时会显示的文字)
	setIcon(QIcon(":/Resources/MainWindow/app/logo.ico"));
	//点击托盘时会触发
	connect(this, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
		this, SLOT(onIconActivated(QSystemTrayIcon::ActivationReason)));
}

//添加系统菜单:显示和退出
void sysTray::addSystemTrayMenu()
{
	CustomMenu*customMenu = new CustomMenu(m_parent);
	//onShow可理解为对象名+logo+显示的文字
	customMenu->addCustomMenu("onShow", ":/Resources/MainWindow/app/logo.ico", QStringLiteral("显示"));
	customMenu->addCustomMenu("onQuit", ":/Resources/MainWindow/app/page_close_btn_hover.png", QStringLiteral("退出"));
	//如果是"onshow"对象触发到了点击信号则执行onShowNormal槽方法
	connect(customMenu->getAction("onShow"), SIGNAL(triggered(bool)), m_parent, SLOT(onShowNormal(bool)));
	connect(customMenu->getAction("onQuit"), SIGNAL(triggered(bool)), m_parent, SLOT(onShowQuit(bool)));
	customMenu->exec(QCursor::pos());//事件循环接受鼠标操作(如果不加这个那么你右键菜单无效)
	delete customMenu;				 //如果点击了某个菜单项则菜单项释放并且执行操作
	customMenu = nullptr;
}
void sysTray::onIconActivated(QSystemTrayIcon::ActivationReason reason) 
{
	if (reason == QSystemTrayIcon::Trigger) {//如果原因是左键点击触发
		m_parent->show();			//将父窗体显示
		m_parent->activateWindow(); //将父窗口设置为活动窗口
	}
	else if (reason == QSystemTrayIcon::Context) {//如果原因是右键点击
		addSystemTrayMenu();					  //添加菜单项 
	}
}

右键菜单的显示


创建右键菜单类
CustomMenu.h

#pragma once

#include <QMenu>
#include<QMap>
class CustomMenu : public QMenu
{
	Q_OBJECT

public:
	CustomMenu(QWidget *parent=nullptr);
	~CustomMenu();
public:
	//动作按钮文本+菜单icon+菜单文本
	void addCustomMenu(const QString&text, const QString&icon,const QString&name);
	QAction*getAction(const QString&text);
private:
	QMap<QString, QAction*>m_menuActionMap;
};

CustomMenu.cpp

#include "CustomMenu.h"
#include"CommonUtils.h"
CustomMenu::CustomMenu(QWidget *parent)
	: QMenu(parent)
{
	setAttribute(Qt::WA_TranslucentBackground);//设置透明
	CommonUtils::loadStyleSheet(this, "Menu"); //加载样式表
}

CustomMenu::~CustomMenu()
{
}

void CustomMenu::addCustomMenu(const QString & text, const QString & icon,const QString&name)
{	/*要结合下面这个例子来理解
	customMenu->addCustomMenu("onShow", ":/Resources/MainWindow/app/logo.ico", QStringLiteral("显示"));
	customMenu->addCustomMenu("onQuit", ":/Resources/MainWindow/app/page_close_btn_hover.png", QStringLiteral("退出"));
	//如果是"onshow"对象触发到了点击信号则执行onShowNormal槽方法
	connect(customMenu->getAction("onShow"), SIGNAL(triggered(bool)), m_parent, SLOT(onShowNormal(bool)));//如果点击到显示则把要显示的窗口显示出来
	connect(customMenu->getAction("onQuit"), SIGNAL(triggered(bool)), m_parent, SLOT(onShowQuit(bool)));//如果点击到退出则退出应用
	*/
	
	QAction*pAction = addAction(QIcon(icon), name);
	m_menuActionMap.insert(text, pAction);
}

QAction * CustomMenu::getAction(const QString & text)
{

	return m_menuActionMap[text];
}

CommonUtils.h

#pragma once
//用于常见的一些操作
#include<QPixmap>
#include<QSize>
#include<QProxyStyle>

//改变默认的部件风格
class CustomProxyStyle:public QProxyStyle {
public:
	CustomProxyStyle(QObject* parent) {
		setParent(parent);
	}
	//重写drawPrimitive
	virtual void drawPrimitive(PrimitiveElement element, const QStyleOption* option,
		QPainter* painter, const QWidget* widget = 0)const {
		if (PE_FrameFocusRect == element) {
			//去掉windows中部件默认的边框或者虚线框,部件获取焦点时直接返回,不进行绘制
			return;
		}
		else {
			QProxyStyle::drawPrimitive(element, option, painter, widget);
		}
	}

};



class CommonUtils
{
public:
	CommonUtils();
public:
	//获取圆头像
	/*
	*  mask:空的圆头像
	*  src: 图片
	*  masksize: 大小
	*/
	static QPixmap getRoundImage(const QPixmap& src, QPixmap& mask, QSize masksize = QSize(0, 0));
	
	//加载样式表
	static void loadStyleSheet(QWidget* widget, const QString& sheetName);
	
	//设置默认皮肤颜色
	static void setDefaultSkinColor(const QColor& color);

	//获取默认皮肤颜色
	static QColor getDefaultSkinColor();
	
};

CommonUtils.cpp

#include "CommonUtils.h"
#include<QFile>
#include<QPainter>
#include<QWidget>
#include<QApplication>
#include<QSettings>
CommonUtils::CommonUtils() {
}

QPixmap CommonUtils::getRoundImage(const QPixmap &src, QPixmap& mask, QSize masksize) {
	if (masksize == QSize(0, 0)) {
		masksize = mask.size();
	}
	else {
		//圆头像进行圆滑的缩放
		mask = mask.scaled(masksize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
	}
	QImage resultImage(masksize, QImage::Format_ARGB32_Premultiplied);
	QPainter painter(&resultImage);
	painter.setCompositionMode(QPainter::CompositionMode_Source);
	painter.fillRect(resultImage.rect(),Qt::transparent);//填充矩形,透明
	painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
	painter.drawPixmap(0, 0, mask);
	painter.setCompositionMode(QPainter::CompositionMode_SourceIn);
	painter.drawPixmap(0, 0, src.scaled(masksize, Qt::KeepAspectRatio, Qt::SmoothTransformation));
	painter.end();
	return QPixmap::fromImage(resultImage);
}


void CommonUtils::loadStyleSheet(QWidget* widget, const QString& sheetName) {
	QFile file(":/Resources/QSS/" + sheetName + ".css");//:/是打开一个资源文件
	file.open(QFile::ReadOnly);
	if (file.isOpen()) {
		widget->setStyleSheet("");							 //样式设置为空
		QString qsstyleSheet = QLatin1String(file.readAll());//全部读取到qsstyleSheet中去
		widget->setStyleSheet(qsstyleSheet);				 //部件进行样式设置
	}
	file.close();
}

//重写设置默认皮肤颜色
void CommonUtils::setDefaultSkinColor(const QColor& color) {
	//将颜色配置文件进行重写
	//获取路径
	const QString &&path = QApplication::applicationDirPath() + "/" + QString("tradeprintinfo.ini");
	//操作配置文件(对配置文件进行读写操作IniFormat)
	QSettings settings(path, QSettings::IniFormat);
	//【结/key,要设置的值】
	settings.setValue("DefaultSkin/red", color.red());
	settings.setValue("DefaultSkin/green", color.green());
	settings.setValue("DefaultSkin/blue", color.blue());
}

//获取默认颜色值
QColor CommonUtils::getDefaultSkinColor() {
	QColor color;
	const QString&& path= QApplication::applicationDirPath() + "/" + QString("tradeprintinfo.ini");
	//不存在文件
	if (!QFile::exists(path)) {//如果不存在该路径就设置默认颜色
		setDefaultSkinColor(QColor(22, 154, 218));
	}
	//存在文件进行文件配置操作
	QSettings settings(path, QSettings::IniFormat);
	QSettings getting(path, QSettings::IniFormat);
	color.setRed(settings.value("DefaultSkin/red").toInt());
	color.setGreen(settings.value("DefaultSkin/green").toInt());
	color.setBlue(settings.value("DefaultSkin/blue").toInt());
	return color;
}
  • 6
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值