Results 1 to 20 of 20

Thread: The dataChanged Signal Not Performing as Expected

  1. #1
    Join Date
    Nov 2016
    Location
    Ridgecrest California
    Posts
    33
    Thanks
    11
    Thanked 1 Time in 1 Post
    Qt products
    Qt4 Qt5
    Platforms
    Windows Android

    Question The dataChanged Signal Not Performing as Expected

    I have a situation that I require some additional insight to solve. I have elected not to post any code at this time because the whole program is rather large and bulky, and I think to isolate just the code involved would be time prohibitive. In any event, I’m not too sure the problem involves the actual code or, what I believe is more likely, that I’m missing some switch, understanding or knowledge about the Qt environment that may be affecting the situation.

    The situation is that I have sub-classed QAbstractItemModel to create a model that uses a similar paradigm as the parent child relationship used in a tree model. The main window displays the values from the model in a treeView, and about half of those values are being constantly updated. The update is initiated by a QTimer in the main window code, that emits a signal which is connected to a slot in the model class, which after insuring the models data is updated, emits the dataChanged signal.

    Some of the components in the model represent objects that are moving in a three dimensional space and the signal mentioned above is used to indicate that the next movement is to take place. Not only are the geographic coordinates displayed in the treeView, if the user has so selected, an additional window is shown that has a map as it’s background and the objects position is shown as an icon on that map. The class that computes the next position is the same class that initiates and controls the graphic representation on the map. Every instance of that class is moved to it’s own thread when it is instantiated. All communication between any instances of this class with the model, or any other component of the program is performed solely with signals and slots. On a bit of a different issue, is there a way to see a representation of this communication concerning signals and slots while debugging?

    In any event, every class, function and operational item appears to work just fine. I have been able to prove that every instantiation of an object that computes location and controls movement is performing its tasks correctly and that it is on a different thread. The problem is that, even though the treeView should be showing certain elements updating 10 times a second in the main window display, the treeView appears to only update when you move the mouse directly over the treeView portion of the main display. Every time the mouse movement stops, even to change direction, or moves off the treeView portion of the display, any values that were updating, immediately stop doing so.

    At this point, I can only assume that for some reason, the dataChanged signal is emitted whenever the mouse is moving over thetreeView and not emitted when I expect it to be. When examining the code, It looks as if it should be properly emitted at the correct time and I can’t even guess why the signal would only be emitted whenever the mouse is moving over the treeView. I’m hoping someone can provide some insight into my problem and I’d like to thank anyone in advance that does

  2. #2
    Join Date
    Jan 2006
    Location
    Bremen, Germany
    Posts
    554
    Thanked 86 Times in 81 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: The dataChanged Signal Not Performing as Expected

    I would guess your dataChanged() signal is emitted with a wrong parent or something. You should check if you really emit with the correct QModelIndex.

  3. The following user says thank you to ChristianEhrlicher for this useful post:

    Corny (28th January 2019)

  4. #3
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,249
    Thanks
    304
    Thanked 868 Times in 855 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: The dataChanged Signal Not Performing as Expected

    I would guess your dataChanged() signal is emitted with a wrong parent or something.
    I don't think that would explain why it works correctly some of the time but not others. If the model was emitting with the wrong indexes, it would fail whether or not the mouse was involved. It sounds like under some circumstances, the view gets updated properly but other times not.

    I am wondering if this is an event loop and thread synchronization issue. @Corny - are you properly protecting the model against simultaneous updates with mutexes or some other thread synchronization device? Even if each item is running in its own thread and is responsible for computing its new position on receipt of the timer signal, these computations will not all occur simultaneously. The tree and map views must be able to lock out any changes to the model while these views are updating themselves.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  5. #4
    Join Date
    Jan 2006
    Location
    Bremen, Germany
    Posts
    554
    Thanked 86 Times in 81 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: The dataChanged Signal Not Performing as Expected

    If the model was emitting with the wrong indexes, it would fail whether or not the mouse was involved
    This is wrong. A mouse move triggers a repaint of the underlying cell (e.g. due to focus changes) so the new data is fetched. The effect definitely points to a wrong dataChanged() emit.

  6. The following user says thank you to ChristianEhrlicher for this useful post:

    Corny (28th January 2019)

  7. #5
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,249
    Thanks
    304
    Thanked 868 Times in 855 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: The dataChanged Signal Not Performing as Expected

    A mouse move triggers a repaint of the underlying cell
    My testing (setting a breakpoint in data() of my tree model) shows that a mouse move does not trigger a fetch of new data unless mouse tracking is enabled and the mouse passes over a tree item. If mouse tracking in not enabled or if the mouse is moving over an empty area of the tree view, only a mouse click or other action that triggers a repaint (eg. moving the window containing the tree view) will cause a data fetch.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  8. #6
    Join Date
    Jan 2006
    Location
    Bremen, Germany
    Posts
    554
    Thanked 86 Times in 81 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: The dataChanged Signal Not Performing as Expected

    That's exactly what I said. And when you've a style which highlights the cell with the mouse focus the even every mouse move will update the underlying cell (e.g. fusion style on linux)

  9. #7
    Join Date
    Nov 2016
    Location
    Ridgecrest California
    Posts
    33
    Thanks
    11
    Thanked 1 Time in 1 Post
    Qt products
    Qt4 Qt5
    Platforms
    Windows Android

    Default Re: The dataChanged Signal Not Performing as Expected

    First I would like to apologize for a slow response, but I was sent out to the field at the end of last week so I'm just now seeing your replies.
    I'd like to thank you both ChristianEhrlicher and d_stranz for the assistance


    You had asked if
    are you properly protecting the model against simultaneous updates with mutexes or some other thread synchronization device?
    and I have not specifically included anything to insure thread synchronization. I will also re-examine the dataChanged() signal parameters and see if I can find anything similar to what you mention. I will be sure to report back what I find, if anything.

    I want to thank you both again for pointing me in a direction that may provide an answer.

    Corny

  10. The following user says thank you to Corny for this useful post:

    d_stranz (28th January 2019)

  11. #8
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,249
    Thanks
    304
    Thanked 868 Times in 855 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: The dataChanged Signal Not Performing as Expected

    I have not specifically included anything to insure thread synchronization
    It can be tricky. One of my co-workers notified me yesterday about just such a problem, where methods marked as "const" (i.e. presumably read-only) were in fact updating mutable data behind the scenes using a "lazy evaluation" scheme to avoid heavy processing until the last minute.

    Under the wrong circumstances, a shared pointer to a single instance was being used by two different threads; both of them were calling the same "const" method, but because the data had changed earlier (through non-const methods), the first thread in invoked the update of the mutable data and then the second thread got inconsistent data because the first thread had already yet changed the flag that said "no update needed" before the update was completely done. The idea of deferring updates of the internal state until someone actually asked for them turned out to be a gotcha.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  12. #9
    Join Date
    Nov 2016
    Location
    Ridgecrest California
    Posts
    33
    Thanks
    11
    Thanked 1 Time in 1 Post
    Qt products
    Qt4 Qt5
    Platforms
    Windows Android

    Default Re: The dataChanged Signal Not Performing as Expected

    That does sounds a bit tricky, but what I'm attempting is not really all that complex. I'm going through the code right now and my thought at this point is that I may have gotten a bit confused with the QAbstractModel class documentation. The requirement for the dataChanged signal indicates two QModelIndex values need to be passed to the function, one for the top left corner of the data area and one for the top right. Since I'm only addressing one point (or cell), I was passing the same index value in both arguments. I'm in the process of verifying if that is a valid or invalid way of addressing just one point right now.

  13. #10
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,249
    Thanks
    304
    Thanked 868 Times in 855 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: The dataChanged Signal Not Performing as Expected

    Actually, it's top left and bottom right, inclusive. From the docs:

    If the items are of the same parent, the affected ones are those between topLeft and bottomRight inclusive.
    This implies that if only one item is changed, the topLeft and bottomRight indexes should be the same. But for a tree view, this is important:

    If the items do not have the same parent, the behavior is undefined.
    This implies that if multiple items in the tree are changing at the same time, then you would need to emit multiple dataChanged() signals if the items come from different parts of the tree.

    Top left and bottom right also implies that the items changing are contiguous between those two limits.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  14. The following user says thank you to d_stranz for this useful post:

    Corny (29th January 2019)

  15. #11
    Join Date
    Nov 2016
    Location
    Ridgecrest California
    Posts
    33
    Thanks
    11
    Thanked 1 Time in 1 Post
    Qt products
    Qt4 Qt5
    Platforms
    Windows Android

    Default Re: The dataChanged Signal Not Performing as Expected

    Quote Originally Posted by d_stranz View Post
    Actually, it's top left and bottom right, inclusive.
    Thanks, you're absolutely correct, my bust. And as you have noted, I have managed to verify that using the same index value for both values references the one data point as desired.

    As to your point concerning...
    Quote Originally Posted by d_stranz View Post
    ...would need to emit multiple dataChanged() signals if the items come from different parts of the tree.
    not only is that key, but the fact that the data comes from multiple instantiations of an item, has me leaning towards your original assessment about using a mutex or some other form of thread blocking. As I'm only vaguely familiar with the subject, I've been attempting to study up on the subject, as well as more accurately define the timing of the model and its items.

    Thanks again

    Corny

  16. #12
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,249
    Thanks
    304
    Thanked 868 Times in 855 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: The dataChanged Signal Not Performing as Expected

    Maya Posch has written a great book on C++ multithreading which includes examples using Qt, STL, and other threading implementations. I learned a lot from reading it and used it to solve more than one problem.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  17. #13
    Join Date
    Nov 2016
    Location
    Ridgecrest California
    Posts
    33
    Thanks
    11
    Thanked 1 Time in 1 Post
    Qt products
    Qt4 Qt5
    Platforms
    Windows Android

    Default Re: The dataChanged Signal Not Performing as Expected

    So, it turns out that earlier in the development process, I forgot that I had written some of the data points directly to the items without using the virtual function setData() in the sub-classed QAbstactItemModel. Of course the model is the only place that I was emitting the dataChanged() signal.

    It looks like a simple logic error was the problem. Thanks again for all the help with this, I've learned a lot. Also, I'll check out that book by Maya Posch that you mentioned.

    Corny

    P.S. I would have marked this thread as solved but don't see a means of doing so.

  18. #14
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,249
    Thanks
    304
    Thanked 868 Times in 855 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: The dataChanged Signal Not Performing as Expected

    I had written some of the data points directly to the items
    Oops. Won't be the first time that's happened.

    Maya Posch also has a great web site / blog with all sorts of interesting things, programming and beyond.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  19. #15
    Join Date
    Nov 2016
    Location
    Ridgecrest California
    Posts
    33
    Thanks
    11
    Thanked 1 Time in 1 Post
    Qt products
    Qt4 Qt5
    Platforms
    Windows Android

    Thumbs up Re: The dataChanged Signal Not Performing as Expected

    Though this thread is rather old, I’m posting this in the event someone else comes across the same situation. Even though I indicated that I thought I had found the problem. It wasn’t until a bit later that I figured out the real problem.

    It turns out that the QAbstractItemModel documentation for dataChanged(), states among other things that...

    [signal] void QAbstractItemModel::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles = QVector<int> ())
    ...
    The optional roles argument can be used to specify which data roles have actually been modified. An empty vector in the roles argument means that all roles should be considered modified. The order of elements in the roles argument does not have any relevance.

    Based on other Qt documentation that shows a value assigned to an argument apparently indicating that it is an optional argument, and that I wanted to address all roles, I assumed (erroneously), that if you wanted to address all of the rolls the role argument could be an empty vector, or the role argument was optional. However, emitting the signal without a role argument appeared to work but proved to be problematic. Then, when I came across the QAbstractItemView documentation for the dataChanged() signal, it stated in part...

    [virtual protected slot] void QAbstractItemView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles = QVector<int> ())
    ...
    The roles which have been changed can either be an empty container (meaning everything has changed), or a non-empty container with the subset of roles which have changed.

    Which I took to mean that the role argument itself is not optional and a container must be used as the argument, but the contents of the container can be empty if you want to address all roles.

    Sending an empty container QVector<int> solved the problem.

  20. #16
    Join Date
    Jan 2006
    Location
    Bremen, Germany
    Posts
    554
    Thanked 86 Times in 81 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: The dataChanged Signal Not Performing as Expected

    Quote Originally Posted by Corny View Post
    Which I took to mean that the role argument itself is not optional and a container must be used as the argument, but the contents of the container can be empty if you want to address all roles.
    This is nonsense - not passing the third argument will let the compiler add the default value for the third argument which is an empty QVector<int>() - so it's *exactly to same if you call dataChanged(idx, idx2, QVector<int>()) or dataChanged(idx, idx2) or dataChanged(idx, idx2, {})

  21. #17
    Join Date
    Nov 2016
    Location
    Ridgecrest California
    Posts
    33
    Thanks
    11
    Thanked 1 Time in 1 Post
    Qt products
    Qt4 Qt5
    Platforms
    Windows Android

    Default Re: The dataChanged Signal Not Performing as Expected

    I'm not sure how to respond to your reply other than that when emitting the signal without anything for the roles argument dataChanged(idx, idx2), I encounter the problems outlined above. When I actually emit using dataChanged(idx, idx2, QVector<int>()), I no longer experience those problems. The results have proven to be repeatable on multiple test runs, using both methods of emitting the signal.

    I may have stated it in a manner that is not easily understood, but as noted, I have run multiple tests using both methods, and have repeatably achieved the exact same results for the equivalent method used. Is there something that I'm not seeing?

  22. #18
    Join Date
    Jan 2006
    Location
    Bremen, Germany
    Posts
    554
    Thanked 86 Times in 81 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: The dataChanged Signal Not Performing as Expected

    There must be another reason - from the C++ side it doesn't matter - see https://en.cppreference.com/w/cpp/la...ault_arguments or a good C++ book.

  23. #19
    Join Date
    Nov 2016
    Location
    Ridgecrest California
    Posts
    33
    Thanks
    11
    Thanked 1 Time in 1 Post
    Qt products
    Qt4 Qt5
    Platforms
    Windows Android

    Default Re: The dataChanged Signal Not Performing as Expected

    I don't disagree, that in C++ that's the way it works. However I am at a loss understanding what exactly is happening here. I am simply attempting to let anyone else who may run into a similar circumstance, know how I resolved the situation.

  24. #20
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,249
    Thanks
    304
    Thanked 868 Times in 855 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: The dataChanged Signal Not Performing as Expected

    I don't disagree, that in C++ that's the way it works.
    As Christian points out, there is absolutely no difference between emitting dataChanged() with two arguments vs. with a third argument being an empty (but explicitly declared) QVector<int>(). Both versions should compile to exactly the same thing (with the compiler inserting the default argument in the first instance), so there is absolutely no way that a slot receiving the signal can tell how it was called in the source code. If you are seeing a difference in behavior if you build and run code written first one way and then the other with no other code changes and exactly the same runtime test conditions then I would also be at a loss to explain why.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

Similar Threads

  1. QTableView switching currentIndex not performing as expected
    By AlphaWolfXV in forum Qt Programming
    Replies: 6
    Last Post: 31st December 2013, 15:22
  2. Get indices of rows where the signal dataChanged() was emitted
    By yannwilfried in forum Qt Programming
    Replies: 6
    Last Post: 8th August 2013, 10:19
  3. emitDataChanged and dataChanged signal
    By fruzzo in forum Qt Programming
    Replies: 1
    Last Post: 26th September 2012, 16:47
  4. Why the signal "dataChanged" by QTableWidget not work?
    By Tao Clark in forum Qt Programming
    Replies: 1
    Last Post: 20th August 2011, 18:16
  5. QDir entryList performing slowly
    By bunjee in forum Qt Programming
    Replies: 3
    Last Post: 8th October 2009, 17:21

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.