qt animation opacity fadeout qpainter

¿Cómo hacer que los widgets Qt se atenúen o desaparezcan?



animation opacity (3)

Estoy tratando de desvanecer y desvanecer un QLabel o, en QWidget cualquier subclase de QWidget . He intentado con QGraphicsEffect , pero desafortunadamente solo funciona bien en Windows y no en Mac.

La única otra solución que puede funcionar tanto en Mac como en Windows parece ser tener mi propio paintEvent personalizado donde establezco la opacidad de QPainter y también defino una Q_PROPERTY para "opacidad" en mi QLabel derivado y cambio la opacidad mediante QPropertyAnimation .

Estoy pegando debajo del fragmento de código relevante para su referencia. Sigo viendo un problema aquí: reutilizar QLabel::paintEvent no parece funcionar, solo funciona si hago una pintura personalizada completa con QPainter , pero no parece ser una manera fácil y si necesito hacer eso para cada subclase de QWidget que quiero desvanecer, es una pesadilla. Por favor, aclare si estoy haciendo algún error obvio aquí.

Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity) void MyLabel::setOpacity(qreal value) { m_Opacity = value; repaint(); } void MyLabel::paintEvent((QPaintEvent *pe) { QPainter p; p.begin(this); p.setOpacity(); QLabel::paintEvent(pe); p.end(); } void MyLabel::startFadeOutAnimation() { QPropertyAnimation *anim = new QPropertyAnimation(this, "opacity"); anim->setDuration(800); anim->setStartValue(1.0); anim->setEndValue(0.0); anim->setEasingCurve(QEasingCurve::OutQuad); anim->start(QAbstractAnimation::DeleteWhenStopped); }


En realidad, hay una manera muy fácil de hacer esto sin las intercepciones desordenadas de QPaintEvent y sin los requisitos QGraphicsProxyWidget de QGraphicsProxyWidget , que no funciona en los niños de widgets promocionados. La siguiente técnica funcionará incluso con los widgets promocionados y los widgets de sus hijos.

Desvanecerse en su widget

// w is your widget QGraphicsOpacityEffect *eff = new QGraphicsOpacityEffect(this); w->setGraphicsEffect(eff); QPropertyAnimation *a = new QPropertyAnimation(eff,"opacity"); a->setDuration(350); a->setStartValue(0); a->setEndValue(1); a->setEasingCurve(QEasingCurve::InBack); a->start(QPropertyAnimation::DeleteWhenStopped);

Desvanece tu widget

// w is your widget QGraphicsOpacityEffect *eff = new QGraphicsOpacityEffect(this); w->setGraphicsEffect(eff); QPropertyAnimation *a = new QPropertyAnimation(eff,"opacity"); a->setDuration(350); a->setStartValue(1); a->setEndValue(0); a->setEasingCurve(QEasingCurve::OutBack); a->start(QPropertyAnimation::DeleteWhenStopped); connect(a,SIGNAL(finished()),this,SLOT(hideThisWidget())); // now implement a slot called hideThisWidget() to do // things like hide any background dimmer, etc.


Intente exponer una parte de la paleta como propiedad de la etiqueta y luego anímela:

Q_PROPERTY(QColor color READ color WRITE setColor) void MyLabel::setColor(const QColor &value) { QPalette palette; palette.setBrush(QPalette::WindowText, value); setPalette(palette); } QColor MyLabel::color() { return palette(QPalette::Normal, QPalette::Window). } void MyLabel::startFadeOutAnimation() { QPropertyAnimation *animation = new QPropertyAnimation(label, "color", this); QColor c = label->color(); animation->setKeyValueAt(0, c); c.setAlpha(0); animation->setKeyValueAt(1, c); animation->setEasingCurve(QEasingCurve::OutQuad); animation->setDuration(1000); animation->start(QAbstractAnimation::DeleteWhenStopped); }

Puede intentar evitar las subclases definiendo y registrando un nuevo interpolador que manejará QPalette qRegisterAnimationInterpolator , pero esto es un poco complicado.


Puedes poner tus widgets en un QGraphicsScene . Soporta cambio de opacidad y animación.

Consulte la documentación de QGraphicsProxyWidget para ver un ejemplo.