Comment faire pour que les widgets Qt s'effacent ou s'effacent?
je suis en train de fade in et fade out QLabel
ou de QWidget
sous-classe. J'ai essayé avec QGraphicsEffect
, mais malheureusement cela fonctionne bien seulement sur Windows et pas sur Mac.
la seule autre solution qui peut fonctionner à la fois sur Mac et Windows semble avoir ma propre coutume paintEvent
où j'ai mis l'opacité de QPainter
et aussi définir un Q_PROPERTY
pour "l'opacité" dans mon dérivée QLabel
et modifier l'opacité par QPropertyAnimation
.
je suis coller en dessous de la extrait de code pertinent pour votre référence. Je vois encore un problème ici, - la réutilisation de l' QLabel::paintEvent
ne semble pas fonctionner, il ne fonctionne que si je fais une peinture complète sur mesure en utilisant le QPainter
, mais ça ne semble pas être un moyen facile et si j'ai besoin de le faire pour tous les QWidget
sous-classe je veux disparaître, c'est un cauchemar. Veuillez préciser si je fais une erreur évidente.
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);
}
3 réponses
il y a en fait un moyen super facile de faire cela sans désordre QPaintEvent
intercepte et sans les rudes exigences de QGraphicsProxyWidget
, qui ne fonctionne pas sur les enfants widget promus. La technique ci-dessous fonctionnera même avec les widgets promus et les widgets de leurs enfants.
Fondu Dans Votre 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);
Fade Out Your 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.
vous pouvez mettre vos widgets dans un QGraphicsScene
. Il supporte le changement d'opacité et l'animation.
Voir QGraphicsProxyWidget
documentation pour un exemple.
Essayez d'exposer une partie de la palette en tant que propriété de l'étiquette de l'animation:
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);
}
Vous pouvez essayer d'éviter le sous-classement en définissant et en enregistrant un nouvel interpolateur qui traitera QPalette qRegisterAnimationInterpolator, mais c'est un peu compliqué.