多进程界面开发-Qt试玩儿
一、概述
做客户端开发已经有好几个年头了,今天看到同事发了一篇关于富途牛牛的文章,核心思想就是想说,新版本的富途支持多进程架构了,效率大大提升啦,可以更好的里有多核CPU,提供软件运行效率。
听到这个消息,我不仅感叹,我靠,真的好牛逼。
但是心里又在默默的想,这个东西到底有什么好处,多进程写界面!!!从来没这么搞过呀,会不会有坑,到底比多线程好在了哪里?带着这个问题,从百度上看了几篇相关文章,主要是讲解了线程和进程的一些区别。当然了,最重要的还是目前的多进程架构的客户端已经开始变得多了起来。
其实很早以前就接触过多进程,支持自己好想也没有想那么多,一直对多进程架构的概念不是那么清晰。今天和同事聊了一些相关话题,感觉自己的知识面豁然开朗,要学习的东西好像还挺多。
看下面这张图,是任务管理器的应用截图,以前还真是没发现,居然我自己用的这么多应用都是多进程架构的。
我们平时最常用的Chrome浏览器,客户端版本微信,还有有道云笔记等等

有了这么多的多进程架构开发的客户端软件,难道说多进程开发已经是势在必行了?
说这么多,还不如来点儿实际的干货,这篇文章是我初步开始使用多进程开发段产品的初步尝试,有不对的地方欢迎大家指出,可以给出更好建议
二、效果展示
下面是我做的一个demo程序截图,测试程序中一共包含了4个使用场景,分别是:
- Qt嵌入系统自带计算机
- Qt嵌入系统自带记事本
- Qt调用系统ping命令,并收集结果
- Qt嵌入其他Qt可执行程序

大家可以先看看效果图,如果觉着有价值的可以继续往下看,下面我会分章节把四个事例进行讲解。
三、使用方法
首先需要清楚,我们是多进程界面开发,那么我们的exe启动后,势必是需要启动其他可执行程序的,并且把其他进程的界面嵌入到我们的窗口中来
1、启动外部进程
启动外部进程有多重方式,Qt使用比较习惯的同学可以直接使用QProcess类,这个类是Qt封装的一个跨平台的类。
启动方式可能像下面这样
QProcess * myProcess = new QProcess(this);
QStringList arguments;
myProcess->start("C:/Windows/System32/notepad.exe");
myProcess->waitForFinished(2000);
除过QProcess之外,Windows系统上我们还可以使用CreateProcess方法来创建进程。
QString cmd = "C:/Windows/system32/calc.exe";
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = true;
bool bRet = CreateProcess(
NULL,
(LPWSTR)cmd.toStdWString().c_str(),
NULL,
NULL,
FALSE,
CREATE_NEW_CONSOLE,
NULL,
NULL, &si, &pi);
2、创建Qt窗口
外部进程启动后,我们可以在任务管理器中找到启动的进程
接着我们需要使用SPY++工具进行查看外部进程的类名称和窗口名称,并使用FindWindow接口进程查找,找到这个进程的主窗口句柄后,嵌入到我们的程序中来。
类名和窗口名称查找过程可以参考外部进程嵌入到Qt进程界面这篇文章中的内容。
WId wid = (WId)FindWindow(QStringLiteral("Notepad").toStdWString().c_str()
, QStringLiteral("无标题 - 记事本").toStdWString().c_str());
QWindow * window = QWindow::fromWinId(wid);
if (window)
{
window->setFlags(window->flags() | Qt::CustomizeWindowHint | Qt::WindowTitleHint); //这边可以设置一下属性
QWidget * widget = QWidget::createWindowContainer(window, this, Qt::Widget);
}
如上代码所示,我们如果找到外部进程的主窗口句柄后,就可以使用Qt提供的createWindowContainer这个接口进行创建QWidget,并加入到我们的程序中来。
3、加入到主进程布局
外部进程被封装成为一个QWidget后,我们只需要加入到自己的布局中即可。
ui.verticalLayout_2->addWidget(widget);
接下来我们分别讲解不同场景下的多进程界面开发的简单使用
四、嵌入NotePad
第三小节已经把嵌入其他程序的流程大致说了一遍,这里我就不在详细说明了,直接给出具体代码。
代码中比较关键的有2个地方
- QProcess不能使用临时变量,要不然函数执行完毕notepad.exe进程也就退出了。
- FindWindow的两个参数,一个是类名,一个窗口标题栏名称,这两个信息都可以用个SPY++进行查找。
void EmbedCalculate::on_pushButton_2_clicked()
{
//创建进程
QString cmd = "C:/Windows/System32/notepad.exe";
QProcess * myProcess = new QProcess(this);
QStringList arguments;
myProcess->start(cmd);
myProcess->waitForFinished(2000);
WId wid = (WId)FindWindow(QStringLiteral("Notepad").toStdWString().c_str()
, QStringLiteral("无标题 - 记事本").toStdWString().c_str());
QWindow * window = QWindow::fromWinId(wid);
if (window)
{
window->setFlags(window->flags() | Qt::CustomizeWindowHint | Qt::WindowTitleHint); //这边可以设置一下属性
QWidget * widget = QWidget::createWindowContainer(window, this, Qt::Widget);
ui.verticalLayout_2->addWidget(widget);
}
}
五、调用Ping命令
ping命令使用场景主要是想展示主进程和外部进程是怎样通信的,虽然这个事例比较简单,但也算是两者之间发生了信息交换
子进程在执行完ping一个地址之后,会把得到的结果传递给主进程,主进程使用readAll函数全部读入到主进程中。
void EmbedCalculate::on_pushButton_3_clicked()
{
//创建进程
QProcess * myProcess = new QProcess(this);
connect(myProcess, static_cast<void (QProcess::*)(int)>(&QProcess::finished), this, [this, myProcess](int exitCode){
if (exitCode == 0) {
QTextCodec * gbkCodec = QTextCodec::codecForName("GBK");
QString result = gbkCodec->toUnicode(myProcess->readAll());
ui.textEdit->setText(result);
}
});
//myProcess->start("cmd.exe", QStringList() << "/c" << "ping www.baidu.com");
myProcess->start("cmd.exe", QStringList() << "/c" << "ping " + ui.lineEdit->text().trimmed());
myProcess->waitForFinished(2000);
···
}
六、嵌入其他QWidget窗体
虽然这个东西是最后讲的,但是这个才是重头戏,有了这个实验之后,我们以后的Qt多进程界面开发也可以进行投入正式环境了。
如下所示,ChildWidget外部程序的主窗体被我们嵌入到了EmbedCalculate这个进程的主界面上,突然觉着好神奇,给自己点赞,哈哈哈哈。

由于我这里的ChildWidget外部程序和EmbedCalculate主程序在一个目录中,因此cmd变量直接就指向了ChildWidget这个外部程序的名称。
其他部分的代码基本上就和前边几种使用场景差不多。
void EmbedCalculate::on_pushButton_4_clicked()
{
//创建进程
QString cmd = "ChildWidget.exe";
QProcess * myProcess = new QProcess(this);
QStringList arguments;
myProcess->start(cmd);
myProcess->waitForFinished(2000);
WId wid = (WId)FindWindow(QStringLiteral("Qt5QWindowIcon").toStdWString().c_str()
, QStringLiteral("ChildWidget").toStdWString().c_str());
QWindow * window = QWindow::fromWinId(wid);
if (window)
{
window->setFlags(window->flags() | Qt::CustomizeWindowHint | Qt::WindowTitleHint); //这边可以设置一下属性
QWidget * widget = QWidget::createWindowContainer(window, this, Qt::Widget);
ui.verticalLayout_3->addWidget(widget);
}
}
七、相关文章
以上的内容,基本上就是本篇文章的内容所有内容啦!序列化和反序列化功能基本完成,希望可以帮到大家。
![]() |
![]() |
很重要--转载声明
本站文章无特别说明,皆为原创,版权所有,转载时请用链接的方式,给出原文出处。同时写上原作者:朝十晚八 or Twowords
如要转载,请原文转载,如在转载时修改本文,请事先告知,谢绝在转载时通过修改本文达到有利于转载者的目的。
多进程界面开发-Qt试玩儿的更多相关文章
- C语言 C++1X STL QT免费视频课程 QT5界面开发美化 式样表 QML
C/C++/QT界面开发界面美化视频课程系列 课程1 C语言 C++1X STL QT免费视频课程 QT5界面开发美化 式样表 QML 返回顶部 课程1 C语言 C++1X STL QT免费视 ...
- 快速全面了解QT软件界面开发技术
快速全面了解QT软件界面开发技术 目录 前言 一. 学习QT可能的目的是什么? 只想体验一下QT? 当前的项目选择了用QT. 为将来做QT技术储备. 二. QT的核心技术优势是什么? QT在软 ...
- Objective C (iOS) for Qt C++ Developers(iOS开发,Qt开发人员需要了解什么?)
Qt/C++开发人员眼中的Obj-C 对于我们第一次自己定义iOS应用来说,对于来自Qt/C++开发人员来说,我不得不学习Objective-C相关语法与知识 为了让读者可以更easy理解这 ...
- [GUI]界面开发类库-Ribbon风格 [转]
[GUI]界面开发类库 如果我们不十分清楚需要什么样的界面风格及如何实现,请按以下两个步骤操作: (1) 搞清楚这种风格叫什么名字 (2) 查现有的比较著名的GUI库是否已有相 ...
- [GUI]界面开发类库
如果我们不十分清楚需要什么样的界面风格及如何实现,请按以下两个步骤操作: (1) 搞清楚这种风格叫什么名字 (2) 查现有的比较著名的GUI库是否已有相应的实现方案. (3) ...
- 嵌入式系统WinCE下应用程序GUI界面开发【转】
嵌入式系统WinCE下应用程序GUI界面开发 ByToradex 秦海 本文旨在介绍嵌入式系统在Wince下进行GUI应用程序开发可以选择的不同GUI开发框架(Framework),目前最常用的几种方 ...
- VS2010/MFC编程入门之五十三(Ribbon界面开发:为Ribbon Bar添加控件)
前面一节中鸡啄米为大家简单介绍了如何创建Ribbon样式的应用程序框架,本节教程就来初步讲讲怎样为Ribbon Bar添加Ribbon控件. VS2010为Ribbon界面开发提供了Ribbon De ...
- ESP32 LyraT音频开发板试玩(一):搭建开发环境
我是卓波,很高兴你来看我的博客. 系列文章: ESP32 LyraT音频开发板试玩(一):搭建开发环境 ESP32 LyraT音频开发板试玩(二):播放音乐 关于ESP32的开发环境搭建,官方有教程, ...
- 转:vc与界面开发之间的文章
[很好的一篇文章,很喜欢看同行的心路历程:http://www.vckbase.com/index.php/nv/444.html] 本屌丝在新春放假期间闲来无事,在各大编程论坛溜达了一圈.发现年前的 ...
随机推荐
- C# 使用外部别名
原文:C# 使用外部别名 版权声明:博客已迁移到 http://lindexi.gitee.io 欢迎访问.如果当前博客图片看不到,请到 http://lindexi.gitee.io 访问博客.本文 ...
- HTML5 的成长之路
html5历史 w3c从2008年提出html5的概念,目前html5的版本已经趋于稳定,也逐步得到了业界的认可和接受. 以前我们有一个疑问,HTML5与Flash究竟谁将在移动互联网时代称霸市场?这 ...
- Node child_process Study.2
child_process 模块用于新建子进程.子进程的运行结果存储在系统缓存之中,等到子进程运行结束之后,主进程再用回调函数读取子进程的运行结果 1.exec() exec 方法用于执行base命令 ...
- 至Linux-2.6.32编译内核ipset-6.23坎坷的经历
新的版本号ipset 上周,一名医生在儿童医院等待一段差距叫做数量.接受NetfilterPush信息的邮件列表,列表ipset最新6.23版本号的新功能,非常喜欢我现在需要的是,特别是timeout ...
- WPF 同一窗口内的多线程/多进程 UI(使用 SetParent 嵌入另一个窗口)
原文 WPF 同一窗口内的多线程/多进程 UI(使用 SetParent 嵌入另一个窗口) WPF 的 UI 逻辑只在同一个线程中,这是学习 WPF 开发中大家几乎都会学习到的经验.如果希望做不同线程 ...
- Open SSL 开发环境配置
Open SSL 开发环境配置 最后更新日期:2014-05-13 阅读前提:VisualStudio的基本使用.Cent OS的基本使用 环境: Windows 8.1 64bit英文版,Visua ...
- DataGridView 鼠标双击获得行列索引
如果是CellDoubleClick事件,可以在事件的参数e里获取列索引及行索引.也可以通过CurrentCell来获取当前选中的单元格的列索引及行索引.参考:private void dataGri ...
- ASP UserInfoList 方法1
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="UserInfoList.a ...
- JS 小鸟飞
<!DOCTYPE html><html lang="en" xmlns="http://www.w3.org/1999/xhtml"> ...
- SyncML是一平台无关的信息同步标准协议集
SyncML (Synchronization Markup Language)是一平台无关的信息同步标准协议集.分为SyncML数据传输协议(SyncML-DS)和SyncML设备管理协议(Sync ...