How to insert ListElement into QML ListModel using C ++?

Ok, I'm learning how to work with QML, and I have one doubt. In my example, I have a ListModel with ListElements in QML, and I have a main QML file with a rectangle, PathView, etc.

I also have a QWidget than my main window. In this QWidget, I include the QML interface as a component. Ok!

How can I handle QML ListElements using C ++?
Note: when I say "process", I want to say, for example, include an element.

Below are some parts of my code ...

QML containing my ListElement called "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" } } 

My main 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() } } 

And since I use QML as a component for my QWidget:

 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); } 

I have seen some articles about this, but I cannot change my LisModel using C ++. I saw here http://doc.qt.nokia.com/4.7/qdeclarativemodels.html#c-data-models and here in the examples using PathView http://doc.qt.nokia.com/4.7/qdeclarativeexamples.html

Can someone help me?

Thanks!

+4
source share
2 answers

Good. I think you can do something like this:

A simple function has been added to your main QML file.

 Rectangle { // ... function append(newElement) { view.model.append(newElement) } PathView { id: view // ... model: Menu1 {} //First QML showed // ... } } 

This method will simply call the appropriate method from the ListModel. You can find more supported methods there .

Then you only need to call this method from C ++ code. You can do it as follows:

 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); } 

You should check this one for more information.

You can also choose another approach: pass some data through qml properties (using QDeclarativeEngine and QDeclarativeContext), and then process this data and your list model in JavaScript code.

+8
source

I want to make the answer from @GooRoo more complete / useful for beginners of Qt. If you are using Qt Creator, you will start with a template using QmlApplicationViewer. To apply the answer from GooRoo you need to do something like this (thanks 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 { ... } } 
+1
source

Source: https://habr.com/ru/post/1394464/


All Articles