Как заставить виджеты Qt исчезать или исчезать?
Я пытаюсь затухать и исчезать QLabel
или, в этом отношении, любой подкласс QWidget
. Я попытался с QGraphicsEffect
, но, к сожалению, он работает хорошо только на Windows, а не на Mac.
Единственное другое решение, которое может работать как на Mac, так и на Windows, похоже, имеет собственный пользовательский paintEvent
где я устанавливаю непрозрачность QPainter
а также определяю Q_PROPERTY
для "непрозрачности" в моей производной QLabel
и изменяю непрозрачность через 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);
}
Ответы
Ответ 1
На самом деле это очень простой способ сделать это без беспорядочного перехвата QPaintEvent
и без жестких требований QGraphicsProxyWidget
, который не работает на продвинутых дочерних QPaintEvent
. Нижеприведенная техника будет работать даже с продвинутыми виджетами и видениями их детей.
Fade In 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(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.
Ответ 2
Вы можете поместить свои виджеты в QGraphicsScene
. Он поддерживает изменение непрозрачности и анимацию.
Для примера см. Документацию QGraphicsProxyWidget
.
Ответ 3
Попробуйте выставить некоторую часть палитры как свойство метки, а затем оставьте ее:
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, но это немного сложно.