Binding list from C++ to QML
-
Thanks you very much!
But, now i have new problem, when i using signal and slot to communicate between cpp file and qml file. I'm using code below:
Cpp file (main.cpp)
QQmlApplicationEngine engine;
QQmlContext* context = engine.rootContext();
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
QObject *topLevel = engine.rootObjects().value(0);
QQuickWindow *window = qobject_cast<QQuickWindow *>(topLevel);
KeywordBusiness business;
QObject::connect(window,SIGNAL(savekeywords(KeywordsModel)), &business, SLOT(SaveChangedData(KeywordsModel)));on class KeywordBusiness .h I define a slot SaveChangedData with parameter is KeywordsModel extends QObject
On qml file. I define a signal savekeywords with also parameter is KeywordsModel.
But when i click button to call signal savekeywords , in cpp file the QObject::connect funtion not working.
Please help me, I was missing something?
Thanks!
-
Thanks you very much!
But, now i have new problem, when i using signal and slot to communicate between cpp file and qml file. I'm using code below:
Cpp file (main.cpp)
QQmlApplicationEngine engine;
QQmlContext* context = engine.rootContext();
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
QObject *topLevel = engine.rootObjects().value(0);
QQuickWindow *window = qobject_cast<QQuickWindow *>(topLevel);
KeywordBusiness business;
QObject::connect(window,SIGNAL(savekeywords(KeywordsModel)), &business, SLOT(SaveChangedData(KeywordsModel)));on class KeywordBusiness .h I define a slot SaveChangedData with parameter is KeywordsModel extends QObject
On qml file. I define a signal savekeywords with also parameter is KeywordsModel.
But when i click button to call signal savekeywords , in cpp file the QObject::connect funtion not working.
Please help me, I was missing something?
Thanks!
-
I simplified the MainForm.ui.qml (as below) and find that the QML report "TypeError: Cannot read property 'items' of undefined" for each instance of the the page when I execute the app. According to this, I think I have to register Items_model. However I am unable to do so with qmlRegisterType()
(I rename the property Items in Page_model to have lowercamel: Q_PROPERTY(Items_model* items READ Items WRITE setItems NOTIFY itemsChanged) )
import QtQuick 2.4 import QtQuick.Controls 1.3 Rectangle { id: rectangleMain property alias quitButton: quitButton property alias pagesView: pagesView width: 360 height: 360 ListView { id: pagesView width: 500 orientation: ListView.Horizontal spacing: 2 anchors { bottom: quitButton.top bottomMargin: 8 right: parent.right rightMargin: 0 left: parent.left leftMargin: 0 top: parent.top topMargin: 0 } delegate: Rectangle { id:paView height: parent.height width:100 color: "transparent" border.color: "teal" border.width: 1 radius: 6 GridView { anchors { rightMargin: 6 leftMargin: 6 bottomMargin: 6 topMargin: 6 fill: parent } cellWidth: width / 2 cellHeight: 50 model:model.items delegate: Rectangle { height: 46 width: 46 color: "blue" //colorCode Text { anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter text:model.displayText } } } } } Button { id: quitButton y: 325 text: qsTr("Quit") anchors { right: parent.right rightMargin: 50 left: parent.left leftMargin: 50 bottom: parent.bottom bottomMargin: 8 } } }I simplified the MainForm.ui.qml (as below) and find that the QML report "TypeError: Cannot read property 'items' of undefined" for each instance of the the page when I execute the app.
Since that property is in parent model try accessing it with its parent object.
model: pagesView.model.items -
I simplified the MainForm.ui.qml (as below) and find that the QML report "TypeError: Cannot read property 'items' of undefined" for each instance of the the page when I execute the app.
Since that property is in parent model try accessing it with its parent object.
model: pagesView.model.items@p3c0 : Thanks, you are correct about that, but that is not enough to solve the problem. I find out what was missing. Instead, create the Q_PROPERTY, I have to create custom "roles" like these (example code below) in the model. Again, I don't know this is the right way or not, but it solved my problem of binding models further down on the chain (second level). But then now, I find out that the QAbstractTableModel may not the right choice :~) Despite I implemented columnCount(), it only ask for data in rows of column 0!!
QHash<int, QByteArray> Pages_model::roleNames() const { QHash<int, QByteArray> roles; roles[DisplayNameRole] = "displayName"; roles[DisplayItemsRole] = "displayItems"; return roles; } QVariant Pages_model::data(const QModelIndex &index, int role) const { if (!index.isValid()) return QVariant(); int i = index.row(); if (i < 0 || i >= _pagesModelList.count()) return QVariant(); const Page_model *pPage = _pagesModelList[i]; if (role == DisplayNameRole) { return pPage->displayName(); } else if (role == DisplayItemsRole) { return QVariant::fromValue(pPage->Items()); } return QVariant(); } -
@p3c0 : Thanks, you are correct about that, but that is not enough to solve the problem. I find out what was missing. Instead, create the Q_PROPERTY, I have to create custom "roles" like these (example code below) in the model. Again, I don't know this is the right way or not, but it solved my problem of binding models further down on the chain (second level). But then now, I find out that the QAbstractTableModel may not the right choice :~) Despite I implemented columnCount(), it only ask for data in rows of column 0!!
QHash<int, QByteArray> Pages_model::roleNames() const { QHash<int, QByteArray> roles; roles[DisplayNameRole] = "displayName"; roles[DisplayItemsRole] = "displayItems"; return roles; } QVariant Pages_model::data(const QModelIndex &index, int role) const { if (!index.isValid()) return QVariant(); int i = index.row(); if (i < 0 || i >= _pagesModelList.count()) return QVariant(); const Page_model *pPage = _pagesModelList[i]; if (role == DisplayNameRole) { return pPage->displayName(); } else if (role == DisplayItemsRole) { return QVariant::fromValue(pPage->Items()); } return QVariant(); }But then now, I find out that the QAbstractTableModel may not the right choice :~) Despite I implemented columnCount(), it only ask for data in rows of column 0!!
That's right
GridVieworListViewonly deals with rows. In that case can't you replace it withQAbstractItemModel? Keep everything other than columns. -
But then now, I find out that the QAbstractTableModel may not the right choice :~) Despite I implemented columnCount(), it only ask for data in rows of column 0!!
That's right
GridVieworListViewonly deals with rows. In that case can't you replace it withQAbstractItemModel? Keep everything other than columns.@p3c0 Uh but then which view should I use? I read this,
"QAbstractItemModel presents a hierarchy of tables, but the views currently provided by QML can only display list data."
Does that mean, at the present time, nothing I can use except maybe create my own view!? If so, what is the best reading can you recommend? -
But then now, I find out that the QAbstractTableModel may not the right choice :~) Despite I implemented columnCount(), it only ask for data in rows of column 0!!
That's right
GridVieworListViewonly deals with rows. In that case can't you replace it withQAbstractItemModel? Keep everything other than columns.@p3c0 I solved the problem! Even without doing custom roles. I just simplified it, adding some qRegisterMetaType. The solution is not as I want to be, but it works. For now, I just have to figure out how to hide the dummy items. Thank you for pointing out some direction.
-
@p3c0 I solved the problem! Even without doing custom roles. I just simplified it, adding some qRegisterMetaType. The solution is not as I want to be, but it works. For now, I just have to figure out how to hide the dummy items. Thank you for pointing out some direction.
@TonyN Congratulations :)
IMO you can useQAbstractItemModelwithGridView(for grid like item positioning) orListView(for list like item positioning). For hiding dummy items you can maintain a field for items and update it from the model whenever required. -
@TonyN Congratulations :)
IMO you can useQAbstractItemModelwithGridView(for grid like item positioning) orListView(for list like item positioning). For hiding dummy items you can maintain a field for items and update it from the model whenever required.@p3c0 I certainly want to hear other opinion. I did attempt to use QAbstractItemModel, but then the GridView still treat model as a list!?
(my current solution is using QAbstractListModel with GridView, and compute item's index from its specified row and column, if there is no item at the requested index, I just return QVariant(). The rowCount() of QAbstractItemModel is the total item the can represent on the grid (row * column) ) -
@p3c0 I certainly want to hear other opinion. I did attempt to use QAbstractItemModel, but then the GridView still treat model as a list!?
(my current solution is using QAbstractListModel with GridView, and compute item's index from its specified row and column, if there is no item at the requested index, I just return QVariant(). The rowCount() of QAbstractItemModel is the total item the can represent on the grid (row * column) )