做橡胶的网站/网站seo服务商
QT 界面编程中使用协程
- 一、概述
- 二、集成
- 2.1、编译 Acl
- 2.2、将 Acl 库集成到 QT 项目中
- 2.3、开始编写代码
- 2.3.1、QT 程序初始化时初始化 Acl 协程
- 2.3.2、在界面中创建协程
- 2.3.3、界面程序退出前需要停止协程调度
- 2.3.4、在界面线程中下载数据
- 2.3.5、在协程中延迟创建窗口
- 2.4、效果展示
- 2.5、小结
一、概述
人们在谈论协程编程时,往往与编写命令行网络程序有关,如编写网络客户端与网络服务器程序,很少涉及到客户端 UI 相关的界面编程。Acl 协程库是支持在 Windows 下的 UI 界面编程的,因为 Acl 协程的事件引擎支持了界面消息传递过程。最近学习了一下 QT UI 编程,轻松将 Acl 协程与 QT UI 集成在一起,从而实现了 QT 界面协程化,使开发人员在使用 QT 编写界面程序时,编写网络模块变得非常简单。
本文结合 Acl 中 lib_fiber/samples-gui/QtFiber 示例,演示了如何将 Acl 协程功能集成到 QT 界面中,实现了网络模块与界面模块的融合。
二、集成
2.1、编译 Acl
目前 QT IDE 还无法直接使用 Acl 里的 CMakeLists.txt 文件编译 ACL,可以借助于 VC2019 打开 Acl 里的 acl_cpp_vc2019.sln 工程编译 Acl 五个库的动态库,分别为:lib_acl.dll, lib_protocol.dll, lib_acl_cpp.dll, libfiber.dll, libfiber_cpp.dll 及静态导出库:lib_acl.lib, lib_protocol.lib lib_acl_cpp.lib, libfiber.lib, libfiber_cpp.lib。
2.2、将 Acl 库集成到 QT 项目中
参考 lib_fiber/samples-gui/QtFiber/CMakeLists.txt 文件,将 Acl 库的头文件包含进去,如下:
set(acl_path ../../..)include_directories(${acl_path}/lib_acl/include${acl_path}/lib_acl_cpp/include${acl_path}/lib_fiber/c/include${acl_path}/lib_fiber/cpp/include
)
然后设定编译条件:
add_definitions("-DACL_DLL""-DACL_CPP_DLL""-DHTTP_DLL""-DICMP_DLL""-DSMTP_DLL""-DFIBER_CPP_DLL""-D_CRT_SECURE_NO_WARNINGS""-D_WINSOCK_DEPRECATED_NO_WARNINGS"
)
添加库到工程中,如下:
if (CMAKE_BUILD_TYPE STREQUAL "RELEASE")set(acl_libs_path ${CMAKE_CURRENT_SOURCE_DIR}/../../../x64/ReleaseDll)
else()set(acl_libs_path ${CMAKE_CURRENT_SOURCE_DIR}/../../../x64/DebugDll)
endif()set(lib_all ${acl_libs_path}/libfiber_cpp.lib${acl_libs_path}/lib_acl_cpp.lib${acl_libs_path}/lib_protocol.lib${acl_libs_path}/lib_acl.lib${acl_libs_path}/libfiber.lib)target_link_libraries(QtFiber PRIVATE Qt5::Widgets ${lib_all} Ws2_32)add_custom_command(TARGET ${PROJECT_NAME} POST_BUILDCOMMAND ${CMAKE_COMMAND} -E copy_if_different"${acl_libs_path}/libfiber_cpp.dll""${acl_libs_path}/libfiber.dll""${acl_libs_path}/lib_acl_cpp.dll""${acl_libs_path}/lib_acl.dll""${acl_libs_path}/lib_protocol.dll"$<TARGET_FILE_DIR:${PROJECT_NAME}>
)
2.3、开始编写代码
经过摸索研究,想要集成 Acl 协程到 QT UI 程序中,需要采用以下方法(主要是协程的初始化及退出):
2.3.1、QT 程序初始化时初始化 Acl 协程
在调用 QT APP exec() 前,需要先调用 Acl 协程初始化过程,如下:
static void startupCallback() {acl::fiber::schedule_gui(); // Won't return until schedule finished.
}void main() {QApplication app(argc, argv);MainWindow w;w.show();QTimer::singleShot(0, startupCallback);app.exec();
}
可以看出,在调用 app.exec() 前注入了启动函数 startupCallback(),在里面启动了 acl 在界面模式下的协程调度过程 acl::fiber::schedule_gui(),该方法将进入界面消息循环过程,直到协程调度停止后才会返回。
2.3.2、在界面中创建协程
一旦协程调度器启动,就可以创建并运行协程了,可以在主界面上添加一个按钮,当点击该按钮后的处理函数中便可以创建并启动一个协程。比如在例子中,点击 “Start fiber server” 按钮,在处理函数 MainWindow::onStartServer()
中,可以创建一个网络监听服务器,如下:
void MainWindow::onStartServer() {...server_ = new fiber_server("127.0.0.1", 9001, this);server_->start();...
}
这样在界面里就创建了一个 TCP 监听协程,当有连接连接监听地址时,在监听协程里便可以创建一个客户端连接处理协程进行处理,如下:
while (true) {SOCKET conn = socket_accept(sock);if (conn == INVALID_SOCKET) {break;}acl::fiber* fb = new fiber_echo(conn);fb->start();}
上面例子的客户端协程启动后,便可以进行网络 IO 读写,如下:
char buf[8192];while (true) {int ret = acl_fiber_recv(conn_, buf, sizeof(buf) - 1, 0);if (ret == -1) {break;}buf[ret] = 0;if (acl_fiber_send(conn_, buf, ret, 0) != ret) {break;}}
2.3.3、界面程序退出前需要停止协程调度
必须保证在界面程序退出前停止协程调度器,否则界面程序无法正常退出,该步骤也非常重要。可以在主界面处理类里重载基类的 void closeEvent(QCloseEvent *event);
方法,在该方法里停止协程调度器,如下:
void MainWindow::closeEvent(QCloseEvent *event) {acl::fiber::schedule_stop(); // 停止协程调度器event->accept(); // 接受关闭事件
}
2.3.4、在界面线程中下载数据
点击主界面中点击HTTP下载按钮,在事件处理函数中创建协程从后端HTTP服务器下载数据,过程如下:
void MainWindow::onUrlGet() {...go[this] {const char *url = "http://www.baidu.com/";acl::http_request req(url);if (!req.request(nullptr, 0)) {printf("Send HTTP request failed\r\n");return;}acl::string body;if (!req.get_body(body)) {printf("Get HTTP body error\r\n");return;}qDebug() << "Got body:" << body.c_str();...};
}
2.3.5、在协程中延迟创建窗口
如果想某个窗口延迟创建,不必借助定时器,直接在协程中就可以轻松实现:
void MainWindow::delayCreate() {go[this] {acl::fiber::delay(5000); // 休眠 5 秒InputDialog dialog(this);dialog.exec();};qDebug() << "Fiber was created to create one window after a while";
}
2.4、效果展示
编译运行 acl/lib_fiber/samples-gui/QtFiber/ 工程,可以得到以下运行界面:
在前面窗口中,右边请求HTTP服务器时的HTTP请求头,右连接为后端服务器返回的HTTP响应头,该下载过程中在协程中进行,运行结果显示在主界面上;
- 窗口下方的进度条为客户端协程与服务端协程交互时的交互进度展示。
2.5、小结
以上便是如何编译集成 Acl 协程到 QT 界面程序的方法,主要的要点是:
- 需要使用 vc2019 编译 Acl 的动态库,并集成至 QT 界面程序的工程文件中;
- 编程时需要注意:
- 在启动 QT (即调用 app.exec())前,需要先启动 Acl 协程调度器;
- 在主界面类里需要重载基类关闭虚方法
closeEvent()
,并在该方法里停止 Acl 协程调度器; - 因为协程运行在界面的线程空间中,所以可以在协程中直接操作界面上的窗口对象,避免了线程之间的消息传递过程。
注: Acl库下载:https://github.com/acl-dev/acl/
相关文章:

QT 界面编程中使用协程
QT 界面编程中使用协程 一、概述二、集成2.1、编译 Acl2.2、将 Acl 库集成到 QT 项目中2.3、开始编写代码2.3.1、QT 程序初始化时初始化 Acl 协程2.3.2、在界面中创建协程2.3.3、界面程序退出前需要停止协程调度2.3.4、在界面线程中下载数据2.3.5、在协程中延迟创建窗口 2.4、效…...

macOS 开发环境配置与应用开发
✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…...

第13讲 实践:设计SLAM系统
设计一个视觉里程计,理解SLAM软件框架如何搭建,理解视觉里程计设计容易出现的问题以及解决方法。 目录 1、工程目标 2、工程框架 3、实现 附录 1、工程目标 实现一个精简版的双目视觉里程计。由一个光流追踪的前端和一个局部BA的后端组成。 2、工程…...

NeRF2: Neural Radio-Frequency Radiance Fields 笔记
任务:用 NeRF 对无线信号的传播进行建模,建模完成后可以用NeRF网络生成新位置下的信号。生成的信号用于指纹定位、信道估计等下游任务。 核心思路 在视觉 NeRF 的基础上,根据无线信号的特点修改了隐式场模型、渲染函数,网络的输…...

以太网交换安全:MAC地址表安全
一、MAC地址表安全 MAC地址表安全是网络安全中的一个重要方面,它涉及到网络设备的MAC地址表的管理和保护。以下是对MAC地址表安全的详细介绍: (1)基本概念 定义:MAC地址表是网络设备(如交换机࿰…...

CSS综合页布面局案例
写的比较一般,如果想要参考可以点击链接。 CSS综合案例(登录页面)资源-CSDN文库 引言: 我们学习CSS和HTML都是为了想要做一个网页布局,但是每逢上手可能就会需要查阅很多语言,我觉得是没有什么问题的,熟能生巧,编程是需要练的,但是写网页的时候需要实现某个效果时需…...

低代码可视化-UniApp二维码可视化-代码生成器
市面上提供了各种各样的二维码组件,做了一简单的uniapp二维码组件,二维码实现依赖davidshimjs/qrcodejs。 组件特点 跨浏览器支持:利用Canvas元素实现二维码的跨浏览器兼容性,兼容微信小程序、h5、app。 无依赖性:QR…...

Electron 使用 Nodemon 配置自动重启
在Electron项目中,每次修改了代码都需要手动关闭应用,再执行npm start重启应用。 Nodemon 是一个非常实用的工具,主要用于在开发 Node.js 应用时自动监测文件的变化并重新启动服务器。 安装nodemon 开发环境安装nodemon: npm …...

JVM和GC监控技术
一、监控技术简介 JVM是什么?项目里面有JVM吗?JVM跟Tomcat有什么关系?为什么需要去分析JVM? 1. JVM(全称:Java Virtual Machine),Java虚拟机 是Java程序运行的环境,它是一个虚构的计算机&…...

Android中级控件
文章目录 图形定制1.图形Drawable2.形状图像3.九宫格图片4.状态列表图形 选择按钮1.复选框CheckBox2.开关按钮Switch3.单选按钮 文本输入1.编辑框EditText2.焦点变更监听器3.文本变化监听器 对话框1.提醒对话框2.日期对话框DatePickerDialog3.时间对话框TimePickerDialog 图形定…...

WebSocket消息防丢ACK和心跳机制对信息安全性的作用及实现方法
WebSocket消息防丢ACK和心跳机制对信息安全性的作用及实现方法 在现代即时通讯(IM)系统和实时通信应用中,WebSocket作为一种高效的双向通信协议,得到了广泛应用。然而,在实际使用中,如何确保消息的可靠传输…...

生信初学者教程(二十二):Boruta+RF筛选候选标记物
文章目录 介绍加载R包导入数据准备数据机器学习特征筛选数据分割基础模型Boruta特征筛选调参最终分类模型测试集验证标记基因输出结果总结介绍 采用了Boruta结合 RF(Random Forest) 的方法,对差异基因(参考 @sec-different-limma) 进行了特征筛选。通过这种方法,能够从大…...

JVM Class类文件结构
国庆节快乐 2024年10月2日17:49:22 目录 前言 magic 数 文件版本 使用JClassLib观察class文件 一般信息 接口 常量池 字段 方法 常量池计数器 常量池 类型 CONSTANT_Methodref_info CONSTANT_Class_info 类型结构总表 访问标志 类索引, …...

解决 GitHub 文件大小限制的问题
要解决 GitHub 文件大小限制的问题,可以使用 Git Large File Storage (Git LFS)。以下是设置步骤: 安装 Git LFS: 对于 macOS:brew install git-lfs对于 Windows:从 Git LFS官网 下载并安装。 初始化 Git LFSÿ…...

wordpress源码资源站整站打包32GB数据,含6.7W条资源数据
源码太大了,足足32gb,先分享给大家。新手建立资源站,直接用这个代码部署一下,数据就够用了。辅助简单做下seo,一个新站就OK了。 温馨提示:必须按照顺序安装 代码下载...

金融领域的人工智能——Palmyra-Fin 如何重新定义市场分析
引言 DigiOps与人工智能 正在改变全球各行各业,并带来新的创新和效率水平。人工智能已成为金融领域的强大工具,为市场分析、风险管理和决策带来了新方法。金融市场以复杂性和快速变化而闻名,人工智能处理大量数据并提供清晰、可操作的见解的…...

STL--string类
我们从这篇文章之后就正式开始学习STL的string,字面看起来是不是像C语言里面的字符串之类的处理方法,是的,C里面也是对字符串的一些处理函数,但是C有很多这样的函数,给大家推荐一个网站 ,这个网站是C的官网…...

iptables 的NDAT报错bash: 9000: command not forward
外网主机设置: iptables -t nat -A PREROUTING -d 192.168.3.51 -p tcp --dport 9000 -j DNAT --to-destination 192.168.3.61:22 本地shell连接: PS C:> ssh root192.168.3.51 9000 显示如下操作: PS C:> ssh root192.168.3.51 9000…...

快速了解:MySQL InnoDB和MyISAM的区别
目录 一、序言二、InnoDB和MyISAM对比1、InnoDB特性支持如下2、MyISAM特性支持如下 三、两者核心区别1、事务支持2、锁机制3、索引结构4、缓存机制5、故障恢复6、使用场景 一、序言 在MySQL 8.0中,InnoDB是默认的存储引擎。除了InnoDB,MySQL还支持其它的…...

TI DSP TMS320F280025 Note14:模数转换器ADC原理分析与应用
TMS320F280025 模数转换器ADC原理分析与应用 ` 文章目录 TMS320F280025 模数转换器ADC原理分析与应用逐次比较型ADC和双积分型ADC工作原理逐次比较型 ADC双积分型 ADC280025ADCADC原理分析ADC时钟SOCSOC内部原理ADC触发方式ADC采集(采样和保持)窗口通道寄生电容基准电压发生器模…...

【C++前缀和】2845. 统计趣味子数组的数目|2073
本文涉及的基础知识点 C算法:前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 LeetCode 2845. 统计趣味子数组的数目 难度分:2073 给你一个下标从 0 开始的整数数组 nums ,以及整数 modulo 和整数 k 。 请你找出并统计数组…...

C++入门基础 (超详解)
文章目录 前言1. C关键字2. C的第一个程序3. 命名空间3.1 namespace的定义3.2 命名空间的嵌套3.3 命名空间使用3.4 查找优先级总结 4. C输入和输出4.1 标准输入输出 (iostream库)4.2 文件输入输出 (fstream库)4.3 字符串流 (sstream库)4.4 C格式化输出4.5 std::endl和\n的区别 …...

docker零基础入门教程
注意 本系列文章已升级、转移至我的自建站点中,本章原文为:Docker入门 目录 注意1.前言2.docker安装3.docker基本使用4.打包docker镜像5.docker进阶 1.前言 如果你长期写C/C代码,那你应该很容易发现C/C开源项目存在的一个严重问题ÿ…...

【Java SE 题库】移除元素(暴力解法)--力扣
🔥博客主页🔥:【 坊钰_CSDN博客 】 欢迎各位点赞👍评论✍收藏⭐ 目录 1. 题目 2. 解法(快慢“指针”) 3. 源码 4. 小结 1. 题目 给你一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素。元素的顺…...

linux文件编程_进程
1. 进程相关概念 面试中关于进程,应该会问的的几个问题: 1.1. 什么是程序,什么是进程,有什么区别? 程序是静态的概念,比如: 磁盘中生成的a.out文件,就叫做:程序进程是…...

java NIO实现UDP通讯
NIO Udp通讯工具类 import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.DatagramChannel; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.util.Iterator;impo…...

ffmpeg如何实现视频推流?
FFmpeg是一个强大的多媒体框架,用于处理视频和音频数据。它包括了libavcodec(用于解码和编码)、libavformat(用于格式转换)、libavutil(提供一些辅助工具和函数)、libavfilter(用于音视频过滤)等多个库。 以下这些都是FFmpeg的特性 FFmpeg支持大量的音视频编解码器&…...

【HTML5】html5开篇基础(3)
1.❤️❤️前言~🥳🎉🎉🎉 Hello, Hello~ 亲爱的朋友们👋👋,这里是E绵绵呀✍️✍️。 如果你喜欢这篇文章,请别吝啬你的点赞❤️❤️和收藏📖📖。如果你对我的…...

echarts实现3D柱状图(视觉层面)根据博主改编
https://blog.csdn.net/weixin_57798646/article/details/131067725 这是原贴 在这个基础上我需要实现 一根柱子 代码如下 <!DOCTYPE html> <html lang"en" style"height: 100%"><head><meta charset"utf8"> </hea…...

【一篇文章理解Java中多级缓存的设计与实现】
文章目录 一.什么是多级缓存?1.本地缓存2.远程缓存3.缓存层级4.加载策略 二.适合/不适合的业务场景1.适合的业务场景2.不适合的业务场景 三.Redis与Caffine的对比1. 序列化2. 进程关系 四.各本地缓存性能测试对比报告(官方)五.本地缓存Caffine如何使用1. 引入maven依…...