Reputation: 1103
I am trying to connect a signal from QML to a SLOT from Qt. The signal passes a QList variable.
QML:
property var cases: ["A", "B", "C"]
signal casesClicked(list cases)
Qt:
d->m_view->setSource(QUrl("qrc:/qml/main.qml"));
d->m_item = d->m_view->rootObject();
QObject::connect(d->m_item, SIGNAL(casesClicked(QList<QString>)), this, SLOT(onCasesClicked(QList<QString>)));
The issue I am having is that I don't know how to declare QList from the QML side, so it is taken directly. If I declare it with:
signal casesClicked(var cases)
then, the signal is not connected, and I if I declare it as a list or an Array it says "Invalid signal parameter type: list/Array"
Any tip? I don't have any problems with single int, bool or string. Thanks,
Upvotes: 2
Views: 1925
Reputation: 244282
I do not think it is appropriate to make the connection on the C ++ side since when compiling it does not know the signal created in QML, a possible solution is to make the connection on the QML side. In the following I show an example
main.cpp
#include <QGuiApplication>
#include <QQuickView>
#include <QQmlContext>
#include <QDebug>
class Test: public QObject{
QQuickView *view;
Q_OBJECT
public:
Test(QObject *parent=Q_NULLPTR):QObject(parent)
{
view = new QQuickView;
view->rootContext()->setContextProperty("Test", this);
view->setSource(QUrl("qrc:/main.qml"));
view->show();
}
public slots:
void onCasesClicked(QVariantList cases){
qDebug()<<cases;
}
};
int main(int argc, char *argv[])
{
#if defined(Q_OS_WIN)
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
QGuiApplication app(argc, argv);
Test test;
return app.exec();
}
#include "main.moc"
main.qml
import QtQuick 2.9
Item {
id: it
visible: true
width: 640
height: 480
signal casesClicked(var cases)
MouseArea {
id: mouseArea
anchors.fill: parent
onClicked: it.casesClicked(["B", 1, "D"])
}
Connections{
target: it
onCasesClicked: Test.onCasesClicked(cases)
}
// or
// onCasesClicked: Test.onCasesClicked(cases)
// if the connection is made in the same item
}
Output:
(QVariant(QString, "B"), QVariant(int, 1), QVariant(QString, "D"))
Upvotes: 1
Reputation: 49329
IIRC JS arrays are converted to QVariantList
in C++, so try using that instead.
EDIT:
Ok, it appears that although the above is the default automatic conversion, it doesn't work for some reason when the connection is made from C++.
In this scenario the signal value is converted to a QVariant
instead, which can directly be converted to a QStringList
which is convenient. However that approach will not work if you have a JS array with different data types in it, which is perfectly legal and quite frequently used in JS.
QVariantList
will still work if you pass the JS array as a parameter to a C++ function call thou. So you can iterate each value and handle a "polymorphic" array.
Whether or not it is recommended practice to create connections from to QML objects from C++ depends on the usage scenario, overall, I'd say that it isn't. The recommended practice is to expose the C++ core interface to QML and do the connections from there and to avoid touching any QML from C++ whatsoever. But there are a few corner cases where exceptions can be made.
Upvotes: 1