1

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!

0 Answers0