【QT常用技术讲解】任务栏图标+socket网络服务+开机自启动
前言
首先看网络编程的定义:两个不同主机设备之间的进程通信。C/S(Client-Server)是早期非常典型的软件架构,C/S架构虽然简单,但却非常适用于桌面图形化的QT项目。
本篇的QT项目是从真实的项目中简化出来,满足很多相似的场景:创建一个TCP服务,接收到消息后,通过多线程执行后台CMD命令行,并且自动把程序放到系统自启动目录中。
覆盖到QT的知识点:任务栏托盘、右键菜单、TCP服务、多线程。
功能讲解
1、创建系统托盘
// 创建托盘图标QSystemTrayIcon *trayIcon = new QSystemTrayIcon();trayIcon->setIcon(QIcon(":/index/img/default.png")); // 设置托盘图标
// 创建上下文菜单QMenu *menu = new QMenu();
// 添加菜单项menu->addAction(exitAction);trayIcon->setContextMenu(menu);// 显示托盘图标trayIcon->show();
2、托盘右键菜单
// 创建上下文菜单QMenu *menu = new QMenu();QAction *showAction = new QAction("执行后台命令", &app);//测试用// 连接信号与槽QObject::connect(showAction, &QAction::triggered, []() {//测试:打开谷歌浏览器QString cmd = "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe";cmdrun act;act.Run(cmd);});QAction *exitAction = new QAction("退出", &app);QObject::connect(exitAction, &QAction::triggered, &app, &QApplication::quit);// 添加菜单项menu->addAction(showAction);menu->addAction(exitAction);trayIcon->setContextMenu(menu);
showAction事件只是用来测试点击右键之后,执行本地的CMD命令是否正常,适合用来调用第三方软件达到指定的目的(比如通过window的powershell脚本获取指定EXE执行程序的图标),调通之后就可以注释掉,用TCP创建的服务执行本地的CMD命令。
3、TCP服务
首先,需要在.pro文件中加上network,编译时才不会报错
QT += core gui network
tcp服务头文件:
#ifndef MYTCPSERVER_H
#define MYTCPSERVER_H
#include <QTcpServer>
#include <QTcpSocket>
#include <QDebug>
#include <QObject>//请求包结构
typedef struct netPackQ
{char opCode[2];//暗号校验头--校验不对的直接丢弃char keyword[254];//交互的核心内容netPackQ(){memset(opCode,0,2);memset(keyword,0,254);}
} netPackQ;class Mytcpserver: public QObject {Q_OBJECTpublic:Mytcpserver(QObject *parent = nullptr);private slots:void onNewConnection();private:QTcpServer *server;
};#endif // MYTCPSERVER_H
TCP主文件:
#include "mytcpserver.h"
#include "cmdrun.h"Mytcpserver::Mytcpserver(QObject *parent) : QObject(parent) {// 创建 TCP 服务器server = new QTcpServer(this);// 连接新连接信号到槽函数connect(server, &QTcpServer::newConnection, this, &Mytcpserver::onNewConnection);// 绑定到 10086 端口if (!server->listen(QHostAddress::Any, 10086)) {qDebug() << "Server could not start!";} else {qDebug() << "Server started on port 10086.";}
}void Mytcpserver::onNewConnection() {QTcpSocket *socket = server->nextPendingConnection();// 连接读取数据信号connect(socket, &QTcpSocket::readyRead, [socket]() {netPackQ packet;qint64 bytesReceived = socket->read(reinterpret_cast<char*>(&packet), sizeof(netPackQ));if (bytesReceived == sizeof(netPackQ)) {// 处理接收到的数据qDebug() << "Received date";if(packet.opCode[0] == 0x01 && packet.opCode[1]==9){//执行后台命令,打开指定应用。比如:C:\Windows\notepad.exeqDebug() << "Received keyword:" << packet.keyword;cmdrun act;act.Run(packet.keyword);//====处理核心内容=====}socket->write("Received sucess\n"); // 回复客户端} else {qDebug() << "Received incomplete data";}});// 连接断开信号connect(socket, &QTcpSocket::disconnected, socket, &QTcpSocket::deleteLater);
}
4、多线程执行后台CMD命令
直接用进程执行CMD命令会导致托盘卡顿,所以得用多线程来执行,cmdrun类很简单,如下:
//头文件:cmdrun.h
#ifndef CMDRUN_H
#define CMDRUN_H
#include<QString>
#include "threadCmd.h"
class cmdrun
{
public:cmdrun();~cmdrun();int Run(QString cmd);
};#endif // CMDRUN_H//cpp文件:cmdrun.cpp
#include "cmdrun.h"
#include <QDebug>cmdrun::cmdrun()
{}cmdrun::~cmdrun()
{}int cmdrun::Run(QString cmd){//qDebug() << __LINE__ << cmd;ThreadCmd *thread = new ThreadCmd(cmd);thread->start();return 1;
}
5、多进程执行CMD命令
//头文件:threadCmd.h
#ifndef THREADCMD_H
#define THREADCMD_H#include <QThread>
#include <QString>class ThreadCmd : public QThread
{Q_OBJECT
public:explicit ThreadCmd(const QString ¶m) ;protected:void run() override;private:QString m_param;
};#endif // THREADCMD_H//cpp文件:threadCmd.cpp
#ifndef THREADCMD_CPP
#define THREADCMD_CPP#include "threadCmd.h"
#include <QDebug>
#include <QProcess>
#include <QTextCodec>ThreadCmd::ThreadCmd(const QString ¶m) : m_param(param) {}void ThreadCmd::run(){QProcess process;// 执行命令QString cmd = "D:\\cmdexec.cmd \"" + m_param +"\"";//QString cmd = m_param;//qDebug() << __LINE__ << cmd;// 启动快捷方式if (QProcess::startDetached(cmd)) {qDebug() << "Application launched successfully.";} else {qDebug() << "Failed to launch application.";}// 进程使用完毕后,可以手动删除process.deleteLater();
}#endif // THREADCMD_CPP
6、开机自启动
系统托盘通常都有开机自启动的需求,可以手动拷贝到启动目录,或者在程序中编写把应用程序的.lnk文件放到自启动目录中:
void addToStartup(const QString appPath) {QString startupPath = QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation) + "/Startup/";//qDebug()<< __LINE__ << startupPath;// 创建启动文件夹(如果不存在)QDir dir(startupPath);if (!dir.exists()) {dir.mkpath(".");}// 创建快捷方式(Windows 特有)QString shortcutPath = startupPath + "cstsvr.lnk";if (!QFile::exists(shortcutPath)) {// 使用 PowerShell 创建快捷方式 (请根据实际情况调整)QString command = QString("powershell -command \"$ws = New-Object -ComObject WScript.Shell; $s = $ws.CreateShortcut('%1'); $s.TargetPath='%2'; $s.Save()\"").arg(shortcutPath).arg(appPath);QProcess::execute(command);}
}int main(int argc, char *argv[]) {QApplication app(argc, argv);// 获取当前应用程序的完整路径QString appPath = QCoreApplication::applicationFilePath();//qDebug()<< __LINE__ << appPath;addToStartup(appPath);// 添加自启动到启动文件夹.......
}
篇尾
不同主机之间的进程间通信,通常需要设定一端为服务端进行侦听,当然也可以两端都设置为服务端,服务端≠服务器,服务端只代表某项服务的侦听端,比如本篇涉及的项目需求是,国产Linux系统需要获取window系统的所有应用程序的图标,并且取回到国产Linux系统的QT界面中展示,此时就需要在window系统上挂着【根据exe应用路径获取图片】的服务端,并把文件回传给Linux。
相关文章:
【QT常用技术讲解】任务栏图标+socket网络服务+开机自启动
前言 首先看网络编程的定义:两个不同主机设备之间的进程通信。C/S(Client-Server)是早期非常典型的软件架构,C/S架构虽然简单,但却非常适用于桌面图形化的QT项目。 本篇的QT项目是从真实的项目中简化出来,满足很多相似的场景&…...

【计算机基础——数据结构——AVL平衡二叉树】
1. BST二叉查找树 1.1 BST二叉查找树的特性 左子树上所有结点的值均小于或等于它的根结点的值。右子树上所有结点的值均大于或等于它的根结点的值。左、右子树也分别为二叉排序树。 1.2 BST二叉查找树的缺点 二叉查找树是有缺点的,在不断插入的时候,…...

体育活动赛事报名马拉松微信小程序开发
功能描述 体育活动赛事报名马拉松微信小程序,该项目是一个体育活动报名小程序,主要功能有活动报名、扫码签到、签到积分、排行奖励、积分兑换等功能。 用户端🔶登录:◻️1.微信授权登录 ◻️2.手机号码授权 🔶首页&am…...

【C++】C++基础知识
一.函数重载 1.函数重载的概念 函数重载是函数的一种特殊情况,C允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表必须不同。函数重载常用来处理实现功能类似,而数据类型不同的问题。 #include <iostream> using…...

中间件安全
IIS IIS短文件漏洞 此漏洞实际是由HTTP请求中旧DOS 8.3名称约定(SFN)的代字符(~)波浪号引起的。它允许远程攻击者在Web根目录下公开文件和文件夹名称(不应该可被访问)。攻击者可以找到通常无法从外部直接访问的重要文件,并获取有关应用程序基础结构的信息。 利用工具 https…...

Zabbix中文监控指标数据乱码
1)点击主机,选择Zabbix server 中的 图形 一项,可以看到当前显示的为乱码 2) 下载字体文件: https://gitcode.com/open-source-toolkit/4a3db/blob/main/SimHei.zip 解压unzip -x SimHei.zip 3) 替换字体文…...
【AI】AI如何赋能软件开发流程
方向一:流程与模式介绍【传统软件开发 VS AI参与的软件开发】 传统软件开发流程 传统软件开发流程一般可以分为以下几个阶段: 1. 需求分析:在这个阶段,开发团队与客户沟通,明确软件的需求和目标。团队会收集、整理和分…...

恒创科技:什么是 RAID 3 ? RAID 3、4 和5之间有什么区别?
RAID 是一种存储数据以提高性能并减少数据丢失的特定技术。您可以根据自己的需求选择多种 RAID 类型。RAID 3 是列表中比较有效的类型之一。本文将重点介绍这种特定的 RAID 技术,并比较 RAID 3、4 和 5。 RAID 3 的定义 RAID 3 是一种特定的磁盘配置,用于…...
python获取iOS最近业务日志的两种方法
当iOS UI自动化用例执行失败的时候,需要获取当时的业务日志,供后续分析使用。 现在已经把iOS沙盒目录挂载到本地,剩下的事情就是从沙盒目录中捞取当前的日志,沙盒中的日志文件较大,整体导出来也可以,但是会…...
【如何获取股票数据43】Python、Java等多种主流语言实例演示获取股票行情api接口之沪深指数历史交易数据获取实例演示及接口API说明文档
最近一两年内,股票量化分析逐渐成为热门话题。而从事这一领域工作的第一步,就是获取全面且准确的股票数据。因为无论是实时交易数据、历史交易记录、财务数据还是基本面信息,这些数据都是我们进行量化分析时不可或缺的宝贵资源。我们的主要任…...
ESLint 使用教程(一):从零配置 ESLint
前言 在现代前端开发中,代码质量和风格一致性是团队合作和项目维护的重要因素。而 ESLint 作为一款强大的 JavaScript 静态代码分析工具,能够帮助开发者发现和修复代码中的潜在问题。本文将详细介绍 ESLint 的常用规则配置,并结合实际应用场…...
openssl对称加密代码讲解实战
文章目录 一、openssl对称加密和非对称加密算法对比1. 加密原理2. 常用算法3. 加密速度4. 安全性5. 应用场景6. 优缺点对比综合分析 二、代码实战代码说明:运行输出示例代码说明:注意事项 一、openssl对称加密和非对称加密算法对比 OpenSSL 是一个广泛使…...

web前端动画按钮(附源代码)
效果图 源代码 HTML部分 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title> …...

go函数传值是值传递?还是引用传递?slice案例加图解
先说下结论 Go语言中所有的传参都是值传递(传值),都是一个副本,一个拷贝。 值语义类型:参数传递的时候,就是值拷贝,这样就在函数中就无法修改原内容数据。 基本类型:byte、int、bool…...

PostgreSQL数据库笔记
PostgreSQL 是什么 PostgreSQL(简称Postgres或PG)是一个功能强大、可靠性高、可扩展性好的开源对象-关系数据库服务器(ORDBMS),它以加州大学伯克利分校计算机系开发的POSTGRES版本4.2为基础。 发展历程 起源与发展&a…...

财务软件源码SaaS云财务
在如今的商业环境中,准确的财务管理是一家企业取得成功的关键。然而,传统的财务管理方法已经无法满足现代企业的需求,需要一个全新的解决方案。推出了全新的财务软件为您提供完美的解决方案。 选择财务软件源码,您将享受到以下优…...

Elasticsearch集群和Kibana部署流程
搭建Elasticsearch集群 1. 进入Elasticsearch官网下载页面,下载Elasticsearch 在如下页面选择Elasticsearch版本,点击download按钮,进入下载页面 右键选择自己操作系统对应的版本,复制下载链接 然后通过wget命令下载Elastics…...

丹摩征文活动 | 丹摩智算:大数据治理的智慧引擎与实践探索
丹摩DAMODEL|让AI开发更简单!算力租赁上丹摩! 目录 一、引言 二、大数据治理的挑战与重要性 (一)数据质量问题 (二)数据安全威胁 (三)数据管理复杂性 三、丹摩智算…...
【Django】Clickjacking点击劫持攻击实现和防御措施
Clickjacking点击劫持 1、clickjacking攻击2、clickjacking攻击场景 1、clickjacking攻击 clickjacking攻击又称为点击劫持攻击,是一种在网页中将恶意代码等隐藏在看似无害的内容(如按钮)之下,并诱使用户点击的手段。 2、clickj…...

Ansys Zemax | 手机镜头设计 - 第 4 部分:用LS-DYNA进行冲击性能分析
该系列文章将讨论智能手机镜头模组设计的挑战,从概念和设计到制造和结构变形分析。本文是四部分系列中的第四部分,它涵盖了相机镜头的显式动态模拟,以及对光学性能的影响。使用Ansys Mechanical和LS-DYNA对相机在地板上的一系列冲击和弹跳过程…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...

10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...

保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek
文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama(有网络的电脑)2.2.3 安装Ollama(无网络的电脑)2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...
LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》
这段 Python 代码是一个完整的 知识库数据库操作模块,用于对本地知识库系统中的知识库进行增删改查(CRUD)操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 📘 一、整体功能概述 该模块…...

【笔记】WSL 中 Rust 安装与测试完整记录
#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统:Ubuntu 24.04 LTS (WSL2)架构:x86_64 (GNU/Linux)Rust 版本:rustc 1.87.0 (2025-05-09)Cargo 版本:cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...