Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Update: Forum Guidelines & Code of Conduct

    Cannot connect signal to slots

    QML and Qt Quick
    2
    6
    2019
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • V
      VincentLiu last edited by

      Hi, I have three signal-slot pairs and I only succeed at the first time, but failed at the following two. Below is my code, does anyone know the reason:

      main.cpp

      Q_DECLARE_METATYPE(vector<Mat>)
      Q_DECLARE_METATYPE(Mat)
      
      Q_DECLARE_METATYPE(vector<Point>)
      Q_DECLARE_METATYPE(Ptr<SVM>)
      
      Q_DECLARE_METATYPE(vector<KeyPoint>)
      
      int main(int argc, char *argv[])
      {
      
      qDebug() << "Invoked main.cpp - " << QThread::currentThreadId();
      
      qRegisterMetaType<vector<Mat>>("vector<Mat>");
      qRegisterMetaType<Mat>("Mat");
      qRegisterMetaType<vector<Point>>("vector<Point>");
      qRegisterMetaType<Ptr<SVM>>("Ptr<SVM>");
      qRegisterMetaType<vector<KeyPoint>>("vector<KeyPoint>");
      
      QGuiApplication app(argc, argv);
      
      QQmlApplicationEngine engine;
      
      QThread imgProcessThread;
      
      QObject::connect(&app, &QGuiApplication::aboutToQuit, &imgProcessThread, &QThread::quit);
      
      ImgProcess *imgProcessObj = new ImgProcess(0);
      
      imgProcessObj->moveToThread(&imgProcessThread);
      
      imgProcessThread.start();
      
      // Add image provider to engine
      DefineHandler *defineHandler = new DefineHandler(0);
      engine.addImageProvider(QLatin1String("define_handler"), defineHandler);
      
      QObject::connect(defineHandler, &DefineHandler::signalCalculateBgMean, imgProcessObj, &ImgProcess::calculateBgMean);    // Succeed
      QObject::connect(imgProcessObj, &ImgProcess::signalMeanBgReady, defineHandler, &DefineHandler::receiveMeanBg); // Succeed
      
      QObject::connect(defineHandler, &DefineHandler::signalTrainSVM, imgProcessObj, &ImgProcess::slotTrainSVM); // Succeed
      QObject::connect(imgProcessObj, &ImgProcess::signalSVMReady, defineHandler, &DefineHandler::slotSVMReady); // Fail
      
      QObject::connect(defineHandler, &DefineHandler::signalCalculateSIFTFeartures, imgProcessObj, &ImgProcess::slotCalculateSIFTFeartures); // Succeed
      QObject::connect(imgProcessObj, &ImgProcess::signalSIFTReady, defineHandler, &DefineHandler::slotSIFTReady);  // Fail
      
      // Expose image provider to QML
      QQmlContext *ctx = engine.rootContext();
      ctx->setContextProperty("DefineHandlerContext", defineHandler);
      ctx->setContextProperty("VerifyHandlerContext", verifyHandler);
      
      QQmlComponent component(&engine, QUrl(QStringLiteral("qrc:/define.qml")));
      QObject *object = component.create();
      
      
      // Note: has been loaded previously in "QQmlComponent component(&engine, QUrl(QStringLiteral("qrc:/verify.qml")));
      // engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
      
      int result = app.exec();
      
      imgProcessThread.wait();
      
      return result;
      }
      

      ImgProcess.h

      class ImgProcess:public QObject
      {
      Q_OBJECT
      public:
      
      explicit ImgProcess(QObject *parent = 0);
      
      signals:
      
          Q_SIGNAL void signalMeanBgReady(Mat meagBg);
      
          Q_SIGNAL void signalSVMReady(Ptr<SVM> svm);
      
          Q_SIGNAL void signalSIFTReady(vector<KeyPoint> keyPoints, Mat descriptor);
      
      public slots:
      
          void calculateBgMean(vector<Mat> bgVector);
      
          void slotTrainSVM(vector<Point> samplePts, const Mat mat);
      
          void slotCalculateSIFTFeartures(Mat mat);
      

      };

      DefineHandler.h

      class DefineHandler: public QObject, public QQuickImageProvider
      {
      Q_OBJECT
      
      public:
      
      explicit DefineHandler(QObject *parent = 0);
      
      protected:
      
      private:
      
      signals:
      
      
      Q_SIGNAL void signalCalculateBgMean(vector<Mat>);
      
      Q_SIGNAL void signalTrainSVM(vector<Point>, const Mat);
      
      Q_SIGNAL void signalCalculateSIFTFeartures(Mat);
      
      public slots:
      
      void slotNewFrameReady();
      
      void setImage(QPixmap);
      
      void receiveMeanBg(Mat);
      
      void slotSVMReady(Ptr<SVM>);
      
      void slotSIFTReady(vector<KeyPoint>, Mat);
      
      };
      

      In the second and third pair, I can send the signal from definehandler to imgprocessing, but fail to emit signal back from imgprocessing to definehandler. Thanks

      1 Reply Last reply Reply Quote 0
      • m.sue
        m.sue last edited by

        Hi,
        does the call to QObject::connect not work i.e. return false or does the emit not work as such. Please show the code that emits the signals, too.
        -Michael.

        V 1 Reply Last reply Reply Quote 1
        • V
          VincentLiu last edited by VincentLiu

          Hi, @m.sue

          This is my code:

          void DefineHandler::slotSVMReady(Ptr<SVM> svm)
          {
             qDebug() << "DefineHandler::slotSVMReady";
          
             this->kSVM = svm;
          
          }
          
          void DefineHandler::slotSIFTReady(vector<KeyPoint> keyPoints, Mat descriptor)
          {
          qDebug() << "DefineHandler::slotSIFTReady";
          
          this->keyPoints = keyPoints;
          
          this->descriptor = descriptor;
          }
          
          void DefineHandler::exportConfiguration()
          {
              qDebug() << "DefineHandler::exportConfiguration() - " << QThread::currentThreadId();
          
          emit signalTrainSVM(samplePts, rotatedImg);
          
          vector<KeyPoint> templateKeyPoint;
          Mat templateDescriptors;
          
          // Calculate features of connector
          // imgProcess.calculateSIFTFeatures(connectorImg, templateKeyPoint, templateDescriptors);
          
          emit signalCalculateSIFTFeartures(connectorImg, true);
          
          // Export configurations
          FileStorage fs("configuration.yml", FileStorage::WRITE);
          
          fs << "width" << meanBg.rows;
          fs << "height" << meanBg.cols;
          
          fs << "meanBg" << meanBg;
          fs << "connectorImg" << connectorImg;
          
          fs << "templateKeyPoints" << templateKeyPoint;
          fs << "templateDescriptors" << templateDescriptors;
          
          fs << "classNum" << kClassNum;
          
          // kSVM->save("svmModel.yml");
          
          fs.release();
          
          }
          

          It confused me that if I write "kSVM->save("svmModel.yml"); " (as the second line from the bottom in exportConfiguration()), an exception occurred and the logs "qDebug() << "DefineHandler::slotSIFTReady";" and "qDebug() << "DefineHandler::slotSVMReady";" were not printed. However,if I removed the "kSVM->save("svmModel.yml"); ", the two logs successfully printed.

          It brings me two points:

          1. Since the SVM model could be saved in imgProcess side while fails in defineHandler, did the SVM model lost some infos during the transfer process from signal to slot ? If so, was it resulted from erroneous or incomplete qRegisterMeteType settings ?

          2. Even if saving SVM model fails in exportConfigurtaion(), why the logs "qDebug() << "DefineHandler::slotSIFTReady";" and "qDebug() << "DefineHandler::slotSVMReady" which should be executed before the saving were not printed?

          Thanks~

          1 Reply Last reply Reply Quote 0
          • V
            VincentLiu @m.sue last edited by

            @m.sue
            BTW, the connections are successful in both ways with/without writing kSVM->save("svmModel.yml").

            1 Reply Last reply Reply Quote 0
            • m.sue
              m.sue last edited by m.sue

              Hi,
              but this is not the part of the code where you emit the said signals that failed: ImgProcess::signalSVMReady and ImgProcess::signalSIFTReady. It's the targets of the signals, the slots to which the signals are connected.
              -Michael.

              1 Reply Last reply Reply Quote 0
              • V
                VincentLiu last edited by

                Hi,
                below is the emitters of both, note that the signals are emitted at the end of each function. Thanks.

                1. signalSVMReady

                void ImgProcess::slotTrainSVM(vector<Point> samplePts, const Mat mat)
                {
                qDebug() << "ImgProcess::slotTrainSVM() - " << QThread::currentThreadId();

                const int numPerClass = 25;
                
                Mat matHSV;
                cvtColor(mat, matHSV, CV_BGR2HSV);
                
                const size_t classNum = samplePts.size();
                
                int* labels = static_cast<int*>(malloc(sizeof(int)*classNum*numPerClass));
                
                // Create class labels: [0...0,1...1,...,classNum-1,...classNum-1]
                for (size_t i = 0; i< classNum; ++i)
                {
                    for (size_t j = 0;j < numPerClass; ++j)
                    {
                        *(labels + i* numPerClass + j) = static_cast<int>(i);
                    }
                }
                
                float* trainingData = static_cast<float*>(malloc(sizeof(float)*classNum*numPerClass*3));
                
                Mat labelsMat(static_cast<int>(classNum * numPerClass),1, CV_32S, labels);
                Mat trainingDataMat(static_cast<int>(classNum * numPerClass),3, CV_32FC1, trainingData);
                
                for (size_t vecIdx = 0; vecIdx < classNum; ++vecIdx)
                {
                    Point center = samplePts[vecIdx];
                    int x = center.x;
                    int y = center.y;
                
                    size_t inClassIdx = 0;
                
                    for (int i = x-2; i <= x+2; ++i)
                    {
                        for (int j = y-2; j <= y+2; ++j)
                        {
                            Vec3b val = matHSV.at<Vec3b>(j,i);
                
                            int colIdx = 0;
                
                            trainingDataMat.at<float>(static_cast<int>(vecIdx * numPerClass + inClassIdx),colIdx++) = val[0];
                            trainingDataMat.at<float>(static_cast<int>(vecIdx * numPerClass + inClassIdx),colIdx++) = val[1];
                            trainingDataMat.at<float>(static_cast<int>(vecIdx * numPerClass + inClassIdx),colIdx) = val[2];
                
                            inClassIdx++;
                        }
                    }
                }
                
                Ptr<SVM> svmModel = SVM::create();
                svmModel->setType(SVM::C_SVC);
                svmModel->setKernel(SVM::LINEAR);
                
                svmModel->train(trainingDataMat, ROW_SAMPLE, labelsMat);
                
                free(labels);
                free(trainingData);
                
                // TODO move to defineHandler
                svmModel->save("svmModel.yml");
                
                emit signalSVMReady(svmModel);
                
                }
                
                
                2. signalSIFTReady
                
                    ```
                void ImgProcess::slotCalculateSIFTFeartures(Mat mat, bool isTemplate)
                    {
                    qDebug() << "ImgProcess::slotCalculateSIFTFeartures()" << endl;
                
                    Ptr<Feature2D> sift = xfeatures2d::SIFT::create();
                
                    vector<KeyPoint> keyPoints;
                
                    Mat descriptor;
                
                    sift->detectAndCompute(mat, Mat(), keyPoints, descriptor);
                
                    // TODO move to defineHandler
                    if (isTemplate)
                    {
                        FileStorage fs("template.yml", FileStorage::WRITE);
                
                        fs << "templateKeyPoints" << keyPoints;
                        fs << "templateDescriptors" << descriptor;
                
                        fs.release();
                
                    }
                
                        emit signalSIFTReady(keyPoints, descriptor);
                    }
                
                1 Reply Last reply Reply Quote 0
                • First post
                  Last post