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 Updated to NodeBB v4.3 + New Features

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