Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Cannot connect signal to slots
Forum Update on Monday, May 27th 2025

Cannot connect signal to slots

Scheduled Pinned Locked Moved QML and Qt Quick
6 Posts 2 Posters 2.2k Views
  • 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 Offline
    V Offline
    VincentLiu
    wrote on last edited by
    #1

    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
    0
    • m.sueM Offline
      m.sueM Offline
      m.sue
      wrote on last edited by
      #2

      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
      1
      • V Offline
        V Offline
        VincentLiu
        wrote on last edited by VincentLiu
        #3

        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
        0
        • m.sueM m.sue

          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 Offline
          V Offline
          VincentLiu
          wrote on last edited by
          #4

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

          1 Reply Last reply
          0
          • m.sueM Offline
            m.sueM Offline
            m.sue
            wrote on last edited by m.sue
            #5

            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
            0
            • V Offline
              V Offline
              VincentLiu
              wrote on last edited by
              #6

              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
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved