Solved Get QModelIndex in delegate
-
Hi,
I have the following problem: I have a TreeView of a QFileSystemModel
TreeView { id: view anchors.fill: parent sortIndicatorVisible: true model: fileSystemModel rootIndex: rootPathIndex selection: sel ....
and a custom delegate which adds a
CheckBox
next to the filename. I would like to store information about whether an element has been checked in my model, so that after sorting the name column still the right boxes are checked (very similar to this TreeView of QFileSystemModel: Remember selection after sorting. However, I have the problem that the solution in the linked post works as theItemSelectionModel
is returning a list ofQModelIndex
and if I want to do something similar, by adding aappendChecked
invokable function to my model and call it in the delegateComponent { id: mycomp Item { id: myitm Row{ id: myrow CheckBox{ id: cbox property bool checked: false anchors.baseline: ctext.baseline onCheckedChanged: { if(checked==false) { model.appendChecked((model.index))
model.index seems to only give me the row number of the delegate and not a
QModelIndex
. But i would need to store aQPersistentModelIndex
in my model. How can I get theQModelIndex
in a delegate and not just the row number? -
typeof(model.index) gives number
-
In general, this is very easy as Qt already has a role to save the CheckboxState (
Qt::CheckStateRole
) so you just need the last part of this wiki article to read/write that roleThe problem here is that QFileSystemModel can't handle
Qt::CheckStateRole
.
To overcome this problem you need a proxymodel between your model and the view that takes care of the roles that QFileSystemModel doesn't manage.I worked on such a solution in my spare time and, while I can't guarantee 100% stability you can find it here under the name
RoleMaskProxyModel
. I haven't developed examples for it yet but the test methodtst_RoleMaskProxyModel::testUseRoleMask
should give you an idea of the usage -
Adding a role to
QFileSystemModel
should also not be difficult. However, to set the initial state I guess I must once walk through the whole model, right? Or can one set a default state for a role? -
@maxwell31 said in Get QModelIndex in delegate:
Adding a role to QFileSystemModel should also not be difficult.
It's not only if you either use the privates of Qt or recompile a custom Qt widgets model
However, to set the initial state I guess I must once walk through the whole model, right?
Normally yes
Or can one set a default state for a role?
You could in the subclass but in this case it is probably easier to handle the default state directly in the delegate
-
Hm, so no easy solution :-(
-
What about getting the QModelIndex inside the delegate, that would be easy if possible
-
Actually I found how to get the index:
fileSystemModel.index(model.urlstringrole,0)
where filesystemmodel is
engine.rootContext()->setContextProperty("fileSystemModel", fsm);
and
fsm
theQFileSystemModel
-
Now I would only need to find out how to set a property of my
TableViewColumn
delegate, e.g. for theonSortIndicatorChanged
signal of my view.I have a
isChecked(QModelIndex)
function in my model. If I can loop over the displayed delegates, I could update theirchecked
state, but I don't know how to do thisEdit: Hm, fileSystemModel.index(model.urlstringrole,0) seems to give the wrong index
-
What you are doing is flaky at best. Please read that wiki page I linked especially in the section "Using the data in QML"
-
:-) Yes, I have the feeling that it is flaky at best. But is there really no way to get the QModelIndex right? I found that using a
Connection
to the delegate should work, but my problem is still getting the right QModelIndex for a delegate -
Is there something like a
modelAdaptor.mapRowToModelIndex
function accessible?
-
As I do not yet understand the solution @VRonin has in his repository, I thought about a hacky solution:
Keep a list of persistent model indexes in a
QFileSystemModel
derived model, add aIsChecked
Role to the derived model and set the data function for this role tocase IsCheckedRole: return isChecked(QPersistentModelIndex(index));
a custom function, which will check, whether index is in the persistentModel Index list.
This brought to my mind, that I don't actually know how this works. If in the delegate I then use this role to set the
checked
property of a checkbox, how does the delegate now if the model is updated? It seems to work though - but not completly:If I select an item, sort by the name column, deselect it and sort again, the item is selected again. I guess this has nothing todo with my isChecked function. A similar thing is if I only add a checkbox to the delegate and do nothing in the model. If I select it, and then sort, the item which goes to its place due to sorting is selected.