atin
atin

Reputation: 63

QObject::connect: No such signal while connecting qml signals in c++ Qt 5.3

I am a newbie in using Qt framework. I am not sure where I am going wrong. I tried looking at many related material but still could not figure it out.

I am getting "QObject::connect: No such signal error.." while I have declared a signal in a qml file.

Here is the code:

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    //QDeclarativeView view;
    QQmlApplicationEngine engine;

    testclass dsc;

    QQmlComponent component(&engine, QUrl(QStringLiteral("qrc:///test.qml")));
    while(component.isLoading());
    if (component.isError()) {
        qWarning() << component.errors();
    }

    QObject *object = component.create();
    QQuickItem *item = qobject_cast<QQuickItem*>(object);

    QObject::connect(item,SIGNAL(dsa(QVariant)),&dsc,SLOT(testslot(QVariant)));
    QObject::connect(&dsc,SIGNAL(dummysignal(QVariant)),&dsc,SLOT(testslot(QVariant)));
    dsc.dummysignal(&dsc);
    qDebug("Entered :");
    engine.load(QUrl(QStringLiteral("qrc:///main.qml")));

    return app.exec();
}

qml file: test.qml

Item {
    width: 800
    height: 500
    signal dsa(var obj)
    SystemPalette { id: palette }
}

Test class: testclass.cpp

#include <QObject>

class testclass: public QObject
{
Q_OBJECT
public:
explicit testclass(QObject *parent = 0);

signals:
void dummysignal(QVariant);


public slots:


void testslot(QVariant);

};

I am getting this error:

QObject::connect: No such signal test_QMLTYPE_0::dsa(QVariant) in ..

Upvotes: 6

Views: 3902

Answers (3)

blino
blino

Reputation: 21

QVariant was the proper type to use in Qt 5.2 to map var signal parameters, but it has been changed in Qt 5.3 to map to QJSValue instead: Change C++ parameter type used for var parameters in QML declared signals

Though, this has been reverted in Qt 5.4, which will use QVariant again for var signal parameters: Revert mapping of var signal parameters to QJSValue

Upvotes: 2

dbrianj
dbrianj

Reputation: 472

The problem is that you're declaring the dsa signal parameter as a 'var' type, which is considered a javascript value by the qml engine. So this gets propagated into c++ as a QJSValue, and the signature of the signal you're trying to connect with is actually dsa(QJSValue).

If you want the signature to be dsa(QVariant), change your signal declaration in test.qml as follows:

// test.qml

Item {
  signal dsa(variant obj)

  width: 800
  height: 500

  SystemPalette { id: palette }
}

This should allow you to connect as you were trying with the statement

QObject::connect(item,SIGNAL(dsa(QVariant)),&dsc,SLOT(testslot(QVariant)));

(But first you should update the signature of your slot to void testslot(QVariant);...otherwise you'll just have the same problem on the flip side with a 'no such slot' error)

FWIW, here's a useful trick for debugging 'no such signal/slot' errors:

// Assuming you've instantiated QQuickItem* item
// This will print out the signature for every signal/slot on the object
// Make sure you include <QMetaObject>, <QMetaMethod>

const QMetaObject* metaObj = item->metaObject();
for (int i = 0; i < metaObj->methodCount(); ++i) {
    QMetaMethod method = metaObj->method(i);
    qDebug() << method.methodSignature();
}

Upvotes: 10

lappet
lappet

Reputation: 114

Add signal and slot

#include <QObject>

class testclass: public QObject
{
    Q_OBJECT
public:
    explicit testclass(QObject *parent = 0);

signals:
    void dsa(QVariant parameter) {
        //some code
    }

public slots:
    void testslot(QVariant parameter) {
        //some code here
    }

    void testslot();
};

Upvotes: 0

Related Questions