私は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);
}
実際には、面倒な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.
パレットの一部をラベルのプロパティとして公開し、アニメーション化してみてください:
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 を処理する新しいインターポレーターを定義して登録することで、サブクラス化を回避できますが、これは少し複雑です。
ウィジェットをQGraphicsScene
に入れることができます。不透明度の変更とアニメーションをサポートしています。
例については、QGraphicsProxyWidget
のドキュメントを参照してください。