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);
}
20
demandé sur Angie Quijano 2013-09-30 10:36:25

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.
26
répondu Volomike 2015-10-07 06:24:06

vous pouvez mettre vos widgets dans un QGraphicsScene. Il supporte le changement d'opacité et l'animation.

Voir QGraphicsProxyWidget documentation pour un exemple.

1
répondu Pavel Strakhov 2013-09-30 08:15:01

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

1
répondu Marek R 2013-09-30 09:28:19