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_OBJECT

    public:
    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_OBJECT

    public:
    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_OBJECT

    public:
    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);
    };
    @


  • Moderators

    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);
    @


Log in to reply
 

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