web-dev-qa-db-ja.com

Qtウィジェットをフェードインまたはフェードアウトさせる方法は?

私はQLabelをフェードインおよびフェードアウトしようとしています。さらに言えば、QWidgetサブクラスです。私はQGraphicsEffectを試してみましたが、残念ながらWindowsでのみ機能し、Macでは機能しません。

MacとWindowsの両方で機能する他の唯一のソリューションは、独自のカスタムpaintEventを使用しているようです。ここで、QPainterの不透明度を設定し、派生したQLabelで「不透明度」のQ_PROPERTYを定義し、QPropertyAnimationを使用して不透明度を変更します。

参考のために、関連するコードスニペットの下に貼り付けています。ここでも問題が発生します-QLabel::paintEventの再利用は機能していないようです。QPainterを使用して完全なカスタムペイントを実行した場合にのみ機能しますが、それは簡単な方法ではないようです。フェードアウトしたいQWidgetサブクラスごとにこれを行う必要があります。これは悪夢です。ここで明らかな間違いを犯しているかどうかを明確にしてください。

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);
}
22
Soumya Das

実際には、面倒なQPaintEventインターセプトなしで、またQGraphicsProxyWidgetの厳しい要件なしでこれを行う非常に簡単な方法があります。これは、プロモートウィジェットの子では機能しません。以下の手法は、プロモートされたウィジェットとその子ウィジェットでも機能します。

ウィジェットのフェードイン

// 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);

ウィジェットをフェードアウト

// 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.
30
Volomike

パレットの一部をラベルのプロパティとして公開し、アニメーション化してみてください:

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);
}

QPalette qRegisterAnimationInterpolator を処理する新しいインターポレーターを定義して登録することで、サブクラス化を回避できますが、これは少し複雑です。

1
Marek R

ウィジェットをQGraphicsSceneに入れることができます。不透明度の変更とアニメーションをサポートしています。

例については、QGraphicsProxyWidgetのドキュメントを参照してください。

1
Pavel Strakhov