Results 1 to 12 of 12

Thread: Self-update QAbstractItemDelegate when item changes

  1. #1
    Join Date
    Aug 2007
    Posts
    244
    Thanks
    42
    Thanked 8 Times in 8 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Self-update QAbstractItemDelegate when item changes

    Hi, have a problem with a QListView that repaints only when moving mouse in the view.

    The long story: I have a QVariantList of items coming as reply of network query. Each item has a member representing an url to a remote file image. The item class checks if QPixmapCache contains the pixmap (associated to the url) and eventually downloads and adds it to cache (using temporarily a default image). This QVariantList is assigned to a QAbstractListModel and this to the QListView.

    It works quite good: I start searching something, the QListView is populated of items, each with a default image. Nothing changes until I move mouse, when default images are replaced with those downloaded and cached in the background.

    Obviously I'm missing a step, something that connects item's replyFinished routine with model/view.

    Which is the best way?

    Very thanks.
    Giuseppe CalÃ

  2. #2
    Join Date
    May 2008
    Location
    Tripoli Libya
    Posts
    70
    Thanks
    10
    Thanked 8 Times in 8 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Self-update QAbstractItemDelegate when item changes

    emit a signal to repaint with out moving the mouse !!!?
    http://doc.qt.io/qt-4.8/signalsandslots.html

  3. #3
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    4,380
    Thanks
    19
    Thanked 1,005 Times in 913 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows Symbian S60
    Wiki edits
    5

    Default Re: Self-update QAbstractItemDelegate when item changes

    The view updates when the model changes. So how does your model looks like and what do you do after the image gets loaded?

  4. #4
    Join Date
    Aug 2007
    Posts
    244
    Thanks
    42
    Thanked 8 Times in 8 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Self-update QAbstractItemDelegate when item changes

    Quote Originally Posted by Lykurg View Post
    The view updates when the model changes. So how does your model looks like and what do you do after the image gets loaded?
    All happens in custom item class; the model isn't "informed" about changes.
    Giuseppe CalÃ

  5. #5
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    4,380
    Thanks
    19
    Thanked 1,005 Times in 913 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows Symbian S60
    Wiki edits
    5

    Default Re: Self-update QAbstractItemDelegate when item changes

    then you should do that! otherwise you must force the view manually to repaint all using update(). If you have a list model, then simply add a custom role which is set to false, and as soon the image is loaded set it to true which will trigger an update.

  6. #6
    Join Date
    Aug 2007
    Posts
    244
    Thanks
    42
    Thanked 8 Times in 8 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Self-update QAbstractItemDelegate when item changes

    If I understood you well in CustomListModel I should add something like

    Qt Code:
    1. QHash<int, QByteArray> customRoles;
    2. customRoles.insert(ItemRoles::TriggerUpdate, "triggerUpdate");
    3. setRoleNames(customRoles);
    To copy to clipboard, switch view to plain text mode 

    My ItemClass should contain a bool that become true when image download is finished.

    Back in my CustomListModel, in 'QVariant data(const QModelIndex &index, int role) const' i have to insert something like this?

    Qt Code:
    1. switch (role) {
    2. case ItemRoles::TriggerUpdate:
    3. if(itemsList.at(index.row())->triggerUpdate())
    4. // update
    5. ...
    6. }
    To copy to clipboard, switch view to plain text mode 

    If so, I'm having trouble to catch the right routine to call for update.
    Giuseppe CalÃ

  7. #7
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    4,380
    Thanks
    19
    Thanked 1,005 Times in 913 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows Symbian S60
    Wiki edits
    5

    Default Re: Self-update QAbstractItemDelegate when item changes

    Well it is hard to give an adequate advise if one can't see how you created your model, but in theory I was talking about: QAbstractItemModel::setData() which is called after you have loaded the image. Inside that function you call QAbstractItemModel::dataChanged() which will trigger a update of the views.

  8. #8
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Self-update QAbstractItemDelegate when item changes

    I would rather suggest to implement your data model in such a way that you only access your underlying data structure through your model (either via methods available in QAbstractItemModel or your custom ones). You need to make sure that changing some item causes QAbstractItemModel::dataChanged() to be emitted, method inserting new items into the model calls beginInsertRows() and endInsertRows() and method removing data from the model calls beginRemoveRows() and endRemoveRows().
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  9. The following user says thank you to wysota for this useful post:

    jiveaxe (13th February 2013)

  10. #9
    Join Date
    Aug 2007
    Posts
    244
    Thanks
    42
    Thanked 8 Times in 8 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Self-update QAbstractItemDelegate when item changes

    Ok, here it is model implementation:

    Qt Code:
    1. #include "matcheslistmodel.h"
    2. #include "roles.h"
    3.  
    4. MatchesListModel::MatchesListModel(QObject *parent) :
    5. {
    6. // Adding new roles
    7. QHash<int, QByteArray> roles;
    8. roles.insert(ItemRoles::Title, "title");
    9. roles.insert(ItemRoles::Image, "image");
    10. setRoleNames(roles);
    11. }
    12.  
    13. MatchesListModel::~MatchesListModel()
    14. {
    15. }
    16.  
    17. void MatchesListModel::setElements(QList<Item *> items)
    18. {
    19. mItems = items;
    20. }
    21.  
    22. QVariant MatchesListModel::data(const QModelIndex &index, int role) const
    23. {
    24. if (!index.isValid())
    25. return QVariant();
    26.  
    27. if (index.row() >= mItems.size())
    28. return QVariant();
    29.  
    30. switch (role) {
    31. case Qt::DisplayRole:
    32. return QVariant(mItems.at(index.row())->title());
    33. case ItemRoles::Image:
    34. return QVariant(mItems.at(index.row())->image());
    35. default:
    36. return QVariant();
    37. }
    38. }
    39.  
    40. int MatchesListModel::rowCount(const QModelIndex &parent) const
    41. {
    42. Q_UNUSED(parent);
    43. return mItems.count();
    44. }
    To copy to clipboard, switch view to plain text mode 

    As you can see, I'm not using setData().
    Last edited by jiveaxe; 11th February 2013 at 14:48.
    Giuseppe CalÃ

  11. #10
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: Self-update QAbstractItemDelegate when item changes

    Here are the main points:
    • The view will not update itself unless the model tells it the data has changed or the user triggers a view change that forces it to refetch the data.
    • The model cannot tell the view that underlying data has changed unless it knows itself
    • You are changing the underlying data from outside the model and not informing the model.


    The usual approach would be, as wysota points out, to put the actual data inside the model and maintain the state of the data through the model instance. You can use the setData() interface to the model, or your own methods, but whenever the model changes the data it must emit the relevant dataChanged() or related signals. When your network reply comes in you insert the new image into the model causing the model to emit dataChanged().

  12. The following user says thank you to ChrisW67 for this useful post:

    jiveaxe (13th February 2013)

  13. #11
    Join Date
    Aug 2007
    Posts
    244
    Thanks
    42
    Thanked 8 Times in 8 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Self-update QAbstractItemDelegate when item changes

    Quote Originally Posted by ChrisW67 View Post
    The usual approach would be, as wysota points out, to put the actual data inside the model and maintain the state of the data through the model instance. You can use the setData() interface to the model, or your own methods, but whenever the model changes the data it must emit the relevant dataChanged() or related signals. When your network reply comes in you insert the new image into the model causing the model to emit dataChanged().
    I've followed your and wysota way. I subclassed QNetworkAccessManager and now the model calls it with url and index; this new class downloads the image and emits a signal intercepted by the model that in turn emits dataChanged(), as you recommend. Now images are self-updated, as expected. I only encountered a small bug: seems that the model calls the download class 4 times per item and when items are a lot the program crashes with this message:

    GLib-ERROR **: Creating pipes for GWakeup: Too many open files
    Is there a way to limit model's calls? Or is it best to implement a download manager with queue support?

    Thank you both for the valuable help.
    Giuseppe CalÃ

  14. #12
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: Self-update QAbstractItemDelegate when item changes

    The model's data() method will be called multiple times for each model index in the view: for the DisplayRole, DecorationRole, SizeHintRole etc... If you fetch the image once for each call you will indeed be performing efficiency crimes. Make sure you are only fetching a remote image once and storing it in the model for later use.

Similar Threads

  1. Single Item update in QGraphicsView
    By oberlus in forum Qt Programming
    Replies: 0
    Last Post: 27th August 2010, 09:17
  2. Replies: 2
    Last Post: 9th August 2010, 17:53
  3. QAbstractItemDelegate and QLinearGradient
    By toutarrive in forum Qt Programming
    Replies: 2
    Last Post: 12th February 2010, 17:20
  4. about QAbstractItemDelegate
    By drizzlefsh in forum Qt Programming
    Replies: 4
    Last Post: 11th September 2009, 07:01
  5. Use of QAbstractItemDelegate::closeEditor
    By jml in forum Qt Programming
    Replies: 3
    Last Post: 3rd August 2007, 22:55

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.