【Qt 多线程+opencv 读取和显示图像】

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
    • 工程需要Qt多线程+opencv 结合信号与槽读取和显示图像
  • 一、例程
  • 二、线程的开启和关闭
  • 三、判断线程是否还在运行
  • 总结


前言

提示:这里可以添加本文要记录的大概内容:

工程需要Qt多线程+opencv 结合信号与槽读取和显示图像

提示:以下是本篇文章正文内容,下面案例可供参考

一、例程

加入了信号与槽机制来处理多线程中的图像数据:

  1. 创建工作线程类:首先创建一个工作线程类,它从QThread继承并包含一个信号来发送图像数据。
class WorkerThread : public QThread
{Q_OBJECTpublic:void run() override {// 读取图像数据cv::Mat image = cv::imread("path_to_image.jpg");emit imageReady(image); // 发出信号,传递图像数据}signals:void imageReady(const cv::Mat &image); // 信号,传递图像数据
};
  1. 创建主窗口类:创建一个主窗口类,其中包含一个槽函数来接收工作线程发出的信号,并在主线程中显示图像。
class MainWindow : public QObject {Q_OBJECTpublic:MainWindow() {// 创建工作线程实例并启动WorkerThread *thread = new WorkerThread();connect(thread, &WorkerThread::imageReady, this, &MainWindow::displayImage); // 连接信号和槽thread->start();}public slots:void displayImage(const cv::Mat &image) {// 在主线程中显示图像cv::imshow("Image Display", image);cv::waitKey(0); // 等待用户按键,保持显示状态}
};
  1. 连接信号和槽:在主窗口类的构造函数中,我们使用connect函数将工作线程的imageReady信号连接到主窗口类的displayImage槽。这样,当工作线程完成图像读取并发出imageReady信号时,displayImage槽函数将被自动调用。
  2. 主函数:最后,在主函数中创建主窗口类的实例并运行应用程序。
int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);MainWindow mainWindow;return a.exec();
}

这个例子展示了如何使用Qt的信号与槽机制在多线程环境中安全地处理图像数据。工作线程读取图像数据并通过信号发送,主线程通过槽函数接收并显示图像,确保了线程安全和正确的同步。

二、线程的开启和关闭

在Qt中,线程的开始和关闭可以通过以下方式实现:

  1. 启动线程

    • 定义工作类:通常,你会创建一个类来继承QThread,并重写其run()函数。在这个函数中,你可以定义线程应该执行的代码。
    • 实例化并启动线程:在主函数中,你可以实例化这个工作类,并调用其start()方法来启动线程。
  2. 关闭线程

    • 优雅地关闭线程:在线程的run()函数中,你可以使用一个标志变量(如volatile bool m_toStop)来判断是否需要从run()函数返回。在线程运行的过程中,你可以检查这个标志变量的值来决定是否需要停止线程。当线程需要停止时,设置这个标志变量为true。在线程的run()函数结束时,线程自然死亡。
    • 强制关闭线程:如果需要立即停止线程,可以使用thread->quit()thread->wait()方法。前者会尝试停止正在运行的线程,后者会等待线程结束。

请注意,关闭线程时需要确保线程已经完成了其任务,避免资源泄露或数据不一致的问题。同时,处理多线程时需要考虑到线程同步和互斥的问题,确保线程安全地访问共享资源。

以下是一个使用Qt多线程的详细例程:

#include <QCoreApplication>
#include <QThread>
#include <QDebug>
#include <QTimer>class Worker : public QThread
{Q_OBJECTpublic:Worker() {}void run() override {int i = 0;while (!isInterruptionRequested()) {qDebug() << "Thread is running" << ++i;QThread::sleep(1); // 模拟耗时操作}}
};class MainWindow : public QObject {Q_OBJECT
public:MainWindow(QObject *parent = nullptr) : QObject(parent) {Worker *worker = new Worker();connect(worker, &Worker::started, this, &MainWindow::onWorkerStarted);connect(worker, &Worker::finished, this, &MainWindow::onWorkerFinished);worker->start(); // 启动线程}public slots:void onWorkerStarted() { qDebug() << "Worker started"; }void onWorkerFinished() { qDebug() << "Worker finished"; }
};int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);MainWindow mainWindow;return a.exec();
}

这个例程中,我们创建了一个Worker类来继承QThread,并重写了其run()函数。在run()函数中,我们使用一个循环来模拟线程的持续运行,并每隔1秒打印一条消息。我们还定义了一个MainWindow类,其中包含一个工作线程的实例。通过连接工作线程的startedfinished信号到主窗口类的槽函数,我们可以在工作线程开始和结束时执行特定的操作。最后,在主函数中,我们创建了主窗口类的实例并运行应用程序。

三、判断线程是否还在运行

在Qt中,判断线程是否仍在运行可以通过检查线程的状态来实现。Qt提供了QThread::isRunning()函数,该函数返回一个布尔值,表示线程是否正在运行。

以下是一个简单的示例代码,演示如何使用isRunning()函数来判断线程是否仍在运行:

#include <QCoreApplication>
#include <QThread>
#include <QDebug>class MyThread : public QThread {Q_OBJECT
public:MyThread(QObject *parent = nullptr) : QThread(parent) {}void run() override {// 线程执行的代码qDebug() << "Thread started";// ...// 线程结束前的操作qDebug() << "Thread finished";exit(0); // 结束线程}
};int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);MyThread thread;thread.start(); // 启动线程// 检查线程是否仍在运行while (thread.isRunning()) {qDebug() << "Thread is still running";QThread::sleep(1); // 等待一段时间,避免过度消耗CPU资源}qDebug() << "Thread has finished";return a.exec();
}

在上面的代码中,我们创建了一个自定义的MyThread类,它继承自QThread。在run()函数中,我们定义了线程要执行的代码。在主函数中,我们创建了MyThread的实例,并调用其start()方法来启动线程。然后,我们使用一个while循环来检查线程是否仍在运行。如果线程仍在运行,循环会继续执行并打印消息。在每次循环迭代之间,我们使用QThread::sleep(1)来等待一段时间,以避免过度消耗CPU资源。当线程结束时,isRunning()函数将返回false,循环将停止执行。最后,我们打印一条消息表示线程已经完成。

总结

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/662727.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【2024美赛】A题(中英文):资源可用性与性别比例Problem A: Resource Availability and Sex Ratios

【2024美赛】A题&#xff08;中英文&#xff09;&#xff1a;资源可用性与性别比例Problem A: Resource Availability and Sex Ratios 写在最前面2024美赛翻译 —— 跳转链接 中文赛题问题A&#xff1a;资源可用性与性别比例需要检查的问题包括&#xff1a; 英文赛题Problem A:…

【HarmonyOS应用开发】Web组件的使用(十三)

文章末尾含&#xff1a;Web组件抽奖案例&#xff08;ArkTS&#xff09;-示例源码下载 Web组件的使用 一、概述 相信大家都遇到过这样的场景&#xff0c;有时候我们点击应用的页面&#xff0c;会跳转到一个类似浏览器加载的页面&#xff0c;加载完成后&#xff0c;才显示这个页…

数据结构 归并排序详解

1.基本思想 归并排序&#xff08;MERGE-SORT&#xff09;是建立在归并操作上的一种有效的排序算法,该算法是采用分治法&#xff08;Divide andConquer&#xff09;的一个非常典型的应用。 将已有序的子序列合并&#xff0c;得到完全有序的序列&#xff0c;即先使每个子序列有序…

05:容器镜像技术揭秘|发布容器服务器|私有镜像仓库

容器镜像技术揭秘&#xff5c;发布容器服务器&#xff5c;私有镜像仓库 创建镜像使用commit方法创建自定义镜像。Dockerfile打包镜像创建apache服务镜像制作 php 镜像 微服务架构创建nginx镜像 发布服务通过映射端口发布服务容器共享卷 docker私有仓库 创建镜像 使用commit方法…

elk之基本crud

写在前面 本文看下工作中用的最多的CRUD。让我们一起来做一个帅帅的CRUD BOY吧&#xff01;&#xff01;&#xff01; 1&#xff1a;基本操作 Create 格式1(指定ID)&#xff1a;PUT 索引名称/_create/文档ID {文档json} 格式2&#xff08;不指定ID&#xff09;:POST 索引名称…

【Algorithms 4】算法(第4版)学习笔记 03 - 1.3 背包、队列和栈

文章目录 前言参考目录学习笔记0&#xff1a;预热1&#xff1a;栈1.1&#xff1a;栈的链表实现1.1.1 代码实现1.2&#xff1a;栈的数组实现1.2.1&#xff1a;定容栈1.2.2&#xff1a;可调整大小数组1.2.3&#xff1a;代码实现1.3&#xff1a;链表与数组的取舍2&#xff1a;队列…

《吐血整理》高级系列教程-吃透Fiddler抓包教程(37)-掌握Fiddler中Fiddler Script用法,你会有多牛逼-下篇

1.简介 Fiddler是一款强大的HTTP抓包工具&#xff0c;它能记录所有客户端和服务器的http和https请求&#xff0c;允许你监视&#xff0c;设置断点&#xff0c;甚至修改输入输出数据. 使用Fiddler无论对开发还是测试来说&#xff0c;都有很大的帮助。Fiddler提供的功能基本上能满…

【Python】Python异常处理(一)

使用特定的异常 捕获特定的异常类似于使用专门的工具来完成不同的任务。 捕获特定的异常类型至关重要&#xff0c;而不是依赖于通用的包罗万象的语句。 这种做法使你能够区分各种错误并提供准确的错误消息&#xff0c;从而更有效地识别和解决问题。 try:# 可能引发特定异常的…

【LVGL环境搭建】

LVGL环境搭建 win模拟器环境搭建一.二.三.四.五. Ubuntu模拟器环境搭建一. 前置准备二. 下载LVGL Source code&#xff1a;三. 安装sdl2&#xff1a;四. 开启VScode执行五. 安装扩展套件六. 按F5执行七. 执行结果 win模拟器环境搭建 一. 二. 三. 四. 五. Ubuntu模拟器环境…

基于muduo网络库开发服务器程序和CMake构建项目 笔记

跟着施磊老师做C项目&#xff0c;施磊老师_腾讯课堂 (qq.com) 一、基于muduo网络库开发服务器程序 组合TcpServer对象创建EventLoop事件循环对象的指针明确TcpServer构造函数需要什么参数,输出ChatServer的构造函数在当前服务器类的构造函数当中,注册处理连接的回调函数和处理…

介绍msvcp140.dll丢失的解决方法的关键方法,关于msvcp140.dll文件

在使用电脑过程中&#xff0c;我们有时会遇到一些错误提示&#xff0c;比如msvcp140.dll丢失的问题。而这个问题的解决方法对于用户来说就显得尤为重要。本文旨在为大家简要介绍解决msvcp140.dll丢失问题的关键方法。 一.msvcp140.dll丢失的解决方法的详细步骤教程 重新安装相…

Leetcode 热门百题斩(第二天)

介绍 针对leetcode的热门一百题&#xff0c;解决大多数实习生面试的基本算法题。通过我自己的思路和多种方法&#xff0c;供大家参考。 1.两数之和&#xff08;题号&#xff1a;1) 方法一 最先想到的就是两个for去遍历匹配。 class Solution {public int[] twoSum(int[]…

C语言标准库所有字符串操作库函数汇总

以下是C语言标准库中字符串操作相关的API列表&#xff0c;这些函数通常在 <string.h> 头文件中定义&#xff1a; 1. strlen - 计算字符串长度&#xff0c;不包括结尾的空字符\0&#xff1a; size_t strlen(const char *str); 2. strcpy - 复制字符串&#xff1a; c…

Spring Bean 生命周期常见错误

虽然说 Spring 容器上手简单&#xff0c;可以仅仅通过学习一些有限的注解&#xff0c;即可达到快速使用的目的。但在工程实践中&#xff0c;我们依然会从中发现一些常见的错误。尤其当你对 Spring 的生命周期还没有深入了解时&#xff0c;类初始化及销毁过程中潜在的约定就不会…

HAL库配置片内FLASH读写

一、FLASH简介 不同型号的 STM32F40xx/41xx&#xff0c;其 FLASH 容量也有所不同&#xff0c;最小的只有 128K 字节&#xff0c;最大 的则达到了 1024K 字节。我们的探索者开发板选择的是 STM32F407ZGT6 的 FLASH 容量为 1024K 字节。 主存储器&#xff0c;存放代码和数据常数&…

在ESP32上使用MicroPython

ESP32是一款非常好用的物联网芯片&#xff0c;MicroPython可以充分利用ESP32的各种资源,本文会对MicroPython在ESP32上的应用进行说明&#xff0c;包括初始使用、提示信息、使用 WebREPL、连接网络与互联网通信、使用硬件外设以及控制外部组件等等。 准备开发板 在进行下面的…

PHP的线程安全与非线程安全模式选哪个

曾经初学PHP的时候也很困惑对线程安全与非线程安全模式这块环境的选择&#xff0c;也未能理解其中意。近来无意中看到一个教程对线程安全&#xff08;饿汉式&#xff09;&#xff0c;非线程安全&#xff08;懒汉式&#xff09;的描述&#xff0c;虽然觉得现在已经能够很明了透彻…

openlayers地图自定义图标打点(二)

1.效果 2.代码 结构,地图初始化同上篇 <template><div class"container">//地图结构<div id"map"></div></div> </template><script> //引入依赖项 import { Map, View } from ol import TileLayer from ol/l…

模板讲解之进阶

在之前的C入门的博客中我们就学习到了模板初阶&#xff0c;今天我们来学习模板的进阶&#xff0c;以便于更好地将模板运用到代码中 非类型模板参数 模板参数分类类型形参与非类型形参。 类型形参即&#xff1a;出现在模板参数列表中&#xff0c;跟在class或者typename之类的…

2024美赛C题思路/代码:网球中的动量

美赛直播b站&#xff0c;提前关注&#xff1a;川川菜鸟 美赛辅导预定&#xff1a;美赛服务 去年美赛C题&#xff1a;2023美赛C题 题目翻译 背景 在2023年温布尔登男子单打决赛中&#xff0c;20岁的西班牙新星阿尔卡拉兹击败了36岁的诺瓦克德约科维奇。这是德约科维奇自201…