QML 2D Array of rectangles; access via C++
-
wrote on 19 Oct 2015, 10:13 last edited by
Simple tasks: I have a 2D array of which each element represents the color of an rectangle. I want this to be displayd in QML. Here is the qml:
Rectangle { Grid { Repeater { model: myModel Rectangle { width: 50; height: 50 color: ColorRole } } } }
The ColorRole was used by an QAbstractTableModel derived class. Unfortunately, this did not seem to be the right solution as it did not work out as expected. Any ideas?
-
Simple tasks: I have a 2D array of which each element represents the color of an rectangle. I want this to be displayd in QML. Here is the qml:
Rectangle { Grid { Repeater { model: myModel Rectangle { width: 50; height: 50 color: ColorRole } } } }
The ColorRole was used by an QAbstractTableModel derived class. Unfortunately, this did not seem to be the right solution as it did not work out as expected. Any ideas?
Hi @wanderameise and Welcome to Qt Devnet,
For C++ models to work with QML you need to define the rolesnames using
roleNames()
on C++ side and then you can use this role name string in QML. Some thing like:
C++enum Role { ... ColorRole = Qt::UserRole+11 ... } QHash<int, QByteArray> MyModel::roleNames() const { QHash<int, QByteArray> roles; roles[ColorRole] = "colorrole"; return roles; } //Also re-implement data() as usual and return data for ColorRole
QML
Grid { anchors.fill: parent Repeater { model: myModel Rectangle { width: 50; height: 50 color: model.colorrole //this corresponds to the string defined in roleNames() } } }
-
wrote on 20 Oct 2015, 05:54 last edited by
Thanks for the reply.
Yes I did all that but I ran into the issue that QAbstractTableModel didn't do the trick since data() was only called for rows and not for columns...
The main task here is to represent a lets say 8x8 array of rectangles. Each one with a custom color. This should be modeled with an appropriate C++ model. Which approach would you suggest?
-
Thanks for the reply.
Yes I did all that but I ran into the issue that QAbstractTableModel didn't do the trick since data() was only called for rows and not for columns...
The main task here is to represent a lets say 8x8 array of rectangles. Each one with a custom color. This should be modeled with an appropriate C++ model. Which approach would you suggest?
@wanderameise
Why would you require columns ? All the elements inGrid
are assigned andindex
. You can use that to uniquely identify each element.QAbstractItemModel
would suffice too. -
wrote on 20 Oct 2015, 09:27 last edited by wanderameise
ok, so how do I force the model to be of size 8x8? What I did in my derived class QAbstractTableModel:
int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE { return 8; } int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE { return 8; }
I thought this is where I define the size of the grid and hence both values (row and column) create the index?? And here I provide the data:
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE { if (!index.isValid() || role != ColorRole) return QVariant(); // Here I want to use index.row() and index.column() to acces my internal 2D array m_arr[8][8] }
I just want a representation of my 2D array m_arr[8][8] with a gridview of 8x8 where each item is a rectangle.
QAbstractItemModel looked way to complcated....
-
ok, so how do I force the model to be of size 8x8? What I did in my derived class QAbstractTableModel:
int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE { return 8; } int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE { return 8; }
I thought this is where I define the size of the grid and hence both values (row and column) create the index?? And here I provide the data:
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE { if (!index.isValid() || role != ColorRole) return QVariant(); // Here I want to use index.row() and index.column() to acces my internal 2D array m_arr[8][8] }
I just want a representation of my 2D array m_arr[8][8] with a gridview of 8x8 where each item is a rectangle.
QAbstractItemModel looked way to complcated....
@wanderameise
You have used aGrid
andRepeater
in QML.Repeater
just repeats the item andGrid
adjusts them accordingly. It doesnot know which Item is present in which cell.
All you have is theindex
(a sequence starting from 0) property which you can make use of. It should work. Since you have an array and this index you can find out the its position in the array.
For eg:
index = 1
position in array = (0,1)how to get ?
row = index/total items in array's row (8 in your case)
row = 1/8 = 0col = index%total items in array's row (8 in your case)
col = 1%8 = 1index = 11
position in array = (1,3)Thus the above logic should work even without the need for column(Note: we dont need it because Repeater will refer to rows only)
Now if you want to make use of columns then IMO you will need to use
TableView
instead ofGrid
andRepeater
. -
wrote on 27 Oct 2015, 06:55 last edited by
Yes, you talk about flattening the Matrix. Ok, that's one approach that could work.
Maybe flattening might be the onyl solution since I have no idea hot to get TableView involved in this. It wants me to create TableViewColumns but the number of columns is decided dynamically and they dont have names or the meaning of a column in a table.
Good Lord what a pain...
Maybe the idea behind will bring some light into this: Just an array of rectangle which can be either black or white. It will be a game:
(FYI, the engine in the background needs the information in a 2D array since it will perform some calculations on each item depending on its neighbors)
-
Yes, you talk about flattening the Matrix. Ok, that's one approach that could work.
Maybe flattening might be the onyl solution since I have no idea hot to get TableView involved in this. It wants me to create TableViewColumns but the number of columns is decided dynamically and they dont have names or the meaning of a column in a table.
Good Lord what a pain...
Maybe the idea behind will bring some light into this: Just an array of rectangle which can be either black or white. It will be a game:
(FYI, the engine in the background needs the information in a 2D array since it will perform some calculations on each item depending on its neighbors)
@wanderameise
Grid
+Repeater
would be better option with "flattening" out the matrix. EmitdataChanged
when required and return the updated data fromdata
method.
1/8