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

时间:2017-08-22 12:11:26

标签: c++ multithreading qt

我试图在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()被触发吗?

谢谢!

2 个答案:

答案 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)。