Cannot connect signal to slots



  • 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



  • 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.



  • 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~



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



  • 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.



  • 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);
        }
    

Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.