如何在 Qt 中添加和使用系统托盘图标

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

1. 创建 Qt 项目并准备资源文件

首先,确保已经创建了一个 Qt 项目。以下是步骤:

  1. 创建 Qt 项目:在 Qt Creator 中创建一个新的 Qt Widgets 应用程序。
  2. 添加资源文件:在 Qt Creator 中右键点击项目文件夹,选择 New > Qt > Resource File,然后命名为 resources.qrc

2. 将图标添加到资源文件中

一旦有了资源文件(resources.qrc),就可以将图标文件(例如 tray_icon.png)添加到资源系统中了。以下是具体步骤:

  1. 在 Qt Creator 中打开 resources.qrc:右键点击 resources.qrc 文件并选择 Open
  2. 添加图标文件
    • 在资源文件中,点击 添加前缀 按钮,输入前缀。
    • 在资源文件中,点击 添加文件 按钮,选择你的图标文件(例如 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 文件之后,必须重新编译项目。以下是具体步骤:

  1. 清理项目:点击 Build > Clean Project
  2. 重新构建项目:点击 Build > Run qmake,然后选择 Build > Rebuild Project

7. 托盘图标的使用

  1. 左键点击:单击系统托盘图标会将应用恢复到主窗口。
  2. 右键点击:右键点击托盘图标会显示菜单,菜单中包括 显示退出 选项。

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)添加和使用系统托盘图标。通过这些步骤,可以让应用程序在后台运行时使用托盘图标,同时提供更加友好的用户体验。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/69612.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

探索B-树系列

&#x1f308;前言&#x1f308; 本文将讲解B树系列&#xff0c;包含 B-树&#xff0c;B树&#xff0c;B*树&#xff0c;其中主要讲解B树底层原理&#xff0c;为什么用B树作为外查询的数据结构&#xff0c;以及B-树插入操作并用代码实现&#xff1b;介绍B树、B*树。 &#x1f4…

使用 POI-TL 和 JFreeChart 动态生成 Word 报告

文章目录 前言一、需求背景二、方案分析三、 POI-TL JFreeChart 实现3.1 Maven 依赖3.3 word模板设置3.2 实现代码 踩坑 前言 在开发过程中&#xff0c;我们经常需要生成包含动态数据和图表的 Word 报告。本文将介绍如何结合 POI-TL 和 JFreeChart&#xff0c;实现动态生成 W…

QT修仙之路2-2 对话框 尚欠火候

警告对话框 相关代码 错误对话框 相关代码 消息对话框 相关代码 询问对话框 相关代码 相关代码 警告对话框 QMessageBox::warning(this,"错误","账号密码不能为空",QMessageBox::Ok);错误对话框 QMessageBox msgBox(QMessageBox::Critical,"错误…

conda 修复 libstdc++.so.6: version `GLIBCXX_3.4.30‘ not found 简便方法

ImportError: /data/home/hum/anaconda3/envs/ipc/bin/../lib/libstdc.so.6: version GLIBCXX_3.4.30 not found (required by /home/hum/anaconda3/envs/ipc/lib/python3.11/site-packages/paddle/base/libpaddle.so) 1. 检查版本 strings /data/home/hum/anaconda3/envs/ipc/…

RTD2775QT/RTD2795QT瑞昱显示器芯片方案

RTD2775QT与RTD2795QT&#xff1a;高性能4K显示驱动芯片 RTD2775QT与RTD2795QT是瑞昱半导体公司推出的两款高性能显示驱动芯片&#xff0c;专为满足现代显示设备对高清、高分辨率的需求而设计。这两款芯片不仅支持4K分辨率&#xff0c;还具备丰富的功能和卓越的性能&#xff0…

【含开题报告+文档+PPT+源码】学术研究合作与科研项目管理应用的J2EE实施

开题报告 本研究构建了一套集注册登录、信息获取与科研项目管理于一体的综合型学术研究合作平台。系统用户通过注册登录后&#xff0c;能够便捷地接收到最新的系统公告和科研动态新闻&#xff0c;并能进一步点击查看详尽的新闻内容。在科研项目管理方面&#xff0c;系统提供强…

力扣 单词拆分

动态规划&#xff0c;字符串截取&#xff0c;可重复用&#xff0c;集合类。 题目 单词可以重复使用&#xff0c;一个单词可用多次&#xff0c;应该是比较灵活的组合形式了&#xff0c;可以想到用dp&#xff0c;遍历完单词后的状态的返回值。而这里的wordDict给出的是list&…

Node.js 环境配置

什么是 Node.js Node.js 是一个基于 Chrome V8 JavaScript 引擎的 JavaScript 运行时环境&#xff0c;它允许你在服务器端运行 JavaScript。传统上&#xff0c;JavaScript 主要用于浏览器中的前端开发&#xff0c;而 Node.js 使得 JavaScript 也能够在服务器上执行&#xff0c;…

Redis企业开发实战(四)——点评项目之分布式锁

目录 一、分布式锁介绍 (一)分布式锁基本介绍 (二)分布式锁满足的条件 (三)常见的分布式锁 1.Mysql 2.Redis 3.Zookeeper 二、Redis分布式锁详解 (一)Redis分布式锁的实现核心思路 获取锁&#xff1a; 释放锁&#xff1a; (二)基于Redis实现分布式锁初级版本 1.…

【个人开发】cuda12.6安装vllm安装实践【内含踩坑经验】

1. 背景 vLLM是一个快速且易于使用的LLM推理和服务库。企业级应用比较普遍&#xff0c;尝试安装相关环境&#xff0c;尝试使用。 2. 环境 模块版本python3.10CUDA12.6torch2.5.1xformers0.0.28.post3flash_attn2.7.4vllm0.6.4.post1 2.1 安装flash_attn 具体选择什么版本&…

系统思考—自我超越

“我不在乎你从哪里开始&#xff0c;我只在乎你能走到哪里。真正的超越在于敢于突破自己设定的框架。” —— 亚伯拉罕林肯 在今天这个快速变化的商业环境里&#xff0c;许多企业和团队都会遇到同样的挑战&#xff1a;如何突破现有的框架&#xff0c;实现真正的自我超越&#…

win11+mac键盘+PowerToys 重映射热键

在win11系统中&#xff0c;使用mac的蓝牙键盘&#xff0c;键盘本身没有PrintScreen键。这时可以借助PowerToys来将其他键映射到系统的PrintScreen. 1.下载安装PowerToys 地址https://learn.microsoft.com/zh-cn/windows/powertoys/ 2.打开PowerToys&#xff0c;选中【键盘管理器…

程序诗篇里的灵动笔触:指针绘就数据的梦幻蓝图<8>

大家好啊&#xff0c;我是小象٩(๑ω๑)۶ 我的博客&#xff1a;Xiao Xiangζั͡ޓއއ 很高兴见到大家&#xff0c;希望能够和大家一起交流学习&#xff0c;共同进步。 今天我们复习前面学习的指针知识 目录 关于指针数组和数组指针的区别指针数组&#xff08;Array of Poi…

今日写题work01

题目一&#xff1a;轮转数组 三种思路&#xff0c;时间复杂度越优越好 第一种思路: 直接暴力求解&#xff0c;空间复杂度为o(1),但时间复杂度为o(n^2) #include <stdio.h> void rotate(int* nums, int k, int len); int main() {int arr[] { 1,2,3,4,5,6,7 };rotate(a…

原生鸿蒙版小艺APP接入DeepSeek-R1,为HarmonyOS应用开发注入新活力

原生鸿蒙版小艺APP接入DeepSeek-R1&#xff0c;为HarmonyOS应用开发注入新活力 在科技飞速发展的当下&#xff0c;人工智能与操作系统的融合正深刻改变着我们的数字生活。近日&#xff0c;原生鸿蒙版小艺APP成功接入DeepSeek-R1&#xff0c;这一突破性进展不仅为用户带来了更智…

赛博算命之 ”梅花易数“ 的 “JAVA“ 实现 ——从玄学到科学的探索

hello~朋友们&#xff01;好久不见&#xff01; 今天给大家带来赛博算命第三期——梅花易数的java实现 赛博算命系列文章&#xff1a; 周易六十四卦 掐指一算——小六壬 更多优质文章&#xff1a;个人主页 JAVA系列&#xff1a;JAVA 大佬们互三哦~互三必回&#xff01;&#xf…

什么是PMC项目管理?

PMC项目管理&#xff08;Project Management Consultancy&#xff0c;项目管理咨询&#xff09;是一种专业化的管理服务形式&#xff0c;旨在通过提供专业的项目管理支持、方法论和工具&#xff0c;帮助企业或组织在项目实施过程中达到预期目标、提高效率、降低风险、节约成本。…

如何在电脑后台定时进行自动截图?自动截图后如何快捷保存?如何远程查看?

7-2 有时候需要对电脑的屏幕进行在后台连续性的截图保存&#xff0c;并且要可以远程查看&#xff0c;无界面&#xff0c;以达到对电脑的使用过程进行完全了解的目的&#xff0c;一般用于对小孩使用电脑的掌握&#xff0c;如果父母在外地&#xff0c;不方便就近管理&#xff0c…

从Word里面用VBA调用NVIDIA的免费DeepSeekR1

看上去能用而已。 选中的文字作为输入&#xff0c;运行对应的宏即可&#xff1b;会先MSGBOX提示一下&#xff0c;然后相关内容追加到word文档中。 需要自己注册生成好用的apikey Option ExplicitSub DeepSeek()Dim selectedText As StringDim apiKey As StringDim response A…

rebase和merge

rebase 和merge区别&#xff1a; rebase变基&#xff0c;改变基底&#xff1a;rebase会抹去提交记录。 git pull 默认merge&#xff0c;git pull --rebase 变基 rebase C、D提交属于feature分支&#xff0c;是基于master分支&#xff0c;在B提交额外拉出来的&#xff0c;当…