如何发送包含 cv::Mat 的 Qt 信号?

Posted

技术标签:

【中文标题】如何发送包含 cv::Mat 的 Qt 信号?【英文标题】:How to send a Qt signal containing a cv::Mat? 【发布时间】:2012-03-27 14:46:09 【问题描述】:

简而言之,我收到以下错误:

QObject::connect: Cannot queue arguments of type 'cv::Mat'
(Make sure 'cv::Mat' is registered using qRegisterMetaType().)

我想要做的是从 QThread 向主线程发送一个包含两个 cv::Mat 图像的信号,以便我可以显示输出。没有编译时错误,但是当我运行程序时,它卡在 qglobal.h (inline void qt_noop() ) 中的断点处。

我尝试将Q_DECLARE_METATYPE(cv::Mat) 添加到代码中,但无济于事。我现在不知道该怎么做。

代码

在 QThread 类中:

signals:
void sndFlow(cv::Mat &leftEye, cv::Mat &rightEye);

void eyesDriver::run()

    forever
    
        flow->draw(leftEye, rightEye);
        sndFlow(leftEye, rightEye);
    

在 QObject 类中捕获:

public slots:
void recFlow(cv::Mat &leftEye, cv::Mat &rightEye);

void myClass::recFlow(cv::Mat &leftEye, cv::Mat &rightEye)

    cv::imshow("left", leftEye);
    cv::imshow("rigth", rightEye);
    cv::waitKey(40);

主要:

Q_DECLARE_METATYPE(cv::Mat)
int main(int argc, char *argv[])

    QCoreApplication a(argc, argv);
    qRegisterMetaType< cv::Mat >("cv::Mat");
    // create objects from QThread and QObject class
    QObject::connect(&qthread, SIGNAL(sndFlow(cv::Mat&,cv::Mat&)),
                     &qobject, SLOT(recFlow(cv::Mat&,cv::Mat&)));
    qthread.start();
    return a.exec();

将信号槽变量更改为QSharedPointer&lt; cv::Mat &gt; 也不起作用。给出同样的错误:

QObject::connect: Cannot queue arguments of type 'QSharedPointer<cv::Mat>'
(Make sure 'QSharedPointer<cv::Mat>' is registered using qRegisterMetaType().)

作品

好吧,它似乎工作。我在QObject::connect 通话之前移动了qRegisterMetaType&lt; cv::Mat &gt;("cv::Mat");。但是我仍然必须在 qglobal.h 中的断点之后按“F5”,然后才能工作。

我可能是错的,但似乎qRegisterMetaType的位置不是微不足道的。

【问题讨论】:

老实说,我认为您可能无意中更改了其他内容,因为如果在第一次连接之前调用 qRegisterMetaType,我认为它并不重要。还是不是? 【参考方案1】:

除了宏之外,您还需要调用qRegisterMetaType(或代替它,取决于您的需要)。这对于信号能够跨线程编组数据是必要的。但是,如果您使用 QObject 层次结构来管理对象的生命周期,则通过引用或智能指针或原始指针传递可能是一个更明智的主意。

【讨论】:

知道我必须在哪里调用该函数吗?与宏相同,我目前在 main.cpp 文件中尝试它们,主函数上方的宏,qRegisterMetaType 就在其中。这并没有解决它,所以很可能我必须在其他地方调用最后一个函数。 我认为必须在调用connect之前完成。确保此类具有公共默认构造函数(即无参数构造函数)、公共复制构造函数和公共析构函数。如果没有,您必须使用我的替代建议之一或围绕它编写自定义 QObject 包装器(但您可能不需要)。 cv::Mat 拥有所有这些,但它还不能工作。我试图通过引用或指针调用,但它产生了同样的问题。你建议什么智能指针?我不熟悉这些。 如果通过引用,它必须工作,所以还有一个问题。您能否发布您的信号和插槽的声明,以及您如何以及在何处连接它们? 使用参考参数时遇到什么错误?

以上是关于如何发送包含 cv::Mat 的 Qt 信号?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 cv::mat 标头和数据部分转换为单个 qbytearray?

如何将从 C++ 发送的 cv::MAT 字节数组转换为 Java 中的位图?

如何从 c++ 接口 cv::Mat 转换为 c IplImage?

如何从字节数组初始化 RGBA cv::Mat?

Qt python如何知道QPushButton发送了哪些信号?

打印 cv::Mat opencv