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!
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.
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 {
...
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With