问题:
在机器视觉中使用Qt + OpenCV对图像进行处理时,往往需要将图像处理算法放在子线程中,因此子线程会传递处理后的图像QImage类型数据,以及图像特征数据到主线程。直接传递vector<>类型参数,编译不会出错,但没有显示结果。
原因:
猜想vector<>类型参数没有传输成功。通过阅读米小鸢博主的博客,感谢!原来信号与槽之间只能传输通用数据类型,如:QImage、int、bool等,需要使用QVariant类对复杂数据进行包装。
一、解决步骤
- 在子线程中包含头文件、声明信号函数、在构造函数中注册数据;
- 在主线程中包含子线程头文件、声明槽函数;
- 在主线程构造函数中连接信号与槽;
- 在子线程包装数据、emit 发送信号;
- 在主线程槽函数下还原数据、显示。
二、主要代码
子线程:
#pragma once
#include<QObject>
#include <QMetaType>
#include <QVariant>
#include<opencv2/opencv.hpp>
using namespace cv;
using namespace std;
Q_DECLARE_METATYPE(vector<Point3f>);
class thread_deal : public QObject
{
Q_OBJECT
public:
thread_deal(QObject *parent = Q_NULLPTR);
void setFlag(bool flag = true);
void dodata();
signals:
void send_data(QVariant, QVariant);
private:
bool isStop;
vector<Point3f>circle_center,cons;
};
#include "thread_deal.h"
thread_deal::thread_deal(QObject *parent)
: QObject(parent)
{
isStop = false;
qRegisterMetaType<QVariant>("QVariant");
}
void thread_deal::dodata() {
for (int i = 0; i < 6; i++) {
circle_center.push_back(Point3f(i, i, i));
cons.push_back(Point3f(i, i, i));
}
QVariant DataVar1, DataVar2;
DataVar1.setValue(circle_center);
DataVar2.setValue(cons);
emit send_data(DataVar1, DataVar1);
}
void thread_deal::setFlag(bool flag) {
isStop = flag;
}
主线程:
#pragma once
#include <QtWidgets/QMainWindow>
#include "ui_vector_test.h"
#include <thread_deal.h>
#include <QThread>
#include<QStandardItem>
#include<QStandardItemModel>
#include<iostream>
class vector_test : public QMainWindow
{
Q_OBJECT
public:
vector_test(QWidget *parent = Q_NULLPTR);
signals:
void startThread();
private slots:
void on_ptn_clicked();
void on_ptn2_clicked();
void deal_data(QVariant vRowInfo1, QVariant vRowInfo2);
void deal_close();
private:
Ui::vector_testClass ui;
QStandardItemModel * model_1;
QStandardItemModel * model_2;
QThread * thread;
thread_deal * myT;
};
#include "vector_test.h"
#pragma execution_character_set("utf-8")
vector_test::vector_test(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
/******************略部分非相关界面控件代码***********************/
myT = new thread_deal;
thread = new QThread(this);
myT->moveToThread(thread);
connect(this, &vector_test::startThread, myT, &thread_deal::dodata);
connect(myT, &thread_deal::send_data, this, &vector_test::deal_data);
connect(this, &vector_test::destroyed, this, &vector_test::deal_close);
}
void vector_test::deal_data(QVariant vRowInfo1, QVariant vRowInfo2) {
vector<Point3f>circle_centers = vRowInfo1.value<vector<Point3f>>();
vector<Point3f>circle_centers2 = vRowInfo2.value<vector<Point3f>>();
int t = 0;
//表一
for (int i = 0; i<circle_centers.size(); i++) {
QString datas = QString("%1").arg(circle_centers[i].z);
this->model_1->setItem(t, i, new QStandardItem(datas));
}
for (int i = 0; i<circle_centers2.size(); i++) {
QString datas2 = QString("%1").arg(circle_centers2[i].z);
this->model_2->setItem(t, i, new QStandardItem(datas2));
}
}
3、结果