1. 程式人生 > 其它 >VS+Qt多執行緒開發中傳引數的問題

VS+Qt多執行緒開發中傳引數的問題

需求:子執行緒程式採集影象,視窗執行緒實時顯示影象

平臺:VS2017+QT4.5

實現方法:

1建立繼承QObject的ImageContinuous類,實現連續採集影象

2主執行緒內建立ImageContinuous的物件指標,同時建立QThread類的物件指標

3子執行緒內建立槽函式,實現連續採集功能

4子執行緒內建立訊號,像主執行緒傳送訊號,訊號帶引數cv::Mat型;

5主執行緒建立訊號start,傳送start觸發子執行緒的連續採集槽函式;

6連續採集槽函式每採集一張圖,向主執行緒傳送一次訊號,訊號包含影象內容

7主執行緒接收到子執行緒訊號,更新ui影象顯示

子執行緒類程式碼,標頭檔案

#pragma once
#include <qobject.h>
#include "MvcCamera.h"
class ImageContinuous :    public QObject
{
    Q_OBJECT
public:
    //explicit ImageContinuous(QObject *parent = 0) : QObject(parent) {}
    ImageContinuous();
    ~ImageContinuous();
public slots:
    void getImage(MvcCamera &m_camera);
signals:
    
void imageInfo(cv::Mat temp); };

子執行緒類程式碼,原始檔

#include "ImageContinuous.h"
#include "QThread.h"
#include <QDebug>
ImageContinuous::ImageContinuous()
{
}

ImageContinuous::~ImageContinuous()
{
}

void ImageContinuous::getImage(MvcCamera &m_camera)
{
    //QTimer::singleShot();//此函式可用,後期研究

    while
(true) { cv::Mat m_image = m_camera.CaptureOneImage(); cv::Mat m_imageToShow_1; //原始解析度,2048*1536,縮小512*384 cv::resize(m_image, m_imageToShow_1, cv::Size(m_image.cols / 4, m_image.rows / 4), 0, 0, CV_INTER_LINEAR); emit imageInfo(m_imageToShow_1); QThread::msleep(30); //qDebug() << "current threadID:" << QThread::currentThread() << endl; } }

主執行緒內部分程式碼,類的例項定義

private:
    ImageContinuous *m_imageConti;
    QThread *m_realtimeImageThread;

槽函式定義

    void showRealTimeVideo(cv::Mat image);

啟動採圖的訊號定義

void startChildThread(MvcCamera &m_camera);

部分原始檔程式碼,槽訊號傳遞自定義型別引數時必須使用註冊的方式,一開始採用訊號的連線方式為Qt:DirectionConnect,程式碼可以編譯過去,但是引數傳遞不過去,並且會導致無法開啟子執行緒!!

//分配記憶體
    m_imageConti = new ImageContinuous;
    m_realtimeImageThread = new QThread;

    //自定義型別作為槽訊號的引數,需要先註冊
    qRegisterMetaType<cv::Mat>("cv::Mat");
    qRegisterMetaType<MvcCamera>("MvcCamera&");

    connect(m_realtimeImageThread, &QThread::finished, m_imageConti, &QObject::deleteLater);
    connect(m_realtimeImageThread, &QThread::finished, m_realtimeImageThread, &QObject::deleteLater);


    connect(this, &QtWeldingRobotControlSystem::startChildThread, m_imageConti, &ImageContinuous::getImage);
    connect(m_imageConti, &ImageContinuous::imageInfo, this, &QtWeldingRobotControlSystem::showRealTimeVideo);

    m_imageConti->moveToThread(m_realtimeImageThread);

    //啟動子執行緒
    m_realtimeImageThread->start();