通过QThread与QProcess进行通信

时间:2016-04-06 11:15:17

标签: c++ qt qthread qprocess

申请结构:

MainWindow - > ProcessingThread(QThread) - > Python脚本的QProcess

在Processing Thread的Run / Exec循环中,我想与进程交互。

我该如何解决?

当前问题: 我知道ProcessingThread(QThread)和它的Run循环都在不同的线程内运行。因此,如果我在QProcess构造函数中初始化QThread,则由于以下错误,我无法与该进程交互:

  

QSocketNotifier:无法启用或禁用套接字通知程序   另一个线程

如果我尝试在Run Loop中初始化该过程,我会收到以下错误:

  

QObject:无法为不同的父级创建子级   线       (Parent是ProcessingThread(0x984b2a0),父线程是QThread(0x940e180)),       当前线程是ProcessingThread(0x984b2a0)

如果我在QProcess构造函数中初始化ProcessingThread,我就能完美地与脚本进行交互。

有什么建议吗?

更新:另外使用QThread的原因是因为我正在执行图像处理,处理线程不断从相机中提取图像。其中一些图像需要由QProcess中运行的Python脚本进一步处理。

更新2:CODE

void MainWindow::MainWindow(QWidget *parent)
{
    ...
    debugProcessingThread = new DebugProcessingThread();
}

class DebugProcessingThread : public QThread
{
    Q_OBJECT
    ...
    private:
    qProcess *myprocess;
}

DebugProcessingThread::DebugProcessingThread()
{
    ...
    myProcess = new QProcess(this);
    myProcess->start("python abc.py");
    connect(myProcess, SIGNAL(started()), this, SLOT(processStarted()));
    connect(myProcess, SIGNAL(error(QProcess::ProcessError)), this, SLOT(processError()));
     connect(myProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(readStandardOutput()));

    myProcess->waitForStarted();
}

void DebugProcessingThread::processError()
{
    qDebug("PROCESS ERROR");
    qDebug() << myProcess->errorString();
}

void DebugProcessingThread::readStandardOutput()
{
    qDebug("READ DATA");
    qDebug(myProcess->readAll().toStdString().c_str());
    myProcess->write("out.txt\n");
}

void DebugProcessingThread::processStarted()
{
    qDebug("Process has started");
}

以上代码完美无缺。

但我想从函数发送和接收数据:

void DebugProcessingThread::run()
{
     myProcess->write("out.txt\n");
     // This Throws socket Error
}

1 个答案:

答案 0 :(得分:1)

长话短说,你不应该在构造函数中实例化你在新线程中使用的任何东西,因为那里实例化的每个对象都会获得线程的亲和力,其中你的QThread对象是创建,通常的做法是要么根本不要继承QThread,只需使用QObject和moveToThread,然后将一些插槽如init()连接到QThread的starts()信号,这样你就可以在init()内部进行所有初始化,这将在里面运行一个新线程,或者如果由于某种原因你需要QThread子类化实例化run()中的所有内容。

还要注意QThread本身就是你的真实线程的包装器,并且在你创建它的线程中作为对象保留。