QThread创建多线程之moveToThread函数

参考《OpenCV3与Qt5计算机视觉应用开发》
请参阅本人写的上一篇博客,使用 QThread 子类化创建多线程的方法

2 使用 moveToThread 函数创建多线程

2.1 创建应用程序和新类

按照同样的方法创建应用程序和新的 C++ 类,命名为 VideoProcessor。注意,该类创建后,不需要从 QThread 类继承,而是保留从QObject类继承。(具体参考本人前一篇博客)

2.2 头文件声明信号和槽

将以下成员添加到 videoprocessor.h 文件中:
包含文件:

#include <QObject>
#include <QPixmap>
#include <QDebug>
#include <QMutex>
#include <QReadWriteLock>
#include <QSemaphore>
#include <QWaitCondition>
#include "opencv2/opencv.hpp"

信号和槽:

signals:
    void inDisplay(QPixmap pixmap);
    void outDisplay(QPixmap pixmap);

public slots:
    void startVideo();
    void stopVideo();

private:
    bool stopped;

代码解析: stopped 是标志符,用于帮助终止视频。声明的两个槽分别是用来启动和终止摄像头处理的。

2.3 修改代码

在 videoprocessor.cpp 文件中添加以下代码,这里不需要实现 run 函数,因为这不是 QThread 的子类:

void VideoProcessor::startVideo()
{
    using namespace cv;
    VideoCapture camera(0);
    Mat inFrame, outFrame;
    stopped = false;
    while(camera.isOpened() && !stopped)
    {
        camera >> inFrame;
        if(inFrame.empty())
            continue;

        bitwise_not(inFrame, outFrame);

        emit inDisplay(
                    QPixmap::fromImage(
                        QImage(
                            inFrame.data,
                            inFrame.cols,
                            inFrame.rows,
                            inFrame.step,
                            QImage::Format_RGB888)
                        .rgbSwapped()));

        emit outDisplay(
                    QPixmap::fromImage(
                        QImage(
                            outFrame.data,
                            outFrame.cols,
                            outFrame.rows,
                            outFrame.step,
                            QImage::Format_RGB888)
                        .rgbSwapped()));
    }
}

void VideoProcessor::stopVideo()
{
    qDebug() << Q_FUNC_INFO;
    stopped = true;
}

将下列代码添加至 MainWindow 的私有成员部分:

VideoProcessor *processor;

在 mainwindow.cpp 的构造函数中添加:

processor = new VideoProcessor();

processor->moveToThread(new QThread(this));

connect(processor->thread(),
        SIGNAL(started()),
        processor,
        SLOT(startVideo()));

connect(processor->thread(),
        SIGNAL(finished()),
        processor,
        SLOT(deleteLater()));

connect(processor,
        SIGNAL(inDisplay(QPixmap)),
        ui->inVideo,
        SLOT(setPixmap(QPixmap)));

connect(processor,
        SIGNAL(outDisplay(QPixmap)),
        ui->outVideo,
        SLOT(setPixmap(QPixmap)));

processor->thread()->start();

代码解析: 首先创建了 VideoProcessor 的实例。注意不应该直接调用 VideoProcessor 的 startVideo 函数,而应该通过将一个适当的信号连接到它进行调用,在这里,使用了它自己的线程的启动信号。
在 MainWindow 析构函数中添加以下代码用于正确终止该线程:

processor->stopVideo();
processor->thread()->quit();
processor->thread()->wait();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值