Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Issue with TextField in ListView delegate
Forum Updated to NodeBB v4.3 + New Features

Issue with TextField in ListView delegate

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
5 Posts 2 Posters 904 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B Offline
    B Offline
    Bob64
    wrote on last edited by
    #1

    I have implemented a 'property table' using ListView, with a TextField 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 an onEditingFinished handler in the TextField.

    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, the index 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 a ListView 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 use textEdited to store a 'pending' value together with the index (which I assume would be valid in that signal handler). Then I could submit the pending value in onEditingFinished, ignoring the fact that index might be invalid at that point.

    1 Reply Last reply
    0
    • sierdzioS Offline
      sierdzioS Offline
      sierdzio
      Moderators
      wrote on last edited by
      #2

      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.

      (Z(:^

      B 1 Reply Last reply
      1
      • sierdzioS sierdzio

        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.

        B Offline
        B Offline
        Bob64
        wrote on last edited by Bob64
        #3

        @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 as Components 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 my Loader (this is described at the end of the Detailed Description for Loader in the Qt documentation).

        I have tried introducing a readonly property, as suggested, at various levels - in the Loader, in the Component instantiation above, in the implementation file for MyTextField but all with the same result.

        1 Reply Last reply
        0
        • sierdzioS Offline
          sierdzioS Offline
          sierdzio
          Moderators
          wrote on last edited by
          #4

          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 if index changes to -1, row will not be updated - so it should work as you intend it to.

          (Z(:^

          B 1 Reply Last reply
          2
          • sierdzioS sierdzio

            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 if index changes to -1, row will not be updated - so it should work as you intend it to.

            B Offline
            B Offline
            Bob64
            wrote on last edited by
            #5

            @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 of onTextEdited.

            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.

            1 Reply Last reply
            1

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved