首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >QList<QList<QString>>传入QML

QList<QList<QString>>传入QML
EN

Stack Overflow用户
提问于 2017-08-21 20:44:47
回答 2查看 4.4K关注 0票数 6

我正试图将一个2d QList作为一个Q_PROPERTY传递到QML中,但是,在QML中,我无法真正访问任何信息。

一些代码:

c++:q_property由构造函数中的q_invokable函数填充:

代码语言:javascript
复制
void Class::createNewGameArray(){
QList<QList<QString>> testArray;

for( int i = 0; i < _intervals.size(); ++i) {
    QList<QString> innerArray;
    testArray.append(innerArray);
        testArray[i].append(_intervals[i]);
        testArray[i].append("Audio");
}
for( int i = 0; i < _intervals.size(); ++i) {
    QList<QString> innerArray;
    testArray.append(innerArray);
        testArray[i+12].append(_intervals[i]);
        testArray[i+12].append("Text");
}
 std::random_shuffle(testArray.begin(),testArray.end());
Class::setGameArray(testArray);
emit gameArrayChanged(_newGameArray);

返回以下内容:

代码语言:javascript
复制
(("M7", "Text"), ("M3", "Text"), ("m3", "Text"), ("M6", "Audio"), ("TT", "Audio"), ("P4", "Text"), ("m7", "Audio"), ("m2", "Text"), ("m6", "Audio"), ("m6", "Text"), ("M7", "Audio"), ("P5", "Text"), ("P4", "Audio"), ("m2", "Audio"), ("M2", "Audio"), ("M3", "Audio"), ("P5", "Audio"), ("m3", "Audio"), ("M6", "Text"), ("TT", "Text"), ("m7", "Text"), ("Oct", "Audio"), ("Oct", "Text"), ("M2", "Text"))

这正是我想要的。

我在main.cpp中这样设置了main.cpp:

代码语言:javascript
复制
Class object;

QQmlApplicationEngine engine;
QQmlContext* context = engine.rootContext();

context->setContextProperty("object", &object);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

然而,在qml中,我只得到

qml: QVariant(QList<QList<QString> >)

我无法用它做任何事。

理想情况下,我的目标是能够以这种方式从qml访问2d qlist:

object.gameArray //返回“文本”

我可以用普通的QLists (没有2d)来完成这个任务。任何帮助都将不胜感激!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-10-04 06:49:36

QML本质上并不理解QLists,因此通常不可能传入任何类型的QList并使QML能够访问列表中的项。

但是,QML引擎确实支持几种特定类型的QList:

  • QList<QObject *>
  • QList<QVariant>
  • QStringList -(不是QList<QString>__!)

因此,如果您可以使用上述三种类型的任意组合来构造列表,那么您就可以有一个有效的解决方案。在您的用例中,我建议使用以下结构:

QList<QVariant(QStringList)>

在我们尝试之前最后一个音符..。仅仅因为这会奏效,并不一定意味着这是一个好主意。QList内容在运行时被复制到Javascript数组,因此,从C++对任何列表的任何微小更新都会导致整个列表被重构为一个新的Javascript数组,这可能会很昂贵。

现在,让我们试试.

myclass.h

代码语言:javascript
复制
#ifndef MYCLASS_H
#define MYCLASS_H
#include <QStringList>
#include <QVariant>

class MyClass : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QList<QVariant> variantList READ variantList NOTIFY variantListChanged)

public:
    explicit MyClass(QObject *parent = nullptr) : QObject(parent),
        m_variantList({
                      QStringList({ "apple", "banana", "coconut" }),
                      QStringList({ "alice", "bob", "charlie" }),
                      QStringList({ "alpha", "beta", "gamma" })
        }) { }

    QList<QVariant> variantList() const { return m_variantList; }

signals:
    void variantListChanged();

public slots:

private:
    QList<QVariant> m_variantList;
};

#endif // MYCLASS_H

main.qml

代码语言:javascript
复制
import QtQuick 2.7
import QtQuick.Controls 2.0

ApplicationWindow {
    visible: true
    width: 640
    height: 480

    Column {
        id: column

        // will add the strings here from the handler below
    }

    Component.onCompleted: {
        console.log("variantList length %1".arg(myClass.variantList.length))

        for (var i = 0; i < myClass.variantList.length; i++) {

            console.log("stringList %1 length %2".arg(i).arg(myClass.variantList[i].length))

            for (var j = 0; j < myClass.variantList[i].length; j++) {
                // print strings to the console
                console.log("variantList i(%1), j(%2) = %3".arg(i).arg(j).arg(myClass.variantList[i][j]))

                // add the strings to a visual list so we can see them in the user interface
                Qt.createQmlObject('import QtQuick 2.7; Text { text: "i(%1), j(%2) = %3" }'.arg(i).arg(j).arg(myClass.variantList[i][j]), column)
            }
        }
    }
}

main.cpp

代码语言:javascript
复制
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "myclass.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;

    MyClass myClass;
    engine.rootContext()->setContextProperty("myClass", &myClass);

    engine.load(QUrl(QLatin1String("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}

运行时输出

代码语言:javascript
复制
qml: variantList length 3
qml: stringList 0 length 3
qml: variantList i(0), j(0) = apple
qml: variantList i(0), j(1) = banana
qml: variantList i(0), j(2) = coconut
qml: stringList 1 length 3
qml: variantList i(1), j(0) = alice
qml: variantList i(1), j(1) = bob
qml: variantList i(1), j(2) = charlie
qml: stringList 2 length 3
qml: variantList i(2), j(0) = alpha
qml: variantList i(2), j(1) = beta
qml: variantList i(2), j(2) = gamma

..。它的作用是:)

票数 9
EN

Stack Overflow用户

发布于 2017-08-21 21:01:35

自动转换只适用于几种特定类型的容器,仅此而已。仅仅因为转换A工作,而转换B工作,并不意味着转换A也将工作。

在所有自动转换不起作用的情况下,您几乎可以忘记使用[]操作符。

然而,变体列表可能只起作用。我还没有亲自测试过,但希望渺茫。但是,在将这些内容传递给QML之前,您必须手动进行转换。

一种非常有效的方法是创建访问器函数,例如QString Class::get(int row, int col),或者您可以有单独的访问器来选择一行,然后将结果传递给另一个函数,以选择一个列来为您提供字符串。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45805244

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档