¿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.