简体   繁体   中英

Communicating with QProcess from a QThread

Structure Of Application:

MainWindow -> ProcessingThread(QThread) - > QProcess for Python Script

In the Run/Exec loop of Processing Thread I would like to interact with the process.

How do I go about it?

Current Problem: I know both ProcessingThread(QThread) and its Run loop run inside different threads. Hence if I initialize the QProcess in QThread constructor I am unable to interact with the process because of following error:

QSocketNotifier: Socket Notifiers cannot be enabled or disabled from another thread

and if I try to initialize the process in the Run Loop I get the following error:

QObject: Cannot create children for a parent that is in a different thread (Parent is ProcessingThread(0x984b2a0), parent's thread is QThread(0x940e180)), current thread is ProcessingThread(0x984b2a0)

If I initialize the QProcess in ProcessingThread constructor, I am able to interact with the script perfectly.

Any suggestions?

Update: Also The reason for using QThread is because I am performing image processing, the Processing Threads keeps fetching images from camera. Some of these images need to be further processed by the Python script running in QProcess .

Update 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");
}

The above code works perfectly.

But I want to send and receive data from function:

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

Keep long story short, you shouldn't instantiate anything you going to use in your new thread in the constructor, as every object instantiated there will get an affinity of the thread where your QThread object is created, common practice is either not to subclass QThread at all, just use QObject and moveToThread, and then connect some slot like init() to QThread started() signal, so you can do all initialisation inside the init() which will run inside a new thread, or if for whatever reasons you need QThread subclassing instantiate everything in run().

Also pay attention that QThread itself is nothing more nothing less then a wrapper of your real thread and stays as an object in a thread where you created it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM