连接线程并访问公共变量

时间:2015-10-05 14:30:38

标签: multithreading qt

我在main()-function创建了一个帖子。 线程在一个点发出信号。 我希望信号调用由QMainWindow class PPI w;创建的对象中的一个插槽,而不是尝试访问公共对象videoSocket。我的线程工作正常,但据我所知,无法将信号连接到main()-function的插槽。但是当我试图在QMainWindow Class中创建线程但程序崩溃时。

此代码有效(连接的axcept):

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    PPI w;
    w.show();

    VideoUDPSocketThread videoUDPSocketThread;
    videoUDPSocketThread.start();

    //connect(&videoUDPSocketThread, SIGNAL(videoRead(int)), &w, SLOT(onVideoRead(int)), Qt::QueuedConnection);

    return a.exec();
}

此代码将导致我的程序崩溃:

PPI::PPI(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
    ui.setupUi(this);

    ppiScene = new PPIScene(this);
    ppiScene->setSceneRect(0,0,SCENEWIDTH,SCENEHEIGHT);
    ui.gVPPI->setScene(ppiScene);

    videoImage = new QImage();
    videoPixmap = ppiScene->addPixmap(QPixmap::fromImage(*videoImage));


    VideoUDPSocketThread videoUDPSocketThread;
    //videoUDPSocketThread.start(); <--CRASH

    connect(&videoUDPSocketThread.videoSocket, SIGNAL(videoRead(int)), this, SLOT(onVideoRead(int)));
}

VideoUDPSocketThread.h

#ifndef VIDEOUDPSOCKETTHREAD_H
#define VIDEOUDPSOCKETTHREAD_H

#include <QThread>
#include "videoudpsocket.h"

class VideoUDPSocketThread : public QThread
{
    Q_OBJECT

public:
    //VideoUDPSocketThread(QObject *parent);
    VideoUDPSocketThread();
    ~VideoUDPSocketThread();
    VideoUDPSocket videoSocket;

private:

protected:
    void run();
};

#endif // VIDEOUDPSOCKETTHREAD_H

VideoUDPSocketThread.cpp

#include "videoudpsocketthread.h"

/*VideoUDPSocketThread::VideoUDPSocketThread(QObject *parent)
    : QThread(parent)
{

}*/

VideoUDPSocketThread::VideoUDPSocketThread()
{

}

VideoUDPSocketThread::~VideoUDPSocketThread()
{

}

void VideoUDPSocketThread::run()
{
    VideoUDPSocket videoSocket;
    exec();
}
  

QThread:在线程仍在运行时被销毁

     

Eine Ausnahme(erste Chance)bei 0x5d9d5a29 in ppi.exe:0xC0000005:Zugriffsverletzung beim Lesen位置0x00000074。

     

Unpihandelte Ausnahme bei 0x5d9d5a29 in ppi.exe:0xC0000005:Zugriffsverletzung beim Lesen位置0x00000074。

(我尝试将此错误翻译成英文:)

  

QThread:在线程仍在运行时被销毁

     

ppi.exe中0x5d9d5a29发生异常(第一次机会):0xC0000005:读取位置0x00000074时发生访问冲突。

     

ppi.exe中0x5d9d5a29处的未处理异常:0xC0000005:读取位置0x00000074时发生访问冲突。

1 个答案:

答案 0 :(得分:2)

在PPI的构造函数中在堆栈上创建一个Thread。这意味着它将在您返回的第二个函数中被销毁。我想你想要这样的东西:

PPI::PPI(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
    ui.setupUi(this);

    ppiScene = new PPIScene(this);
    ppiScene->setSceneRect(0,0,SCENEWIDTH,SCENEHEIGHT);
    ui.gVPPI->setScene(ppiScene);

    videoImage = new QImage();
    videoPixmap = ppiScene->addPixmap(QPixmap::fromImage(*videoImage));


    VideoUDPSocketThread * videoUDPSocketThread = new VideoUDPSocketThread();

    // connect BEFORE starting to ensure thread safety (this is very important)
    // connect the finished signal to the deleteLater slot to make sure your memory doesn't leak
    // also use the new connection syntax, compiler warnings are nice
    connect( &videoUDPSocketThread->videoSocket, &VideoUDPSocket::videoRead, this, &PPI::onVideoRead );
    connect( videeoUDPSocketThread, &QThread::finished, videeoUDPSocketThread, &QObject::deleteLater ); 

    // now you can start the tread
    videeoUDPSocketThread->start();
}

我希望这会有所帮助