如何在 Qt 中添加和使用系统托盘图标
在 Qt 中实现系统托盘图标是一个常见的需求,尤其是在桌面应用程序中。系统托盘图标可以让应用程序在后台运行时仍然具有可见性,同时避免占用过多的桌面空间。本文将详细介绍如何在 Qt 项目中添加托盘图标,并通过资源系统(.qrc
文件)来管理图标文件。
1. 创建 Qt 项目并准备资源文件
首先,确保已经创建了一个 Qt 项目。以下是步骤:
- 创建 Qt 项目:在 Qt Creator 中创建一个新的 Qt Widgets 应用程序。
- 添加资源文件:在 Qt Creator 中右键点击项目文件夹,选择 New > Qt > Resource File,然后命名为
resources.qrc
。
2. 将图标添加到资源文件中
一旦有了资源文件(resources.qrc
),就可以将图标文件(例如 tray_icon.png
)添加到资源系统中了。以下是具体步骤:
- 在 Qt Creator 中打开
resources.qrc
:右键点击resources.qrc
文件并选择 Open。 - 添加图标文件:
- 在资源文件中,点击 添加前缀 按钮,输入前缀。
- 在资源文件中,点击 添加文件 按钮,选择你的图标文件(例如
tray_icon.png
)。
这样,图标就会被嵌入到应用的资源系统中,并且可以通过 :/test/icon/tray_icon.png
路径来访问。
3. 修改 .pro
文件
确保 .pro
文件包含了 resources.qrc
文件。打开 .pro
文件,并确认其中有以下行:
RESOURCES += resources.qrc
这一步非常重要,因为它确保了资源文件会被正确加载到项目中。
cmake参考如下图:
4. 使用资源图标
在 Qt 中加载资源文件的图标非常简单,使用 QIcon
来设置系统托盘图标。以下是代码示例:
4.1 设置系统托盘图标
首先,在你的 MainWindow
或者其他类中,创建一个 QSystemTrayIcon
对象,并为其设置图标:
#include <QSystemTrayIcon>
#include <QMenu>
#include <QAction>// 在 MainWindow 或其他类中添加以下成员变量
QSystemTrayIcon *m_pTrayIcon;
QMenu *m_pTrayMenu;void MainWindow::setupTrayIcon() {// 创建系统托盘图标m_pTrayIcon = new QSystemTrayIcon(this);m_pTrayIcon->setIcon(QIcon(":/icon/tray_icon.png")); // 使用资源图标m_pTrayIcon->setToolTip("Qt 应用 - 托盘模式");// 创建托盘菜单m_pTrayMenu = new QMenu(this);QAction *showAction = new QAction("显示", this);QAction *exitAction = new QAction("退出", this);connect(showAction, &QAction::triggered, this, &MainWindow::showMainWindow);connect(exitAction, &QAction::triggered, this, &MainWindow::exitApplication);m_pTrayMenu->addAction(showAction);m_pTrayMenu->addAction(exitAction);m_pTrayIcon->setContextMenu(m_pTrayMenu);// 显示托盘图标m_pTrayIcon->show();// 处理左键点击:恢复窗口connect(m_pTrayIcon, &QSystemTrayIcon::activated, this, [=](QSystemTrayIcon::ActivationReason reason) {if (reason == QSystemTrayIcon::Trigger) {showMainWindow();}});
}
4.2 可勾选的菜单项
在菜单中添加一个 QAction,并使其可勾选。当用户左键单击时,勾选状态会切换。
// 添加一个可勾选的菜单项QAction *checkAction = new QAction("启用功能", this);checkAction->setCheckable(true); // 设置该项为可勾选checkAction->setChecked(false); // 默认不勾选// 当该项的状态改变时,输出当前状态connect(checkAction, &QAction::toggled, this, [=](bool checked) {if (checked) {qDebug("功能已启用");} else {qDebug("功能已禁用");}});
5. 处理关闭事件
当用户尝试关闭窗口时,你可以让窗口最小化到系统托盘,而不是完全关闭。为了实现这一点,你需要重写 closeEvent
方法:
void MainWindow::closeEvent(QCloseEvent *event)
{// 弹出提示框,确认是否关闭应用QMessageBox::StandardButton reply = QMessageBox::question(this, "确认", "确定要关闭应用吗?
应用将最小化到系统托盘",QMessageBox::Yes | QMessageBox::No);if (reply == QMessageBox::Yes) {event->ignore(); // 阻止窗口关闭this->hide(); // 隐藏窗口m_pTrayIcon->showMessage("Qt 应用", "应用已最小化到托盘", QSystemTrayIcon::Information, 3000);} else {event->accept();}
}
6. 重新编译并运行
每次你修改 resources.qrc
文件之后,必须重新编译项目。以下是具体步骤:
- 清理项目:点击 Build > Clean Project。
- 重新构建项目:点击 Build > Run qmake,然后选择 Build > Rebuild Project。
7. 托盘图标的使用
- 左键点击:单击系统托盘图标会将应用恢复到主窗口。
- 右键点击:右键点击托盘图标会显示菜单,菜单中包括 显示 和 退出 选项。
8. 常见问题和调试
如果在运行时遇到如下警告:
QSystemTrayIcon::setVisible: No Icon set
这通常表示 Qt 没有正确加载图标。以下是一些常见的解决方法:
- 确保
.pro
文件包含resources.qrc
。 - 重新编译项目,确保资源文件被正确嵌入到最终的可执行文件中。
- 检查资源路径是否正确,代码中的路径应该是
:/icon/tray_icon.png
。
9. 完整代码
头文件(mainwindow.h)
这个头文件定义了 MainWindow 类,它包含了托盘图标相关的成员变量和函数声明。
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QSystemTrayIcon>
#include <QMenu>QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow {Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();protected:// 重写关闭事件,将窗口最小化到托盘void closeEvent(QCloseEvent *event) override;private slots:// 显示主窗口void showMainWindow();// 退出应用void exitApplication();private:// 初始化托盘图标void setupTrayIcon();private:Ui::MainWindow *ui; // UI 类QSystemTrayIcon *m_pTrayIcon; // 系统托盘图标QMenu *m_pTrayMenu; // 托盘菜单
};
#endif // MAINWINDOW_H
实现文件(mainwindow.cpp)
在 mainwindow.cpp 中,主要实现了如何初始化系统托盘图标和处理关闭事件。
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
#include <QCloseEvent>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);// 设置托盘图标和菜单setupTrayIcon();
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::setupTrayIcon()
{// 创建系统托盘图标m_pTrayIcon = new QSystemTrayIcon(this);m_pTrayIcon->setIcon(QIcon(":/icon/tray_icon.png")); // 使用资源图标m_pTrayIcon->setToolTip("Qt 应用 - 托盘模式");// 创建托盘菜单m_pTrayMenu = new QMenu(this);QAction *showAction = new QAction("显示", this);QAction *exitAction = new QAction("退出", this);// 添加一个可勾选的菜单项QAction *checkAction = new QAction("启用功能", this);checkAction->setCheckable(true); // 设置该项为可勾选checkAction->setChecked(false); // 默认不勾选connect(showAction, &QAction::triggered, this, &MainWindow::showMainWindow);connect(exitAction, &QAction::triggered, this, &MainWindow::exitApplication);// 当该项的状态改变时,输出当前状态connect(checkAction, &QAction::toggled, this, [=](bool checked) {if (checked) {qDebug("功能已启用");} else {qDebug("功能已禁用");}});m_pTrayMenu->addAction(showAction);m_pTrayMenu->addAction(exitAction);m_pTrayMenu->addAction(checkAction);m_pTrayIcon->setContextMenu(m_pTrayMenu);// 显示托盘图标m_pTrayIcon->show();// 处理左键点击:恢复窗口connect(m_pTrayIcon, &QSystemTrayIcon::activated, this, [=](QSystemTrayIcon::ActivationReason reason) {if (reason == QSystemTrayIcon::Trigger) {showMainWindow();}});
}void MainWindow::closeEvent(QCloseEvent *event)
{// 弹出提示框,确认是否关闭应用QMessageBox::StandardButton reply = QMessageBox::question(this, "确认", "确定要关闭应用吗?\n应用将最小化到系统托盘",QMessageBox::Yes | QMessageBox::No);if (reply == QMessageBox::Yes) {event->ignore(); // 阻止窗口关闭this->hide(); // 隐藏窗口m_pTrayIcon->showMessage("Qt 应用", "应用已最小化到托盘", QSystemTrayIcon::Information, 3000);} else {event->accept();}
}void MainWindow::showMainWindow()
{this->show(); // 恢复主窗口this->activateWindow(); // 激活窗口
}void MainWindow::exitApplication()
{m_pTrayIcon->hide(); // 隐藏托盘图标QApplication::quit(); // 退出应用
}
总结
本文介绍了如何在 Qt 项目中通过资源文件(resources.qrc
)添加和使用系统托盘图标。通过这些步骤,可以让应用程序在后台运行时使用托盘图标,同时提供更加友好的用户体验。
相关文章:

如何在 Qt 中添加和使用系统托盘图标
在 Qt 中实现系统托盘图标是一个常见的需求,尤其是在桌面应用程序中。系统托盘图标可以让应用程序在后台运行时仍然具有可见性,同时避免占用过多的桌面空间。本文将详细介绍如何在 Qt 项目中添加托盘图标,并通过资源系统(.qrc 文件…...

【WB 深度学习实验管理】利用 Hugging Face 实现高效的自然语言处理实验跟踪与可视化
本文使用到的 Jupyter Notebook 可在GitHub仓库002文件夹找到,别忘了给仓库点个小心心~~~ https://github.com/LFF8888/FF-Studio-Resources 在自然语言处理领域,使用Hugging Face的Transformers库进行模型训练已经成为主流。然而,随着模型复…...

基础入门-网站协议身份鉴权OAuth2安全Token令牌JWT值Authirization标头
知识点: 1、网站协议-http/https安全差异(抓包) 2、身份鉴权-HTTP头&OAuth2&JWT&Token 一、演示案例-网站协议-http&https-安全测试差异性 1、加密方式 HTTP:使用明文传输,数据在传输过程中可以被…...

C语言基础系列【3】VSCode使用
前面我们提到过VSCode有多么的好用,本文主要介绍如何使用VSCode编译运行C语言代码。 安装 首先去官网(https://code.visualstudio.com/)下载安装包,点击Download for Windows 获取安装包后,一路点击Next就可以。 配…...

MySQL-5.7.44安装(CentOS7)
目录 1、下载安装包并解压 2、创建数据目录与日志目录 3、设置环境变量 4、刷新环境变量 5、执行初始化 6、创建配置文件目录 7、新建配置文件 8、为安装目录赋予可执行权限 9、创建服务启动脚本 10、启动服务并将启动脚本加入开机自启动 11、查看服务状态 12、创建…...

服务端与多客户端照片的传输,recv,send
一、照片传输 server.c /* * 文件名称:server.c * 创 建 者: * 创建日期:2025年02月07日 * 描 述: */ #include <stdio.h> #include <sys/types.h> /* See NOTES */ #include <sys/socket.h…...

JS实现灯光闪烁效果
在 JS中,我们可以实现灯光闪烁效果,这里主要用 setInterval 和 clearInterval 两个重要方法。 效果图 源代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>灯闪烁效果<…...

SpringCloud面试题----Nacos和Eureka的区别
功能特性 服务发现 Nacos:支持基于 DNS 和 RPC 的服务发现,提供了更为灵活的服务发现机制,能满足不同场景下的服务发现需求。Eureka:主要基于 HTTP 的 RESTful 接口进行服务发现,客户端通过向 Eureka Server 发送 HT…...

verilog练习:i2c slave 模块设计
文章目录 前言1. 结构2.代码2.1 iic_slave.v2.2 sync.v2.3 wr_fsm.v2.3.1 状态机状态解释 2.4 ram.v 3. 波形展示4. 建议5. 资料总结 前言 首先就不啰嗦iic协议了,网上有不少资料都是叙述此协议的。 下面将是我本次设计的一些局部设计汇总,如果对读者有…...

3.5 Go(特殊函数)
目录 一、匿名函数 1、匿名函数的特点: 2、匿名函数代码示例 2、匿名函数的类型 二、递归函数 1. 递推公式版本 2. 循环改递归 三、嵌套函数 1、嵌套函数用途 2、代码示例 3、作用域 & 变量生存周期 四、闭包 1、闭包使用场景 2、代码示例 五、De…...

Android的MQTT客户端实现
在 Android 平台上实现 MQTT 客户端的完整技术方案,涵盖基础实现、安全连接、性能优化和最佳实践: 一、技术选型与依赖配置 推荐库 Eclipse Paho Android Service(官方维护,支持后台运行) gradle 复制 // build.gradl…...

国产编辑器EverEdit - 编辑辅助功能介绍
1 编辑辅助功能 1.1 各编辑辅助选项说明 1.1.1 行号 打开该选项时,在编辑器主窗口左侧显示行号,如下图所示: 1.1.2 文档地图 打开该选项时,在编辑器主窗口右侧靠近垂直滚动条的地方显示代码的缩略图,如下图所示&…...

WPF 在后台使TextBox失去焦点的方法
在软件设计开发的时候,偶尔会遇到在后台xaml.cs后台中,要将TextBox控件的焦点取消或者使TextBox控件获取焦点,下面介绍讲述一种简单的“只让特定的 TextBox 失去焦点”方法: 前端xaml代码示例: <StackPanel Orientation"…...

工作案例 - python绘制excell表中RSRP列的CDF图
什么是CDF图 CDF(Cumulative Distribution Function)就是累积分布函数,是概率密度函数的积分。CDF函数是一个在0到1之间的函数,描述了随机变量小于或等于一个特定值的概率。在可视化方面,CDF图表明了一个随机变量X小于…...

CTF SQL注入学习笔记
部分内容来自于SQL注入由简入精_哔哩哔哩_bilibili SQL语句 1.mysqli_error():返回最近调用函数的最后一个错误描述 语法:mysqli_error(connection) 规定要使用的Mysql连接; 返回一个带有错误描述的字符串。如果没有错误发生则返回 "" 2…...

element-plus el-tree-select 修改 value 字段
element-plus el-tree-select 修改 value 字段 ,不显示label 需要注意两个地方: <el-tree-select v-model"value" :data"data" multiple :render-after-expand"false" show-checkbox style"width: 240px" …...

基于javaweb的SpringBoot小区智慧园区管理系统(源码+文档+部署讲解)
🎬 秋野酱:《个人主页》 🔥 个人专栏:《Java专栏》《Python专栏》 ⛺️心若有所向往,何惧道阻且长 文章目录 运行环境开发工具适用功能说明 运行环境 Java≥8、MySQL≥5.7、Node.js≥14 开发工具 后端:eclipse/idea/myeclipse…...

SpringBoot学习之shardingsphere实现分库分表(基于Mybatis-Plus)(四十九)
一、shardingsphere介绍 ShardingSphere是一款起源于当当网内部的应用框架。2015年在当当网内部诞生,最初就叫ShardingJDBC。2016年的时候,由其中一个主要的开发人员张亮,带入到京东数科,组件团队继续开发。在国内历经了当当网、电信翼支付、京东数科等多家大型互联网企业的…...

23.PPT:校摄影社团-摄影比赛作品【5】
目录 NO12345 NO6 NO7/8/9/10 单元格背景填充表格背景填充文本框背景填充幻灯片背景格式设置添加考生文件夹下的版式 NO12345 插入幻灯片和放入图片☞快速:插入→相册→新建相册→文件→图片版式→相框形状→调整边框宽度左下角背景图片:视图→…...

Baumer工业相机堡盟相机的相机传感器芯片清洁指南
Baumer工业相机堡盟相机的相机传感器芯片清洁指南 Baumer工业相机1.Baumer工业相机传感器芯片清洁工具和清洁剂2.Baumer工业相机传感器芯片清洁步骤2.1、准备步骤2.2、清洁过程1.定位清洁工具2.清洁传感器3.使用吹风装置 Baumer工业相机传感器芯片清洁的优势设计与结…...

Spring Boot 整合 JPA 实现数据持久化
目录 前言 一、JPA 核心概念与实体映射 1. 什么是 JPA? 2. JPA 的主要组件 3. 实体映射 4. 常见的字段映射策略 二、Repository 接口与自定义查询 1. 什么是 Repository 接口? 2. 动态查询方法 3. 自定义查询 4. 分页与排序 三、实战案例&…...

快速在wsl上部署学习使用c++轻量化服务器-学习笔记
知乎上推荐的Tinywebserver这个服务器,快速部署搭建,学习c服务器开发 仓库地址 githubhttps://link.zhihu.com/?targethttps%3A//github.com/qinguoyi/TinyWebServerhttps://link.zhihu.com/?targethttps%3A//github.com/qinguoyi/TinyWebServer 在…...

【R语言】数据操作
一、查看和编辑数据 1、查看数据 直接打印到控制台 x <- data.frame(a1:20, b21:30) x View()函数 此函数可以将数据以电子表格的形式进行展示。 用reshape2包中的tips进行举例: library("reshape2") View(tips) head()函数 查看前几行数据&…...

MariaDB MaxScale实现mysql8主从同步读写分离
一、MaxScale基本介绍 MaxScale是maridb开发的一个mysql数据中间件,其配置简单,能够实现读写分离,并且可以根据主从状态实现写库的自动切换,对多个从服务器能实现负载均衡。 二、MaxScale实验环境 中间件192.168.121.51MaxScale…...

【python】简单的flask做页面。一组字母组成的所有单词。这里的输入是一组字母,而输出是所有可能得字母组成的单词列表
目录结构如下: https://github.com/kaede316/Pythons_pj.git 效果: 后续可扩展为工具网站: 更新 2025.02.09 1、增加等间距制作人 时间信息 2、增加判断润年的功能...

单片机之基本元器件的工作原理
一、二极管 二极管的工作原理 二极管是一种由P型半导体和N型半导体结合形成的PN结器件,具有单向导电性。 1. PN结形成 P型半导体:掺入三价元素,形成空穴作为多数载流子。N型半导体:掺入五价元素,形成自由电子作为多…...

吴恩达深度学习——卷积神经网络的特殊应用
内容来自https://www.bilibili.com/video/BV1FT4y1E74V,仅为本人学习使用。 文章目录 人脸识别相关定义Similarity函数使用Siamese网络实现函数d使用Triplet损失学习参数 神经风格迁移深度卷积网络可视化神经风格迁移的代价函数内容损失函数风格损失函数 人脸识别 …...

安宝特方案 | AR助力制造业安全巡检智能化革命!
引言: 在制造业中,传统巡检常面临流程繁琐、质量波动、数据难以追溯等问题。安宝特AR工作流程标准化解决方案,通过增强现实AR技术,重塑制造业安全巡检模式,以标准化作业流程为核心,全面提升效率、质量与…...

Unity-Mirror网络框架-从入门到精通之Discovery示例
文章目录 前言Discovery示例NetworkDiscoveryNetworkDiscoveryHUDServerRequestServerResponse最后前言 在现代游戏开发中,网络功能日益成为提升游戏体验的关键组成部分。本系列文章将为读者提供对Mirror网络框架的深入了解,涵盖从基础到高级的多个主题。Mirror是一个用于Un…...

项目的虚拟环境的搭建与pytorch依赖的下载
文章目录 配置环境 pytorch的使用需要安装对应的cuda 在PyTorch中使用CUDA, pytorch与cuda不同版本对应安装指南,查看CUDA版本,安装对应版本pytorch 【超详细教程】2024最新Pytorch安装教程(同时讲解安装CPU和GPU版本) 配置环境…...