I have 3 threads. The main thread (for my GUI) -> worker thread A -> worker thread B
In worker thread B (in my code called recognitionThread) I am trying to start a process and write data to that process. The process is supposed to start my python virtual environment (this part works) and execute some commands in that environment (that doesn t work).
When I try to write data to that process I get: Socket notifiers cannot be enabled or disabled from another thread
I think I kind of understand what the problem is, but not totally and have no clue about how to solve my issue.
Those are the relevant parts of my code:
recognitionClass.cpp:
QProcess recognitionClass::p; recognitionClass::recognitionClass(QObject *parent) : QObject(parent) { startPythonVirtualEnv(); } void recognitionClass::startPythonVirtualEnv() { qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError"); params<<"-f"<<"-c"<<"python2"<< "/home/John/Desktop/python.log"; qDebug()<<"parameters: "<<params; if(p.state()==2) {qDebug()<<"python virtualenv already running";} else { p.start("script", params); qDebug()<<"started process"; while(!p.waitForStarted()) {qDebug()<<"waiting for virtualenv to be ready";} } } recognitionClass::person recognitionClass::runRecognitionScript() { person persStrObj; qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError"); connect(&p, &QProcess::errorOccurred, qApp, &QApplication::aboutQt ); qint64 successFailWrite; delay(); qDebug()<<"before p.write()"; successFailWrite = p.write("import imp; foo = imp.load_source('myTest', '/home/John/openface/demos/recognitionClass.py'); from myTest import recognitionClass; myClassObj = recognitionClass(); print myClassObj.recognize('/home/John/Desktop/camera.jpg');"); qDebug()<<"after p.write()"; delay(); qDebug()<<"started process, result write op: "<< successFailWrite; }
recognitionClass.h:
class recognitionClass : public QObject { Q_OBJECT private: struct person{ QString persName; double persCertitude; }; static QProcess p; QStringList params; public: explicit recognitionClass(QObject *parent = nullptr); struct person runRecognitionScript(); void startPythonVirtualEnv(); void stopPythonVirtualEnv(); void delay(); signals: public slots: double recognizePerson(); };
webcamclass.cpp:
webcamClass::webcamClass(QObject *parent) : QObject(parent) { recognizePerson=false; //setup recognition thread recognitionThread = new QThread(this); recognitionClObj = new recognitionClass(); connect( recognitionThread, SIGNAL(started()), recognitionClObj, SLOT(recognizePerson()) ); recognitionClObj->moveToThread(recognitionThread); } void webcamClass:: getVideoFrame() { static cv::VideoCapture cap(CV_CAP_ANY); cv::Mat imgFrame; if( !cap.isOpened() ) { qDebug()<< "Could not initialize capturing...\n"; } while(1) { cap >> imgFrame; cv::cvtColor(imgFrame, imgFrame, CV_BGR2RGB); QImage img; img = QImage((uchar*)imgFrame.data, imgFrame.cols, imgFrame.rows, QImage::Format_RGB888); QPixmap pixmap = QPixmap::fromImage(img); emit gottenVideoFrame(pixmap); if(recognizePerson==true) { //write image to recognition buffer recognitionThread->start(); if(myGlobalVariable==0) { frameForRecognition = imgFrame; myGlobalVariable=55; } } cv::waitKey(100); } }
webcamclass (AKA worker thread A) is a worker thread that creates a new worker thread implementing recognitionclass. (recognitionThread, AKA worker thread B) Inside the recognitionThread I try to create a process to start my python virtual environment in my constructor. This works. The error occurs at runtime at line containing successFailWrite = p.write("import imp...."); in the recognitionClass.cpp file on line 37.
My guess is that I am tryong to program this is in a very bad way which is why I am bumping from one problem into another. I already read other posts related to similar issues, but I was unable to find my way out.
Could someone please provide some explanation please?
Thanks!