2

I would be very grateful if you could help me solve this :

I have a subclass of QPushButton called Square and what I want to do is to change the icon of one instance by clicking another instance of Square. I have a vector of vectors of pointers to squares called sqMatrix :

std::vector< std::vector<Square*> > sqMatrix;

and I want to do this from the main.cpp :

QObject::connect(sqMatrix.at(0).at(0),SIGNAL(clicked())
                ,sqMatrix.at(5).at(5),SLOT(discoverThis()));

I have tried lots of things and done many researches but I cannot figure out how to do it properly.

Here I'm having the error :

QObject::connect: No such slot QPushButton::discoverThis()

Here are the corresponding .h and .cpp files :

square.h :

#ifndef SQUARE_H
#define SQUARE_H

#include <QPushButton>

class Square : public QPushButton
{
public:
    Square(const QString &text, QWidget *parent = 0);
    void mousePressEvent(QMouseEvent *e);
public slots:
    void discoverThis();
signals:
    void clicked();
};

#endif // SQUARE_H

square.cpp :

#include <QApplication>
#include <string>
#include "square.h"

#include <QMouseEvent>

Square::Square(const QString &text, QWidget *parent) : QPushButton(text,parent) {
    setFixedSize(16,16);
    setIcon(QIcon(":/images/images/square.png"));
}

void Square::mousePressEvent(QMouseEvent *e) {
    if(e->button() == Qt::LeftButton) {
        setIcon(QIcon(":/images/images/1.png"));
    }
    if(e->button() == Qt::RightButton) {
        setIcon(QIcon(":/images/images/flag.png"));
    }
}

void Square::discoverThis() {
    setIcon(QIcon(":/images/images/8.png"));
}

void Square::clicked() {
}

I'm a begginer so please be indulgent. I'm sure there are atrocious mistakes in my code.

Any help would be very appreciated.

Have a nice day.

  • possible duplicate of [Qt question: What does the Q\_OBJECT macro do? Why do all Qt objects need this macro?](http://stackoverflow.com/questions/1368584/qt-question-what-does-the-q-object-macro-do-why-do-all-qt-objects-need-this-ma) – Kuba hasn't forgotten Monica Apr 03 '14 at 15:32

1 Answers1

4

The problem is you missed the Q_OBJECT macro in the class. See the "HERE" arrow.

#ifndef SQUARE_H
#define SQUARE_H

#include <QPushButton> 

class Square : public QPushButton
{
    Q_OBJECT     <---- HERE!

public:
    Square(const QString &text, QWidget *parent = 0);
    void mousePressEvent(QMouseEvent *e);

public slots:
    void discoverThis();

// +++ The signal "clicked()" is already declared in QPushButton +++
//signals:
//    void clicked();
};

#endif // SQUARE_H

Each subclass of a QObject needs the Q_OBJECT macro. This also triggers usually the moc (Meta Object Compiler) which automatically creates some additional method implementations (e.g. for signals and meta object handling.)

Flovdis
  • 2,945
  • 26
  • 49
  • Specifically, from Qt's perspective an object isn't an instance of a given class without the `Q_OBJECT` macro. It's just an instance of the base class. – Kuba hasn't forgotten Monica Apr 03 '14 at 15:31
  • Hi, thank you for your answers @flovdis and @kuba-ober. But when I do this I have this error: undefined reference to `vtable for Square' That's why I didn't put it. – Dr. N. Klein Apr 03 '14 at 15:54
  • @kuba-ober I'm using Qt Creator 3.0.1 (based on Qt 5.2.1 (MSVC 2010, 32 bit)) on Winsows 8. Didn't do any configurations, I'm compiling directly using Run. Where should I look? – Dr. N. Klein Apr 03 '14 at 16:03
  • @KubaOber Oh! I clicked on execute qmake and now it's OK but I have another error: multiple definition of 'Square::clicked()' – Dr. N. Klein Apr 03 '14 at 16:06
  • 1
    @KarimKecir That should be obvious enough: don't define it multiple times. Specifically, why would you provide an implementation of a signal - especially, one that is *empty*? Your signal would never work if it doesn't do anything. `moc` generates an implementation for you - one that actually activates the signal and invokes the connected slots. – Kuba hasn't forgotten Monica Apr 03 '14 at 16:07
  • @KubaOber I just figured it out, sorry! Now I have no error but clicking on the first square doesn't affect the (5,5) square. Is there something wrong with this : QObject::connect(sqMatrix.at(0).at(0),SIGNAL(clicked()) ,sqMatrix.at(5).at(5),SLOT(discoverThis())); – Dr. N. Klein Apr 03 '14 at 16:10
  • @KubaOber Oh! It's working! I just had to remove one line that was actually executing discoverThis(). Thank you for your help! – Dr. N. Klein Apr 03 '14 at 16:18