0
votes

I've created a Qt Quick 2.5 app and connected signals and slots to my C++ module, I only can send signals from C++ and activate QML slots, but I can't receive QML signals on Qt side.

Here is main.cpp:

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

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/qml/main.qml")));

    AlfredApp(engine.rootObjects().first());

    return app.exec();
}

here is my QML code which holds the signal:

MouseArea {
    id: mainButtonMouseArea
    objectName: "mainButtonMouseArea"
    anchors.fill: parent

    signal signalClicked()

    onClicked: {
        console.log("clicked")
        signalClicked()
    }
}

I always get the console message from QML when I click on the MouseArea.

Here is my c++ constructor:

AlfredApp::AlfredApp(QObject* viewRootObject, QObject* parent)
    : QObject(parent), d(new Private)
{
    d->viewRootObject = viewRootObject;
    d->viewMainButton = viewRootObject->findChild<QObject*>("mainButton");
    d->viewMainButtonIcon = viewRootObject->findChild<QObject*>("mainButtonIcon");
    d->viewMainButtonMouseArea = viewRootObject->findChild<QObject*>("mainButtonMouseArea");

    // Signals/Slots connection

    connect(d->viewMainButtonMouseArea, SIGNAL(signalClicked()),
        this, SLOT(mainButtonClicked()));

    connect(this, SIGNAL(signalListening()),
        d->viewMainButtonIcon, SLOT(listening()));

    connect(this, SIGNAL(signalProcessing()),
        d->viewMainButtonIcon, SLOT(processing()));
}

Here is my slot that never gets called:

void AlfredApp::mainButtonClicked()
{
    qDebug() << "Main Button Clicked";
}

BTW, are there some qml code examples that have slots/function that respond normally to C++ signals

1
Check return value of connect call. Is it true or false? Also check console output for runtime warnings. - hyde
@hyde No problems in the connection at all, it returns true - Mohamed Anwer
First of all use the new Qt 5 style connect: wiki.qt.io/New_Signal_Slot_Syntax, wich gives you much better compile time checking of signals and slots. Then (I think) defining a signal in Qml in not possible when you want to use it in C++. - Simon Warta
I would suggest creating a MVCE, ideally with just two files (main.cpp and main.qml). (If you don't know how to create a nice 2-file Qt/QML test case, you can use this answer as an example, the important bit is #include "main.moc" at the end of main.cpp). - hyde
@SimonWarta You can't use the new connect syntax with QML (or other dynamic) signals and slots, for obvious reasons (signal and slot names are not known at compile time). - hyde

1 Answers

0
votes

Just for testing, could you connect the signal and the slot in main.cpp?

Something like this:

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

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/qml/main.qml")));

    QObject *rootObj = engine.rootObjects().first();
    QObject *item = rootObj->findChild<QObject*>("mainButtonMouseArea");

    AlfredApp alfredapp(rootObj);

    QObject::connect(item, SIGNAL(signalClicked()),
                         &alfredapp, SLOT(mainButtonClicked()));

    return app.exec();
}

This should work. If not, try the idea suggested by @hyde.

Here you have the sample code.