How to insert ListElement in a QML ListModel using C++?
Solution 1
Alright. I think you can do something like this:
In your main QML-file add simple function.
Rectangle {
// ...
function append(newElement) {
view.model.append(newElement)
}
PathView {
id: view
// ...
model: Menu1 {} //First QML showed
// ...
}
}
This method will just call a corresponding method from ListModel. More supported methods you can find there.
Then all you need is to call this method from C++ code. You can do this in such manner:
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 for more information.
Also you can choose another approach: to pass some data via qml properties (using QDeclarativeEngine and QDeclarativeContext) and then handle this data and your list-model right in JavaScript code.
Solution 2
I want to make the answer from @GooRoo more complete/usefull to Qt beginners. If you use the Qt Creator, you will start with a template using QmlApplicationViewer. To apply the answer from GooRoo you have to do something like this (thanks to 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 {
...
}
}
Adriano Leal
I have worked with development systems since 2007 during my first trainee job. Here in Brazil I did a technical course focused in development systems (2005-2008). Currently I have a degree in IT by State University of Campinas (Unicamp), from 2009 to 2013, and have worked developing solutions for Digital TV at EiTV (www.eitv.com.br) company. At EiTV I have worked with C, C++ with Qt Framework, Ruby On Rails, Ginga NCL + Lua script on the Linux environment and some projects with C#. I like to play soccer, drink beer with friends, national pop rock and it's enough! =D Any doubt or interest let me know sending me a message to [email protected] Thanks, see you and don't worry... Be happy! =]
Updated on June 06, 2022Comments
-
Adriano Leal about 2 years
Well, i'm learning to work with QML and i have one doubt. In my example, i have a ListModel with ListElements at QML and i have a QML main file with a rectangle, PathView etc.
I have a QWidget also, than is my main window. In this QWidget i include the QML UI like a component. Ok!
How can I handle QML ListElements by using C++?
Note: when I say "to handle", I want to say include an element for example.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 as I use QML like 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 saw some articles about this, but I am not able to change my LisModel using C++. I saw here http://doc.qt.nokia.com/4.7/qdeclarativemodels.html#c-data-models and here in examples using PathView http://doc.qt.nokia.com/4.7/qdeclarativeexamples.html
Can someone help me?
Thanks!