ulatekh
ulatekh

Reputation: 1500

QObject::connect: signal not found (in subclass)

I've managed to boil down my app's problem to a small sample.

I'm unable to connect a signal defined in a base class.

Here's my simple wtf.pro file:

QT += widgets
SOURCES = wtf.cpp TableViewSubclass.cpp
HEADERS = TableViewSubclass.h

Here's my TableViewSubclass.h:

#include <QTableView>

class TableViewSubclass : public QTableView
{
    Q_OBJECT

public:
    TableViewSubclass(QWidget *parent = nullptr)
        : QTableView(parent) {}
    virtual ~TableViewSubclass() {}

    void setup();

private slots:
    void viewColumnCountChanged(int oldcount, int newcount);
};

Here's my TableViewSubclass.cpp. For good measure, I tried two ways to connect the signal to the slot.

#include "TableViewSubclass.h"

void
TableViewSubclass::setup()
{
    // Trying to use &QTableView::columnCountChanged for parameter 2
    // gives me a compiler error, for being protected within this context.
    QObject::connect(this, &TableViewSubclass::columnCountChanged,
        this, &TableViewSubclass::viewColumnCountChanged);
    QObject::connect(this, SIGNAL(columnCountChanged(int,int)),
        this, SLOT(viewColumnCountChanged(int,int)));
}

void
TableViewSubclass::viewColumnCountChanged(int /* oldcount */, int /* newcount */)
{
    // TODO
}

And finally, the main wtf.cpp:

#include <QApplication>
#include "TableViewSubclass.h"

int
main(int argc, char **argv)
{
    QApplication app(argc, argv);

    TableViewSubclass oView;
    oView.setup();
}

I build with qmake-qt5 wtf.pro and make, then run with ./wtf. It outputs:

QObject::connect: signal not found in TableViewSubclass
QObject::connect: No such signal TableViewSubclass::columnCountChanged(int,int)

The signal is defined in QTableView, the base class for TableViewSubclass. How is it not found? It seems like I'm missing something obvious and stupid.

The above example was run under Fedora Core 35 and Qt 5.15.2, but was first encountered in MinGW, also with Qt 5.15.2.

Upvotes: 0

Views: 582

Answers (1)

BNilsou
BNilsou

Reputation: 895

According to the Qt documentation, the countColumnChanged(int, int) is a slot and not a signal. You can override this protected slot in your derived class:

#include <QTableView>

class TableViewSubclass : public QTableView
{
    Q_OBJECT

public:
    TableViewSubclass(QWidget *parent = nullptr)
        : QTableView(parent) {}
    virtual ~TableViewSubclass() {}

    void setup();

protected slots:
    void columnCountChanged(int oldcount, int newcount) override;
};

The slot is called by the base class (QTableView) each time the column count changes. Therefore, there is no need to connect any signal to this slot to update the behavior in your derived class.

Upvotes: 3

Related Questions