如何使用C ++在QML ListModel中插入ListElement?

时间:2012-02-02 19:31:41

标签: qt qml

好吧,我正在学习使用QML,我有一个疑问。在我的例子中,我有一个ListModel和QML的ListElements,我有一个带有矩形,PathView等的QML主文件。

我也有一个QWidget,而不是我的主窗口。在这个QWidget中,我将QML UI包含在一个组件中。 OK!

如何使用C ++处理QML ListElements?
注意:当我说“处理”时,我想说例如包含一个元素。

以下是我的代码的一些部分......

包含我的ListElement的QML,名为“Menu1”:

import QtQuick 1.0

ListModel {
    id: listMovieModel
    ListElement { name: "Image 1"; iconSource: "pics/image_1.jpg" }
    ListElement { name: "Image 2"; iconSource: "pics/image_2.jpg" }
    ListElement { name: "Image 3"; iconSource: "pics/image_3.jpg" }
    ListElement { name: "Image 4"; iconSource: "pics/image_4.jpg" }
    ListElement { name: "Image 5"; iconSource: "pics/image_5.jpg" }
    ListElement { name: "Image 6"; iconSource: "pics/image_6.jpg" }
}

我的主要QML:

Rectangle {
    width: 500
    height: 600
    color: "transparent"

    PathView {
        id: view
        focus: true
        width: parent.width
        height: parent.height + y
        y: -150
        model: Menu1 {} //First QML showed
        delegate: Image {
            source: iconSource
            width: 64
            height: 90
            scale: PathView.isCurrentItem ? 3.5 * y / parent.height : 2.0 * y / parent.height
            z: y
            smooth: true
        }
        path: MyGeometricFigure { //This a another file, but is confidential
            width: view.width
            height: view.height
        }
        preferredHighlightBegin: 0
        preferredHighlightEnd: 0
        highlightRangeMode: PathView.StrictlyEnforceRange
        Keys.onLeftPressed: decrementCurrentIndex()
        Keys.onRightPressed: incrementCurrentIndex()
    }
}

因为我像我的QWidget一样使用QML:

MainForm::MainForm(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MainForm)
{
    ui->setupUi(this);
    this->resize(1024, 576);

    QDeclarativeView *myQMLTest = new QDeclarativeView(QUrl::fromLocalFile("myMainQML.qml"));
    myQMLTest->setStyleSheet(QString("background: transparent; width: 600px"));

    this->ui->frameListVideoGallery->layout()->addWidget(myQMLTest);
    myQMLTest->setFocus();
    myQMLTest->installEventFilter(this);
}

我看到了一些关于此的文章,但我无法使用C ++更改我的LisModel。我在这里看到了http://doc.qt.nokia.com/4.7/qdeclarativemodels.html#c-data-models,这里是使用PathView http://doc.qt.nokia.com/4.7/qdeclarativeexamples.html

的示例

有人可以帮助我吗?

谢谢!

3 个答案:

答案 0 :(得分:8)

好的。我想你可以这样做:

在主要的QML文件中添加简单的功能。

Rectangle {
    // ...

    function append(newElement) {
        view.model.append(newElement)
    }

    PathView {
        id: view

        // ...

        model: Menu1 {} //First QML showed

        // ...
    }
}

此方法只会从ListModel调用相应的方法。您可以使用更多支持的方法find there

然后您只需要从C ++代码调用此方法。你可以这样做:

MainForm::MainForm(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MainForm)
{
    ui->setupUi(this);
    this->resize(1024, 576);

    QDeclarativeView *myQMLTest = new QDeclarativeView(QUrl::fromLocalFile    ("myMainQML.qml"));
    myQMLTest->setStyleSheet(QString("background: transparent; width: 600px"));

    QVariantMap newElement;  // QVariantMap will implicitly translates into JS-object
    newElement.insert("name",       "Image 13"         );
    newElement.insert("iconSource", "pics/image_13.jpg");

    QMetaObject::invokeMethod(
        myQMLTest->rootObject(),                          // for this object we will call method
        "append",                                         // actually, name of the method to call
        Q_ARG(QVariant, QVariant::fromValue(newElement))  // method parameter
    );

    this->ui->frameListVideoGallery->layout()->addWidget(myQMLTest);
    myQMLTest->setFocus();
    myQMLTest->installEventFilter(this);
}

您应该查看this以获取更多信息。

您还可以选择另一种方法:通过qml属性传递一些数据(使用QDeclarativeEngine和QDeclarativeContext),然后在JavaScript代码中处理这些数据和列表模型。

答案 1 :(得分:1)

我想让@GooRoo的答案对Qt初学者更加完整/有用。如果您使用Qt Creator,您将使用QmlApplicationViewer从模板开始。要应用GooRoo的答案,你必须做这样的事情(感谢http://www.lothlorien.com/kf6gpe/?p=309):

CPP:

Q_DECL_EXPORT int main(int argc, char *argv[])
{
    QScopedPointer<QApplication> app(createApplication(argc, argv));
    QScopedPointer<QmlApplicationViewer> viewer(QmlApplicationViewer::create());

    viewer->setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
    viewer->setMainQmlFile(QLatin1String("qml/mydemo/main.qml"));
    viewer->showExpanded();

    QMetaObject::invokeMethod(
        (QObject *)viewer->rootObject()->findChild<QObject *>("myModel"), // QML item
        "test"                           // name of the method to call
                                         // without parameters
    );

    return app->exec();
}

QML:

PageStackWindow {
    id: mainApp
    ...

    ListModel {
        id: myModel
        objectName: myModel //THIS IS NEEDED BY findChild()
        ...
        function test() {
            console.log("TEST OK");
        }
    }

    Page {
        ...
    }
}

答案 2 :(得分:0)

这是从C ++在QML TableView中填充数据的另一个完整示例。 请原谅错误的变量名。我只是出于测试目的而制作它。

我使用了QVariantList,并用QVariantMap个对象填充了它。


在这里,通过将QML表的两列(即whatsession_name中的for循环中填充了多个数据,方法是将它们放入QVariantMap中,然后插入{{ 1}}在QVariantMap中。

HH.h

QVariantList

在这里,我已经使用#ifndef HH_H #define HH_H #include <QVariant> class AA : public QObject { Q_OBJECT QVariantList m_gname; public: Q_PROPERTY(QVariantList gname READ gname WRITE setGname NOTIFY gnameChanged) AA() { QVariantList q; for(int i = 0; i < 10; i++) { QVariantMap p; p.insert("what", "qq"); p.insert("session_name", "aa"); q.push_back(p); } setGname(q); } QVariantList gname() const { return m_gname; } public slots: void setGname(QVariantList gname) { if (m_gname == gname) return; m_gname = gname; emit gnameChanged(m_gname); } signals: void gnameChanged(QVariantList gname); }; #endif // HH_H 注册了我在上面创建的类qmlRegisterType

main.cpp

AA

在QML中,我通过#include <QGuiApplication> #include <QQmlApplicationEngine> #include "HH.h" int main(int argc, char *argv[]) { QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication app(argc, argv); qmlRegisterType<AA>("ZZZ", 1, 0, "AA"); QQmlApplicationEngine engine; const QUrl url(QStringLiteral("qrc:/main.qml")); QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, &app, [url](QObject *obj, const QUrl &objUrl) { if (!obj && url == objUrl) QCoreApplication::exit(-1); }, Qt::QueuedConnection); engine.load(url); return app.exec(); } 创建了一个TableView。它具有两列,即QtQuick.Controls 1.4what。我在这里及其上的session_name类中创建了一个对象AA,名为Component.onCompleted

像这样:

append

main.qml

mymodel.append( gname )