Reputation: 113
So I have a signal:
QML:
signal qmlSendWorkflowIdsArraySignal(variant workflowIdsArray)
JS:
sendToCppWorkflowIdsArray(arrayOfWorkflowIds);
C++:
QObject::connect(qmlMainContentItemObject, SIGNAL(qmlSendWorkflowIdsArraySignal(QVariant)), &myController, SLOT(qmlToCppWorkflowIdsArraySlot(QVariant)));
C++ slot:
void qmlToCppWorkflowIdsArraySlot(QVariant workflowIdsArray)
{
qDebug() << " +++++++++++++++ Cpp Array slot has been called: "<<workflowIdsArray;
}
Output:
+++++++++++++++ Cpp Array slot has been called:
QVariant(QVariantList, (QVariant(QString, "2") , QVariant(QString, "3") , QVariant(QString, "4") ) )
Does anyone have any suggestions?
Upvotes: 6
Views: 8564
Reputation: 22936
One way to pass an array from QML to C++ is as follows:
Create a class which is going to receive that integer array:
DataReceiver.h
#include <QQuickItem>
#include <QList>
class Receiver : public QQuickItem
{
private:
Q_OBJECT
Q_PROPERTY (QList<int> xx READ xx WRITE setXX NOTIFY xxChanged)
QList<int> m_xx;
public:
Receiver (QQuickItem *parent = 0) {}
QList<int> xx() const
{
return m_xx;
}
public slots:
void setXX (QList<int> arg)
{
if (m_xx != arg) {
m_xx = arg;
emit xxChanged (arg);
}
}
signals:
void xxChanged (QList<int> arg);
};
In main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "DataReceiver.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
const char* ui = "HELLO"; // @uri HELLO
qmlRegisterType <Receiver> (ui, 1, 0, "DataReceiver");
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
return app.exec();
}
In QML (main.qml)
import QtQuick 2.2
import QtQuick.Window 2.1
import HELLO 1.0
Window
{
visible: true
width: 360
height: 360
id: head
property variant myArray: [1,2,3]
DataReceiver
{
id: dataReceiver
xx: head.myArray
}
}
You might also like to check this:
How to push values to QML property variant two dimensional array - dynamically?
Upvotes: 3
Reputation: 5466
QML supports conversion between QList and Javascript values, for a limited amount of types. See the documentation on type conversion for details. No need to use QVariant for these.
With that, calling C++ methods from JS is easy:
tester.h:
class Tester : public QObject
{
Q_OBJECT
public:
Q_INVOKABLE void bla(const QList<QString> &strings) {
qDebug() << "Tester::bla():" << strings;
}
};
main.cpp:
Tester tester;
viewer.engine()->rootContext()->setContextProperty("_tester", &tester);
QML:
onClicked: _tester.bla(["asdf", "foo", "bar"]);
Note that I didn't use a signal here - in your case, the signal was connected from the C++ code, where the C++ code accessed an object from the QML layer. I try to avoid that, to force a cleaner separation between the C++ and QML layers, which makes it possible to completely change the QML code without needing to adapt the C++ layer. The C++ layer should never reach into the QML layer, the other way around is fine though.
Upvotes: 6