【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对相机在地板上的一系列冲击和弹跳过程…...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...
三维GIS开发cesium智慧地铁教程(5)Cesium相机控制
一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点: 路径验证:确保相对路径.…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
23-Oracle 23 ai 区块链表(Blockchain Table)
小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...
P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
06 Deep learning神经网络编程基础 激活函数 --吴恩达
深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...
优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...
Python Ovito统计金刚石结构数量
大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...
LOOI机器人的技术实现解析:从手势识别到边缘检测
LOOI机器人作为一款创新的AI硬件产品,通过将智能手机转变为具有情感交互能力的桌面机器人,展示了前沿AI技术与传统硬件设计的完美结合。作为AI与玩具领域的专家,我将全面解析LOOI的技术实现架构,特别是其手势识别、物体识别和环境…...
提升移动端网页调试效率:WebDebugX 与常见工具组合实践
在日常移动端开发中,网页调试始终是一个高频但又极具挑战的环节。尤其在面对 iOS 与 Android 的混合技术栈、各种设备差异化行为时,开发者迫切需要一套高效、可靠且跨平台的调试方案。过去,我们或多或少使用过 Chrome DevTools、Remote Debug…...
