简体   繁体   中英

How to send a 1 dimensional integer array from QML to C++?

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") ) )
  • How do I read this QVariantList inside QVariant, ie, lets say I want to read this first element of the array, that is QVariant(QString, “2”), then the other and the other. This looks very complicated like this.
  • All I need is to pass an array of integers from QML to C++, so I can read this array. I dont want to use QVariant or a QVariantList, unless I have to as I see no other way to do it.

Does anyone have any suggestions?

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.

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?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM