Qt C++ - 如何将数据从工作线程传递到主线程?

Qt C++ - How to pass data from a worker thread to main thread?

本文关键字:线程 工作 C++ 数据 Qt      更新时间:2023-10-16

我正在尝试在Qt(C++(中执行线程间通信。我有一个工作线程,它执行一些计算,我希望工作线程在完成后将其结果返回到主线程。因此,我使用连接,我知道这要归功于调试,信号已成功发出,但它是未执行的插槽,我不明白为什么。

相关代码段:

webcamClass::webcamClass(QObject *parent) : QObject(parent)
{  
workerThread = new QThread(this);
workerClassObj = new workerClass();
//connect for image
connect(workerClassObj, SIGNAL(mySignal(QPixmap)), this, SLOT(mySlot(QPixmap)));
//connect(&workerClassObj, workerClass::mySignal(QPixmap), this, webcamClass::mySlot(QPixmap));

connect( workerThread, SIGNAL(started()), workerClassObj, SLOT(getImage()) );
workerClassObj->moveToThread(workerThread);

}
void webcamClass:: foo()
{
workerThread->start();
}
void workerClass::getImage()
{
qint64 successFailWrite;
QImage img;
QPixmap pixmap;
... do some stuff with pixmap...
qDebug()<<"going to emit result";
emit mySignal(pixmap);
qDebug()<<"emitted";
}

void webcamClass::mySlot(QPixmap p)
{qDebug()<<"this message should be displayed"; }

相应的头文件:

class workerClass : public QObject
{
Q_OBJECT
private:
public:
explicit workerClass(QObject *parent = nullptr);

signals:
void mySignal(QPixmap);
};

webcamClass::webcamClass(QObject *parent) : QObject(parent)
{
Q_OBJECT
public:
explicit webcamClass(QObject *parent = nullptr);
public slots:
void mySlot(QPixmap p);
private:
QThread *workerThread;
workerClass *workerClassObj;

};

上面的代码只是输出:

going to emit result
emitted

但不幸的是没有输出this message should be displayed.

网络摄像头类属于父线程,而工人类属于 - 你猜对了 - 工作线程。

有人可以解释如何设置我的连接以便触发 mySlot(( 吗?

谢谢!

在您粘贴的代码中 pastebin.com/UpPfrNEt 您有一个使用while (1)getVideoFrame方法。如果调用此方法,它将始终运行并阻止事件循环处理信号。您可以通过多种方式解决它,我认为最佳做法是用其他东西替换 while(1(。

如果可能的话,我强烈建议您使用新的信号槽语法:

connect( SOURCEINSTANCE, &CLASS::SIGNAL, TARGETINSTANCE, &CLASS::SLOT );

在您的情况下,这可能是:

connect( workerClassObj, &workerClass::mySignal, this, &webcamClass::mySlot );

具体来说,对于您的情况,如果您想在线程之间传递信号和插槽,则必须小心。首先,检查连接调用的连接类型,其实际上是最后一个参数。

connect( workerClassObj, &workerClass::mySignal, this, &webcamClass::mySlot, Qt::QueuedConnection );

有关详细说明,请参阅此处: http://doc.qt.io/qt-5/signalsandslots.html

如果要传递自定义类型,必须先将它们声明为元类型。 例如,在您的构造函数中添加以下内容:

qRegisterMetaType("MyDataType"(;

请确保您的自定义数据类型具有默认构造函数,并注意 afaik、引用不能跨线程传递。