如何在 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工业相机传感器芯片清洁的优势设计与结…...
Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...
基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...
UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...
抖音增长新引擎:品融电商,一站式全案代运营领跑者
抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...
MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...
AGain DB和倍数增益的关系
我在设置一款索尼CMOS芯片时,Again增益0db变化为6DB,画面的变化只有2倍DN的增益,比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析: 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...
C/C++ 中附加包含目录、附加库目录与附加依赖项详解
在 C/C 编程的编译和链接过程中,附加包含目录、附加库目录和附加依赖项是三个至关重要的设置,它们相互配合,确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中,这些概念容易让人混淆,但深入理解它们的作用和联…...
宇树科技,改名了!
提到国内具身智能和机器人领域的代表企业,那宇树科技(Unitree)必须名列其榜。 最近,宇树科技的一项新变动消息在业界引发了不少关注和讨论,即: 宇树向其合作伙伴发布了一封公司名称变更函称,因…...
