2015-06-22 27 views
5

A QWidget jako funkcja paintEvent, która jest odpowiedzialna za jego rysunek. Aby poprawnie zaimplementować tę funkcję, obiekt QStyle służy do reprezentowania każdego komponentu i obiektu QStyleOption w celu zapisania statusu kontrolki.Gdzie zapisać stan animacji QWidget do użycia w funkcjach rysowania QStyle?

E.g: Niestandardowy ScrollBar wykonuje swoją paintEvent, która wywołuje drawComplexControl z opcją "CC_ScrollBar". Następnie można rozszerzyć QProxyStyle, aby zmienić wygląd paska przewijania.

Po najechaniu kursorem na użytkownika pojawia się paintEvent, który stosuje nowy "ukryty" wygląd, którego stan jest zapisany w QStyleOption::state. Ale na razie widżety dzienne, ten stan nie powinien być natychmiast aktualizowany, ale z płynnym przejściem (animacja) na około 100-500 milisekund. Aby animować widżet przy takim przejściu, potrzebne są pewne wartości, takie jak bieżący stan animacji (a mianowicie qreal/QColor?) Dla każdej części przewijania: górna strzałka, dolna strzałka lub suwak.


Po tym wstępie „długa”, moje pytanie przyjść:

Czy istnieje zmienna gdzieś ustawić stan tej animacji? Mogę przedłużyć QStyleOption z tą nową wartością, ale obecna implementacja już zawiera animację, nie mogę znaleźć miejsca, w którym zapisany został ten stan przejścia.

Poszukuję odpowiedzi kanonicznej.

Uwaga: Aby uniknąć "możliwego duplikatu ...", nawet jeśli jest to mało powiązane, NIE jest to kwestia sposobu korzystania z QAnimation lub tworzenia niestandardowych widgetów.

+0

"Obecna implementacja już zawiera animację" - czy możesz wskazać, gdzie dokładnie widziałeś animację przejścia w domyślnej implementacji Qt? –

+0

@PavelStrakhov: Na przykład QScrollBar: wskaźnik hover (niebieski w Windows 7) każdego komponentu zostanie zastosowany z krótką animacją. Mam na myśli to, że po najechaniu suwakiem, staje się niebieski na około 0.3s. Pozwól mi się dowiedzieć, czy nie możesz tego zobaczyć, a ja zamieszczam każdy krótki przykład. –

Odpowiedz

4

Animacje stylu wywodzą się z prywatnych QStyleAnimation (#include "qstyleanimation_p.h") i są one QAbstractAnimation, a tym samym QObject. Na przykład animacja stylu paska przewijania to QScrollbarStyleAnimation.

Oto jak styl windows drawControl pobiera wskaźnik do animacji:

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

Animacje dla różnych obiektów typu są zarządzane przez styl PIMPL'sanimation, startAnimation i stopAnimation metod. Podstawowy PIMPL definiujący te metody to QCommonStylePrivate (#include <private/qcommonstyle_p.h>).

Sposób chcesz użyć go w swoim własnym stylu byłoby:

  1. Wyprowadź swój styl z QCommonStyle użyj idiom PIMPL i czerpią swoją pimpl z QCommonStylePrivate. Mam documented the Qt's PIMPL idiom, aby było łatwiej.

  2. Ponownie użyj jednej z istniejących klas animacji stylu lub użyj funkcji wyprowadzenia własnej z QStyleAnimation.

  3. Wykorzystaj metody PIMPL do zarządzania animacjami. Najpierw jednak musisz utworzyć instancję animacji.

+0

Dziwne jest, jak QT blokuje jakąś część api, więc potrzebujemy albo ponownie zastosować lub użyć prywatnych zdań. Dziękuję za to imponujące wyjaśnienie. –

+0

@AdrianMaire Jest to zrobione celowo. Te części są z definicji * nie * interfejsem API. API jest tym, co wyeksponujesz, jeśli jest prywatne, to nie API. Ujawnienie takich wewnętrznych elementów byłoby bardzo problematyczne, ponieważ kiedy stworzysz coś z publicznego API, nigdy nie będziesz mógł go zmodyfikować w binarny, niekompatybilny sposób. Dla szczegółów implementacji niskiego poziomu, takich jak style, byłoby raczej bezcelowe. Jeśli chcesz ponownie użyć stylów Qt, tracisz binarną kompatybilność i jesteś zależny od konkretnej wersji Qt, z którą skompilowałeś się, i musisz przekompilować dla każdej nowej wersji Qt. –

+0

@AdrianMaire Jest to kompromis pomiędzy tym, ile chcesz ponownie wykorzystać i jak dużą elastycznością. Ponieważ nominalnie wysyłasz komercyjną aplikację z określoną wersją Qt, brak BC z innymi wersjami Qt nie stanowi problemu. –