我试图在Qt(C ++)中进行线程间通信。我有一个工作线程,它做了一些计算,我希望workerthread在完成后将结果返回给主线程。我因此使用连接,我知道感谢调试,信号成功发出,但它是没有执行的插槽,我不明白为什么。
相关的代码:
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
。
webcamClass属于父线程,而workerClass属于 - 你猜对了 - 工作线程。
有人可以解释如何设置我的连接以便mySlot()被触发吗?
谢谢!
答案 0 :(得分:1)
如果可能,我强烈建议您使用新的Signal Slot语法:
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
如果要传递自定义类型,则必须先将它们声明为元类型。 添加e.G.这在你的构造函数中:
qRegisterMetaType(&#34; MyDataType&#34);
请确保您的自定义数据类型具有默认构造函数,并且请注意afaik,引用不能跨线程传递。
答案 1 :(得分:1)
在您粘贴在pastebin.com/UpPfrNEt中的代码中,您使用的getVideoFrame
方法使用while (1)
。如果调用此方法,它将一直运行并阻止事件循环处理信号。你可以通过多种方式解决它,我认为最好的做法是用其他东西替换while(1)。