Efficiently updating a QTableView at high speed

后端 未结 3 1126
萌比男神i
萌比男神i 2021-02-06 07:05

I\'m using a QTableView with a subclass of QItemDelegate to control the look and feel of the tableview\'s cells.

Each cell displays the name and status of a of an extern

相关标签:
3条回答
  • 2021-02-06 07:20

    since your QTableView inherits QWidget, you can call the following on it:

    setUpdatesEnabled(false);
    changeAllYourData();
    setUpdatesEnabled(true);
    

    When setUpdatesEnabled is false, any paint() or update() call on it has no effect. So, you could stop it from updating, change all your data and then reenable it, possibly by manually calling paint() or update() manually on it, I'm not sure about this part.

    Here is the doc for the setUpdatesEnabled method.

    QWidget updatesEnabled

    Hope this helps.

    EDIT after comment from user:

    You could implement your own setUpdatesEnabled(bool) for your QItemDelegate subclass (since it does not inherit QWidget and does not have one) by testing a flag before executing your original paint() or update(). After that, you could specify for every cell (or row or column) of your QTableView if they must be updated or repainted.

    By doing this, you could stop your other cells (delegates) from repainting, unless you change the setUpdatesEnabled flag you created manually, but keep the updates on your cells containing a graph.

    I must say I never tested this or anything like this, so I hope it works the way I think it does.

    Best of luck

    EDIT after edit from user:

    Following my previous comment, instead of setting a flag for every cell (I thought your graph was in a separate cell), you could set a flag for every delegate to paint only your graph or the whole image.

    Hope this helps,

    EDIT:

    I stumbled upon a new feature in Qt 4.7 (I do not know if it's possible for you to use it, but it could solve some of your problems.) The feature is QStaticText. It is a class that allows you to cache text (font and effects) and paint them faster. See the link here.

    Hope it could solve your problem.

    0 讨论(0)
  • 2021-02-06 07:32

    It's rare that I suggest this path rather than delegates, but it appears in your situation it might be worth it. I'd consider making my own view, which is aware enough to only update the portions of the screen that need to be updated. A view widget like this is obviously a bit more special-purpose than would usually be the case, but if you really need the efficiency, it's one way to go.

    Other things to consider if you need a small boost in efficiency are making sure you only mark the rows changed that actually change (if the sensor values don't change that often, and are only polled that often) or consider adding a hysteresis value between which it isn't actually redrawn (if the sensor values don't change quickly enough to negate this).

    0 讨论(0)
  • 2021-02-06 07:38

    Cache the background image (cell background image, status and name) to the model as a QPixmap. Redraw that pixmap only when the status or the name are changed. In the common case you will only need to draw the cached QPixmap and the sensor value on top of that.

    Edit:

    Add fullRepaintNeeded flag to your data class. When status or name is changed, fullRepaintNeeded is set to true.

    When the delegate is painting the item, the delegate first checks the item's fullRepaintNeeded flag. If fullRepaintNeeded is true, then a new QPixmap is created and everything is painted to that QPixmap which is finally painted to the tableview. The QPixmap is then cached to the model (which means to your data class) with model's setData-function (but dataChanged is not called). fullRepaintNeeded is now set to false.

    But if fullRepaintNeeded is false in the delegate's paint function, a previously cached QPixmap is asked from the model, drawn to the tableview and the finally sensor value is drawn on top of that.

    0 讨论(0)
提交回复
热议问题