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!
-
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(); }
-
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
GridView
orListView
only 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? -
@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 useQAbstractItemModel
withGridView
(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) )