5

A QWidget as a paintEvent function which is responsible of his drawing. To implement correctly this function, a QStyle object is used to represent each component and a QStyleOption object to save the status of the control.

E.g: A custom ScrollBar implement his paintEvent, which call drawComplexControl with the option "CC_ScrollBar". Then, QProxyStyle could be extended to change the appearance of the scroll-bar.

When the user hover the slider, paintEvent is called which apply the new "hovered" appearance, which state is saved in the QStyleOption::state. But for now a day widgets, this state should not be updated instantly, but with a smooth transition (animation) over some 100-500 milliseconds. In order to animate the widget with this transition some values are needed, like the current state of the animation (a qreal/QColor?) for each part of the scroll: top arrow, bottom arrow or slider.


After this "long" introduction, my question come:

Is there a variable somewhere to set the state of this animation? I could extend QStyleOption with this new value, but the current implementation already seem to include animation, I am unable to found where this transition state is saved.

I am looking for a canonical answer.

Note: To avoid "possible duplicate of...", even if slightly related, this is NOT a question about how to use QAnimation or creating custom Widgets.

Kuba hasn't forgotten Monica
  • 88,505
  • 13
  • 129
  • 275
Adrian Maire
  • 11,506
  • 8
  • 34
  • 72
  • "current implementation already seem to include animation" - can you point out where exactly have you seen transition animation in default Qt implementation? – Pavel Strakhov Jun 22 '15 at 11:28
  • @PavelStrakhov: For example the QScrollBar: the hover(blue in windows 7) of each component is applied with a short animation. I mean that when you hover the slider, it become blue over something like 0.3s. Let's me to know if you are not able to see it, and I upload any short example. – Adrian Maire Jun 22 '15 at 11:35

1 Answers1

4

The style animations are derived from the private QStyleAnimation (#include "qstyleanimation_p.h"), and they are QAbstractAnimation and thus QObject. For example, the scrollbar style animation is the QScrollbarStyleAnimation.

Here's how the Windows style's drawControl gets the pointer to the animation:

if (QProgressStyleAnimation *animation = 
  qobject_cast<QProgressStyleAnimation*>(d->animation(opt->styleObject)))

The animations for various style objects are managed by the style PIMPL's animation, startAnimation and stopAnimation methods. The base PIMPL that defines these methods is QCommonStylePrivate (#include <private/qcommonstyle_p.h>).

The way you'd use it in your own style would be to:

  1. Derive your style from QCommonStyle, use the PIMPL idiom, and derive your pimpl from QCommonStylePrivate. I've documented the Qt's PIMPL idiom to make it easier.

  2. Reuse one of the existing style animation classes, or use derive your own from QStyleAnimation.

  3. Leverage the QCommonStyle PIMPL's methods to manage the animations. It's on you to create the animation instance first, though.

Community
  • 1
  • 1
Kuba hasn't forgotten Monica
  • 88,505
  • 13
  • 129
  • 275
  • It is strange how QT block some part of the api, so we need either to reimplement or to use private clases. Thanks you for this impressive explanation. – Adrian Maire Jun 23 '15 at 06:16
  • @AdrianMaire It's done on purpose. These parts are *not* API by definition. API is what you expose, if it's private it's not API. Exposing such internals would be very problematic, since once you make something a public API, you can't ever modify it in a binary incompatible way. For low-level implementation details such as styles, it'd be rather pointless. If you want to reuse Qt's styles, you lose the binary compatibility and are dependent on the particular Qt version you compiled with, and you have to recompile for each new Qt version. – Kuba hasn't forgotten Monica Jun 23 '15 at 16:49
  • @AdrianMaire It's a tradeoff between how much you want to reuse and how much flexibility you get. Since nominally you'd ship a commercial application with a particular version of Qt, the lack of BC with other Qt versions is not a problem. – Kuba hasn't forgotten Monica Jun 23 '15 at 16:49
  • 1
    I may be wrong but if you compile your commercial application with a private part of Qt you can run through license issues in case you don't have a commercial license of Qt (LGPL version could not be enough). I think another way is to implement animation directly inside your QCommonStyle subclass using event filters. Install your style as event filter to a widget inside polish() member, and handle animation for each widget from eventfilter member. – Vinícius A. Jorge Oct 31 '16 at 12:24