从QThread与QProcess通信

Communicating with QProcess from a QThread

本文关键字:通信 QProcess QThread      更新时间:2023-10-16

应用程序结构:

主窗口->ProcessingThread(QThread)->QProcess for Python Script

在处理线程的运行/执行循环中,我想与进程进行交互。

我该怎么做?

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

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

如果我试图在Run Loop中初始化进程,我会得到以下错误:

QObject:无法为位于其他线(父线程是ProcessingThread(0x984b2a0),父线程是QThread(0x940e180)),当前线程是ProcessingThread(0x984b2a0)

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

有什么建议吗?

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

更新2:代码

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.txtn");
}
void DebugProcessingThread::processStarted()
{
    qDebug("Process has started");
}

上面的代码运行得很好。

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

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

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

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