Unsolved Issue with TextField in ListView delegate
-
I have implemented a 'property table' using
ListView
, with aTextField
in the delegate implementation for value input. The idea is that a value should be committed on pressing enter or on the text field losing focus. To this end, I am using anonEditingFinished
handler in theTextField
.I am relying on the
index
property in the delegate to tell me which item in the table has been edited. That is needed to allow me to make an appropriate commit to my underlying model.The issue I am seeing is that in some circumstances, when the text field loses focus and
onEditingFinished
is triggered, theindex
is -1. This means that although I might know that the value has changed and that it needs to be committed, I don't have the information about which item it actually is.Whether this happens seems to depend on exactly where in the application focus goes to. For example, the property table is below a tree and if I click on a tree branch the problem does not seem to happen. On the other hand if I click on another list that in a part of the application that is 'further away', it does happen.
Because this is happening in a relatively complex scenario, it is quite difficult to narrow it down to a simple example. For now, I wondered if anyone recognised the behaviour where the
index
can be -1 in aListView
delegate or if anyone thought what I am trying to do is fundamentally wrong for some reason.I am wondering about using the
textEdited
signal. I do not want to commit on every single edit as this would be too expensive. However I could usetextEdited
to store a 'pending' value together with theindex
(which I assume would be valid in that signal handler). Then I could submit the pending value inonEditingFinished
, ignoring the fact thatindex
might be invalid at that point. -
Add a readonly property in your delegate, like this:
YourDelegate { readonly property int row: index }
And use this in your
onEditingFinished
handler. It should contain the original value from when the delegate was created. -
@sierdzio Thanks for the suggestion. I thought that would solve it but unfortunately not. The original index is reported as -1 in
onEditingFinished
.One detail which I unfortunately omitted was that, because I have different types of property in my table and it needs to be initialised dynamically from data, I am using a
Loader
as a 'delegate factory' . The delegates themselves are defined asComponent
s such as:// delegate for integer type property Component { id: intFieldDelegate MyTextField { validator: IntValidator{} } }
One consequence of this is that I don't have direct access to
index
etc in my delegate and have to introduce an intermediate property,index_
say, in myLoader
(this is described at the end of the Detailed Description forLoader
in the Qt documentation).I have tried introducing a readonly property, as suggested, at various levels - in the
Loader
, in theComponent
instantiation above, in the implementation file forMyTextField
but all with the same result. -
Weird. I had a very similar case recently and this trick with property worked fine.
There is one other possibility - do not bind the new index property, but assign it. So, do this:
MyTextField { property int row: -1 Component.onCompleted: row = index }
Since you are adding itermediate property in Loader, you can actually do it there, when sourceComponent is changed.
This way the
row
is assigned only once. Even ifindex
changes to-1
,row
will not be updated - so it should work as you intend it to. -
@sierdzio Sorry for delayed response to your suggestion - I was pulled onto other things for a while. Now that I have come back to it a bit more fresh I see that there was something specific happening in my application which probably explains why your solution did not work for me. As I mentioned in my first post, the issue depended on where I clicked in the application. I realise now that it was a result of that click (on an item in another
ListView
) in turn affecting the current selection in the tree. This then reset the model being shown in the property view. What was a bit surprising to me was that the focus out (onEditingFinished
) of my text field happens quite late, after all of this other stuff. Anyway I have found a way to deal with it, along the lines that I was originally thinking about, making more use ofonTextEdited
.Having said all that, like you, I have definitely seen a more general issue of losing the
index
value in the past and I suspect your first suggestion would have worked in that case so thank you for taking the time to suggest it.