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, @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:
-
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 ?
-
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~
-
-
Hi,
does the call toQObject::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.@m.sue
BTW, the connections are successful in both ways with/without writing kSVM->save("svmModel.yml"). -
Hi,
below is the emitters of both, note that the signals are emitted at the end of each function. Thanks.- 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); }
- signalSVMReady