Animating a Delegate
-
Is there a standard way to animate a delegate?
I want to create a delegate that shows an item in a loading state. There are three possibilities for the state of the item:
Unloaded,Loading, orLoaded. While the item is in theLoadingstate, I want the delegate to show an animated spinning wheel. (Note that I don't have actual progress for how far loaded the item is. I just know that it is in aLoadingstate.)Is it possible for a delegate to be animated like that? Do I need to constantly emit
dataChanged()from the model to force the delegate to be repainted? Or is there a way for the delegate to force itself to be repainted every frame (or on a repeating timer), without relying on the model emitting adataChanged()signal? -
Hi,
How many items are you expecting to show at a given time ?
-
@SGaist In a usual case, I wouldn't expect to show more than fifty at once. There may be some edge cases where I show a few hundred.
-
Then I wouldn't recommend showing fifty to several hundreds spinning wheels at the same time. Not that it's not doable but this sounds like a waste of resources.
In any case, one possible way to implement that is to do the painting yourself and have a timer at the model level that triggers every so often incrementing a number that would correspond to the number of points you want to show.
Another possible way to do that, that is also less complicated, is to simply have your model returnLoading .,Loading..,Loading...and loop on that (or more dots).
It's also a sort of animation but you don't need a special delegate. -
Adding to @SGaist: Maybe a progress bar delegate is a better alternative. While showing both the loading state and the progress, you don’t need permanent signal emissions. If it’s minuscule, it needs no more than 10-15 updates between 0 and 100%.
Theoretically, if you get hold of its pointer, you could even update it from outside the model, e.g. from a worker thread with a signal/slot connection. The model would just notify the view that loading has been triggered. The view creates the progress bar delegate and informes the worker about the pointer, who keeps it in a QPointer to know whether it is still around. -
Is there a standard way to animate a delegate?
I want to create a delegate that shows an item in a loading state. There are three possibilities for the state of the item:
Unloaded,Loading, orLoaded. While the item is in theLoadingstate, I want the delegate to show an animated spinning wheel. (Note that I don't have actual progress for how far loaded the item is. I just know that it is in aLoadingstate.)Is it possible for a delegate to be animated like that? Do I need to constantly emit
dataChanged()from the model to force the delegate to be repainted? Or is there a way for the delegate to force itself to be repainted every frame (or on a repeating timer), without relying on the model emitting adataChanged()signal?@peter.thompson said in Animating a Delegate:
Do I need to constantly emit dataChanged() from the model to force the delegate to be repainted? Or is there a way for the delegate to force itself to be repainted every frame (or on a repeating timer), without relying on the model emitting a dataChanged() signal?
You would have to write a timer yourself that constantly updates; Qt does not have something like frames. Just make sure it doesn't use too much CPU (users tend to notice at some point and complain). Usually, calling dataChanged() is the better alternative. However, from updating progress bars I know that updating too often will also slow down your actual loading. That's why I usually use
QTimeand only if more than 50ms have elapsed do I actually update the progress bar (which would be calling dataChanged() every 50ms in your case). -
Is there a standard way to animate a delegate?
I want to create a delegate that shows an item in a loading state. There are three possibilities for the state of the item:
Unloaded,Loading, orLoaded. While the item is in theLoadingstate, I want the delegate to show an animated spinning wheel. (Note that I don't have actual progress for how far loaded the item is. I just know that it is in aLoadingstate.)Is it possible for a delegate to be animated like that? Do I need to constantly emit
dataChanged()from the model to force the delegate to be repainted? Or is there a way for the delegate to force itself to be repainted every frame (or on a repeating timer), without relying on the model emitting adataChanged()signal?@peter.thompson
Further to my colleagues' replies. A couple of extra possibilities. I don't know whether they are suitable, might depend on how/where you use the delegate, but just to be aware of:-
Qt has an Animation Framework, "It enables you to animate a Qt property value of a widget or QObject.". You may be able to use its built-in timing rather than roll your own
QTimer. Though as @SGaist observed, if you have "fifty at once" you won't want to maintain 50 separate widgets for this. -
Otherwise, instead of making the model have to emit
dataChanged()repeatedly, I believeview->update(view->visualRect(index));(or even a more generalview->viewport()->update();orview->update();) may/should force a repaint with just a view-side call.
-