当前位置: 首页 > news >正文

QT-窗口嵌入外部exe

窗口类:

#pragma once
#include <QApplication>
#include <QWidget>
#include <QVBoxLayout>
#include <QProcess>
#include <QTimer>
#include <QDebug>
#include <Windows.h>
#include <QWindow>
#include <QResizeEvent>class ExternalAppWidget : public QWidget 
{Q_OBJECTpublic:ExternalAppWidget(QString exePath, QString strTitle, QWidget *parent = nullptr);~ExternalAppWidget();private:bool checkAppStartDone(QString strAppTitle);void killProcessByExeName(QString processName);protected:void resizeEvent(QResizeEvent *event);private:QVBoxLayout *m_pLayout;QProcess	*m_pProcess;QWidget		*m_pExternalWindow;QString		m_strExePath;QString		m_strExeTile;
};
#include "externalAppWidget.h"
#include <QFileInfo>
#include <QDir>
#include <QThread>
#include <QMessageBox>
#include <QTime>// 不阻塞定时器
struct sTimeout
{QTime time;uint32_t interval;void start(uint32_t t){interval = t;time.start();};bool isTimeOut(){return time.elapsed() > interval;};
};ExternalAppWidget::ExternalAppWidget(QString exePath, QString strTitle,QWidget *parent) :QWidget(parent),m_pExternalWindow(nullptr), m_strExePath(exePath), m_strExeTile(strTitle)
{QFileInfo fileInfo(exePath);killProcessByExeName(fileInfo.fileName());m_pLayout = new QVBoxLayout(this);// 启动外部程序m_pProcess = new QProcess(this);m_pProcess->setWorkingDirectory(fileInfo.absolutePath());m_pProcess->start(exePath); m_pProcess->waitForStarted();checkAppStartDone(m_strExeTile);// 获取外部程序的窗口句柄HWND hwnd = FindWindowW(NULL, reinterpret_cast<LPCWSTR>(m_strExeTile.utf16()));if (hwnd){// 修改窗口样式以去掉标题栏LONG style = GetWindowLong(hwnd, GWL_STYLE);style &= ~(WS_CAPTION | WS_THICKFRAME); // 移除标题栏和边框SetWindowLong(hwnd, GWL_STYLE, style | WS_POPUP); // 设置为无边框的弹出窗口ShowWindow(hwnd, SW_SHOW);WId wid = (WId)hwnd;QWindow *pQwindow;pQwindow = QWindow::fromWinId(wid);// 创建窗口容器m_pExternalWindow = QWidget::createWindowContainer(pQwindow, this);m_pExternalWindow->setAttribute(Qt::WA_NativeWindow);m_pExternalWindow->setMinimumSize(100, 100);m_pLayout->addWidget(m_pExternalWindow);m_pLayout->setMargin(0);		}else{//QMessageBox::information(0, "Tip", QString("未找到窗口:%1").arg(m_strExeTile), QMessageBox::Yes);qDebug() << "Failed to find external application window.";}setLayout(m_pLayout);
}ExternalAppWidget::~ExternalAppWidget()
{QFileInfo fileInfo(m_strExePath);killProcessByExeName(fileInfo.fileName());
}bool ExternalAppWidget::checkAppStartDone(QString strAppTitle)
{// 循环检查窗口是否存在QString windowTitle = strAppTitle;HWND hwnd = nullptr;int nStep = 0;sTimeout timeout;while (true){Sleep(5);switch (nStep){case 0:{timeout.start(30*1000);nStep = 1;}break;case 1:{hwnd = FindWindowW(NULL, reinterpret_cast<LPCWSTR>(windowTitle.utf16()));if (hwnd != NULL){return true; // 找到窗口,退出循环}else if (timeout.isTimeOut()){return false;}}break;default:break;}}return false;}void ExternalAppWidget::killProcessByExeName( QString processName)
{QStringList params;params << "-f" << "-im" << processName;QProcess process;process.start("taskkill", params);process.waitForFinished();
}void ExternalAppWidget::resizeEvent(QResizeEvent *event) {QWidget::resizeEvent(event);if (m_pExternalWindow) {m_pExternalWindow->resize(event->size());}
}

应用层调用

void cWinDebug::initRemoteDesktopWidget()
{for (int i = 1; i <= DEV_MAX_COUNT; i++){QString strTitleName = GET_PARAM_STRING(P_EXE_TITLE_NAME(i));QString strTabName = GET_PARAM_STRING(P_TAB_NAME(i));QString strExePath = GET_PARAM_STRING(P_EXE_PATH(i));if (strExePath.isEmpty() || strTitleName.isEmpty() || strTabName.isEmpty()){continue;}ExternalAppWidget* e = new ExternalAppWidget(strExePath, strTitleName, this);e->showMaximized();ui.tabWidgetRemote->insertTab(0, (QWidget*)e, strTabName);}ui.tabWidgetRemote->setCurrentIndex(0);
}

相关文章:

QT-窗口嵌入外部exe

窗口类&#xff1a; #pragma once #include <QApplication> #include <QWidget> #include <QVBoxLayout> #include <QProcess> #include <QTimer> #include <QDebug> #include <Windows.h> #include <QWindow> #include <…...

C#中使用系统默认应用程序打开文件

有时您可能希望程序使用默认应用程序打开文件。 例如&#xff0c;您可能希望显示 PDF 文件、网页或互联网上的 URL。 System.Diagnostics.Process类的Start方法启动系统与文件关联的应用程序。 例如&#xff0c;如果文件扩展名为.txt&#xff0c;则系统会在 NotePad、WordPa…...

如何在 Ubuntu 22.04 上配置 Logrotate 高级教程

简介 本教程将教你如何在 Ubuntu 22.04 上进行 Logrotate 的高级配置。 日志管理对于维护系统性能和确保你的日志不会占用太多磁盘空间至关重要。在 Ubuntu 上&#xff0c;logrotate 是一个强大的工具&#xff0c;它可以通过轮转、压缩和删除旧日志来自动管理日志文件。在本教…...

java项目之校园管理系统的设计与实现(源码+文档)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的校园管理系统的设计与实现。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; springboot校园…...

关于 webservice 日志中 源IP是node IP的问题,是否能解决换成 真实的客户端IP呢

本篇目录 1. 问题背景2. 部署gitlab 17.52.1 添加repo源2.2 添加repo源 下载17.5.0的charts包2.3 修改values文件2.3.1 hosts修改如下2.3.2 appConfig修改如下2.3.3 gitlab下的sidekiq配置2.3.4 certmanager修改如下2.3.5 nginx-ingress修改如下2.3.6 <可选> prometheus修…...

Serializable接口

最近写项目的时候&#xff0c;发现有一些类要实现Serializable接口&#xff0c;一开始只是粗略的知道实现了Serializable接口&#xff0c;这个类的对象可以被序列化&#xff0c;但我比较轴&#xff0c;想知道这个接口到底有什么作用。 我点开这个接口发现什么方法都没有实现&am…...

如何操作github,gitee,gitcode三个git平台建立镜像仓库机制,这样便于维护项目只需要维护一个平台仓库地址的即可-优雅草央千澈

如何操作github&#xff0c;gitee&#xff0c;gitcode三个git平台建立镜像仓库机制&#xff0c;这样便于维护项目只需要维护一个平台仓库地址的即可-优雅草央千澈 问题背景 由于我司最早期19年使用的是gitee&#xff0c;因此大部分仓库都在gitee有几百个库的代码&#xff0c;…...

【HDU】1089 A+B for Input-Output Practice (I)

1089 AB for Input-Output Practice (I):以EOF结尾的输入 Problem Description Your task is to Calculate a b. Too easy?! Of course! I specially designed the problem for acm beginners. You must have found that some problems have the same titles with this one,…...

lua库介绍:数据处理与操作工具库 - leo

leo库简介 leo 模块的创作初衷旨在简化数据处理的复杂流程&#xff0c;提高代码的可读性和执行效率&#xff0c;希望leo 模块都能为你提供一系列便捷的工具函数&#xff0c;涵盖因子编码、多维数组创建、数据框构建、列表管理以及管道操作等功能。 要使用 Leo 模块&#xff0c;…...

逆向入门(1)C篇-正儿巴经的第1个实验

接触了这么久&#xff0c;第一次不是使用CV大法编写程序&#xff0c;认认真真的重头开始学习&#xff0c;记录一下找调试的感觉。 第一段代码&#xff0c;重温原码&#xff0c;反码和补码。 #include "stdafx.h"int main(int argc, char* argv[]) {char x -7;print…...

vue数据请求通用方案:axios的options都有哪些值

Axios 是一个基于 promise 的 HTTP 库&#xff0c;可以用在浏览器和 Node.js 中。 在使用 Axios 发送请求时&#xff0c;可以通过传递一个配置对象来指定请求的各种选项。 以下是一些常用的 Axios 配置选项及其说明&#xff1a; 1.url: &#xff08;必需&#xff09;请求的 …...

使用R语言绘制标准的中国地图和世界地图

在日常的学习和生活中&#xff0c;有时我们常常需要制作带有国界线的地图。这个时候绘制标准的国家地图就显得很重要。目前国家标准地图服务系统向全社会公布的标准中国地图数据&#xff0c;是最权威的地图数据。 今天介绍的R包“ggmapcn”&#xff0c;就是基于最新公布的地图…...

【PyTorch】迁移学习、数据增强

PyTorch官网 介绍 PyTorch 是一个开源的机器学习库&#xff0c;由 Facebook 的人工智能研究实验室开发。它提供了两种主要的功能&#xff1a;张量计算&#xff08;类似于 NumPy&#xff0c;但具有 GPU 加速&#xff09;和基于动态计算图的深度学习工具。PyTorch 因其灵活性、…...

Lucas-Kanade光流法详解

简介&#xff1a;个人学习分享&#xff0c;如有错误&#xff0c;欢迎批评指正。 光流&#xff08;Optical Flow&#xff09;描述的是图像序列中各像素点随时间的运动情况&#xff0c;是计算机视觉中的基本问题之一。光流问题涉及尝试找出一幅图像中的许多点在第二幅图像中移动的…...

python多张图片生成/合成gif

你可以通过调整帧率来提高GIF的流畅度。默认情况下,代码中的帧率为每秒1帧(fps=1)。我们可以增加这个值来加快动画速度。 下面是修改后的代码,将帧率从每秒1帧提高到每秒5帧(你可以根据需要进一步调整): 在这个版本中,我添加了一个可选参数fps,默认值为5帧每秒。你可…...

iptable限制多个端口出站

iptable限制多个端口出站 安装包 rootiptable:/home/bb# apt-get update rootiptable:/home/bb# apt-get -y install iptables iptables-restoreweb准备 rootweb:/home/bb/test-iptables# docker run -itd --name web -p 80:80 -v ./web1/index.html:/usr/share/nginx/html…...

springmvc--请求参数的绑定

目录 一、创建项目&#xff0c;pom文件 二、web.xml 三、spring-mvc.xml 四、index.jsp 五、实体类 Address类 User类 六、UserController类 七、请求参数解决中文乱码 八、配置tomcat,然后启动tomcat 1. 2. 3. 4. 九、接收Map类型 1.直接接收Map类型 &#x…...

Redis查询缓存

什么是缓存&#xff1f; 缓存是一种提高数据访问效率的技术&#xff0c;通过在内存中存储数据的副本来减少对数据库或其他慢速存储设备的频繁访问。缓存通常用于存储热点数据或计算代价高的结果&#xff0c;以加快响应速度。 添加Redis缓存有什么好处&#xff1f; Redis 基…...

双馈风电DFIG并网系统次转子侧变流器RSC抑制策略研究基于LADRC和重复控制的方法

风电装机容量的持续增长以及电力电子装置的大规模接入&#xff0c;导致电网强度降低&#xff0c;系 统运行特性发生深刻变化&#xff0c;严重威胁风电并网系统的安全稳定运行。因此本文以双馈风 电场经串补线路并网系统为研究对象&#xff0c;在深入分析双馈风电并网系统振荡…...

国产编辑器EverEdit - 使用技巧:变量重命名的一种简单替代方法

1 使用技巧&#xff1a;变量重命名的一种简单替代方法 1.1 应用场景 写过代码的都知道&#xff0c;经常添加功能的时候&#xff0c;是把别的地方的代码拷贝过来&#xff0c;改吧改吧&#xff0c;就能用了&#xff0c;改的过程中&#xff0c;就涉及到一个变量名的问题&#xff…...

Step3-VL-10B-Base一键部署避坑指南:解决403 Forbidden等常见网络错误

Step3-VL-10B-Base一键部署避坑指南&#xff1a;解决403 Forbidden等常见网络错误 最近在星图GPU平台上部署Step3-VL-10B-Base模型的朋友&#xff0c;是不是有不少人卡在了网络连接这一步&#xff1f;特别是那个让人头疼的403 Forbidden错误&#xff0c;明明跟着教程一步步操作…...

人工智能入门:图解Qwen3-ASR-0.6B语音识别模型的工作原理

人工智能入门&#xff1a;图解Qwen3-ASR-0.6B语音识别模型的工作原理 你有没有想过&#xff0c;当你对着手机说“嘿&#xff0c;Siri”或者“小爱同学”时&#xff0c;它到底是怎么听懂你说话的&#xff1f;这背后&#xff0c;就是语音识别技术在默默工作。今天&#xff0c;我…...

RMBG-2.0抠图工具功能体验:蒙版查看、原图对比、一键下载

RMBG-2.0抠图工具功能体验&#xff1a;蒙版查看、原图对比、一键下载 1. 为什么选择RMBG-2.0进行本地抠图&#xff1f; 在日常工作和生活中&#xff0c;我们经常需要处理图片背景去除的需求。无论是电商产品图、设计素材还是个人照片&#xff0c;一个高效、精准的抠图工具可以…...

**发散创新:基于Solidity的DAO组织智能合约设计与实战部署**在We

发散创新&#xff1a;基于Solidity的DAO组织智能合约设计与实战部署 在Web3时代&#xff0c;去中心化自治组织&#xff08;DAO&#xff09;已成为区块链应用的核心形态之一。它通过代码规则替代传统公司治理结构&#xff0c;实现社区驱动、透明可验证的决策机制。本文将深入探讨…...

STM32F407的USART DMA+空闲中断接收HC-05数据,这样写代码更稳定(附手机蓝牙助手通信协议解析)

STM32F407的USART DMA空闲中断接收HC-05数据&#xff0c;这样写代码更稳定&#xff08;附手机蓝牙助手通信协议解析&#xff09; 在物联网设备开发中&#xff0c;蓝牙通信的稳定性和效率往往是决定产品体验的关键因素。许多开发者在使用STM32F407与HC-05蓝牙模块进行通信时&…...

HTML图片怎么用Bitbucket Pipelines发布_Bitbucket自动构建HTML站点

Bitbucket Pipelines 不能直接托管 HTML 站点&#xff0c;仅支持构建后推送到 GitHub Pages、Netlify 或自有服务器&#xff1b;需配置 SSH 密钥权限&#xff0c;用 git push 到 gh-pages 分支或 rsync 部署&#xff0c;并注意资源路径与 base URL 适配。Bitbucket Pipelines 能…...

别再只用默认字体了!Windows C/C++程序员必知的CONSOLE_FONT_INFOEX结构体详解与避坑指南

Windows控制台字体定制&#xff1a;CONSOLE_FONT_INFOEX深度解析与实战技巧 在开发需要特殊显示效果的控制台应用时&#xff0c;默认的字体配置往往难以满足需求。想象一下这样的场景&#xff1a;你的日志系统需要高亮关键信息&#xff0c;或者你的命令行工具需要支持多语言字符…...

tqdm进度条库安装全攻略:从报错排查到高级用法详解

tqdm进度条库安装全攻略&#xff1a;从报错排查到高级用法详解 在Python开发中&#xff0c;处理长时间运行的任务时&#xff0c;一个直观的进度条不仅能提升用户体验&#xff0c;还能帮助开发者更好地监控程序执行状态。tqdm&#xff08;"taqaddum"的缩写&#xff0c…...

ESP32-C3 蓝牙应用实战:从零构建一个自定义 GATT 服务

1. 环境准备&#xff1a;搭建ESP32-C3开发环境 第一次接触ESP32-C3蓝牙开发的朋友可能会觉得无从下手&#xff0c;其实只要把开发环境搭好就成功了一半。我刚开始用Windows系统开发时踩过不少坑&#xff0c;后来发现用VSCode配合官方ESP-IDF工具链最省心。 首先需要安装乐鑫官方…...

加了领导微信,发现他从不发朋友圈。同事说把你屏蔽了。后来才知道没屏蔽任何人,只是不发!问他为什么,他说发什么都不对!

职场里最高级的“躺平”&#xff0c;是把朋友圈彻底清零。最近刷到一个扎心帖子&#xff0c;瞬间戳中了无数职场人的共鸣&#xff1a;加了领导微信&#xff0c;翻遍他的朋友圈&#xff0c;一条动态都没有。同事说“你被屏蔽了”&#xff0c;结果真相更现实——他只是彻底不发了…...