No such slot error
-
Hi,
I am making a small application (C++) (4.7.4) to view a webcam with OpenCV and Qt
I have three main classes:
ImageDisplay :inherits QWidget, converts and displays the OpenCV image format by using SetPixmap (this works)
has a slot to receive an image to display
CamThread : inherits QThread, uses OpenCV to capture images from the webcam, has a signal to give the ImageDisplay a pointer to the updated image
the_window : inherits QMainWindow, has an ImageDisplay set as the central Widget Has a QThread with a signal connected to the ImagDisplay's slot.
I've been searching here, and yes, i do have Q_OBJECT in all my classes and the signatures are the same.I have a CamThread and a ImagDisplay in the the_window, and i connect the signal to the slot in the constructor of the_window: @connect(th,SIGNAL(MatUpdate(cv::Mat)),this->pct_frame,SLOT(update(cv::Mat)));@
where cv::Mat is the OpenCV image type
th is the CamThread pointer and pct_frame is the ImageDisplay pointer.
Qt prints that ImageDisplay has no slot called update(cv::Mat) at runtime
Thanks for your help!
-tim
Main function (main.cpp):
@#include <qapplication.h>#include "the_window.h"
using namespace cv;
int main(int argc, char* argv[]){
QApplication myapp(argc,argv);
the_window* x = new the_window();
x->show();
return myapp.exec();
}@the_window class:
(the_window.h)@
#ifndef THE_WINDOW_H
#define THE_WINDOW_H
#include "imagedisplay.h"
#include "camthread.h"#include <QtGui>
class the_window : public QMainWindow
{
Q_OBJECTpublic:
the_window(QWidget *parent = 0);
~the_window();private:
ImageDisplay* pct_frame;
CamThread* th;
};#endif // THE_WINDOW_H@
(the_window.cpp)
@#include "the_window.h"the_window::the_window(QWidget *parent)
: QMainWindow(parent)
{
pct_frame = new ImageDisplay(this);
th = new CamThread(this);
th->start();
connect(th,SIGNAL(MatUpdate(cv::Mat)),this->pct_frame,SLOT(update(cv::Mat)));
setCentralWidget(pct_frame);
}the_window::~the_window()
{
}@ImageDisplay class:
(imagedisplay.h)@#ifndef IMAGEDISPLAY_H
#define IMAGEDISPLAY_H#include <QWidget>
#include <core/core.hpp>
#include <qlabel.h>
#include <qboxlayout.h>
using namespace cv;class ImageDisplay : public QWidget
{
Q_OBJECTpublic:
ImageDisplay(QWidget *parent = 0);
~ImageDisplay();private:
QImage* the_image;
QLabel* widget_frame;
QImage* GetQImage(Mat img);
QBoxLayout* l;
QImage* ImageDisplay::IplImage2QImage(IplImage *iplImg);public slots:
void update(Mat img);
};#endif // IMAGEDISPLAY_H@
(imagedisplay.cpp)
@#include "imagedisplay.h"
#include "handleEx.h"
#include <core/core.hpp>
#include <cv.h>
#include <imgproc/imgproc.hpp>
#include <highgui/highgui.hpp>
#include <qmessagebox.h>
#include <string>
#include <iostream>ImageDisplay::ImageDisplay(QWidget *parent)
: QWidget(parent){
l = new QBoxLayout(QBoxLayout::LeftToRight, this);
widget_frame = new QLabel(tr("Testing, 1,2,3"),this);
l->addWidget(widget_frame);
setLayout(l);
}ImageDisplay::~ImageDisplay()
{
}void ImageDisplay::update(Mat img){
IplImage the_img = img;
widget_frame->setPixmap(QPixmap::fromImage(*IplImage2QImage(&the_img)));
}QImage* ImageDisplay::IplImage2QImage(IplImage *iplImg)
{
// snip
}@CamThread class:
camthread.h:
@#ifndef CAMTHREAD_H
#define CAMTHREAD_H#include <QThread>
#include <core/core.hpp>
#include <highgui\highgui.hpp>
#include <iostream>
#include "imagedisplay.h"class CamThread : public QThread
{
Q_OBJECTpublic:
CamThread(QObject *parent);
~CamThread();protected:
void run();signals:
void MatUpdate(cv::Mat it);
void error(QString errTxt);
};#endif // CAMTHREAD_H@
CamThread implementation (camthread.cpp)
@#include "camthread.h"
#include "imagedisplay.h"CamThread::CamThread(QObject *parent)
: QThread(parent)
{
}CamThread::~CamThread()
{
}void CamThread::run(){
cv::Mat frame; // Temp frame
cv::VideoCapture cap(0); // Video capture.
// argument of 0 means use first camera
if(!cap.isOpened()){ /// something screwed up
std::cout << "Could not open video capture. :( ";
emit(error(QString("Video opening failed")));
return;
}
for(;;){
cap >> frame;
emit(MatUpdate(frame));
}
}
@ -
Fully qualify the names in your signals/slots signatures (in the .h) and in the connect statements.
-
could you please give me an example of that
This doesn't work: @connect(this->th,SIGNAL(CamThread::MatUpdate(cv::Mat)),
this->pct_frame,SLOT(CamThread::update(cv::Mat)));@
It says
Object::connect: No such signal CamThread::CamThread::MatUpdate(cv::Mat)
EDIT: some of the code in the post was covered up by the bit at the side. -
No, that's wrong -- you should qualify the ARGUMENTS of your slots, not the names of the methods (they're looked up in the right class, since you pass an object there).
In your slot declaration you're not qualifying Mat:
@
public slots:
void update(Mat img);
};
@ -
The other method would be to get rid of the qualification in your connect and class definition. The SIGNAL and SLOT macros are triggering simply said a string matching. If you are using at one point the qualification and in the other not, it has to fail.
So the code should look more like:
@
connect(th,SIGNAL(MatUpdate(cv::Mat)),pct_frame,SLOT(update(cv::Mat)));
@@
public slots:
void update(cv::Mat img);
@@
signals:
void MatUpdate(cv::Mat it);
@or the other possibility:
@
connect(th,SIGNAL(MatUpdate(Mat)),pct_frame,SLOT(update(Mat)));
@@
public slots:
void update(Mat img);
@@
signals:
void MatUpdate(Mat it);
@