我想要一个小部件在显示/隐藏时为其不透明度设置动画。我使用下面的代码,但它不起作用。
如果我为属性“maximumHeight”设置动画,则会在show()中设置动画,但不会在hide()中设置动画。有人能告诉我哪里出错了吗?
标题文件
byeform.h
#include <QWidget>
#include <QPropertyAnimation>
namespace Ui {
class ByeForm;
}
class ByeForm : public QWidget
{
Q_OBJECT
public:
explicit ByeForm(QWidget *parent = 0);
~ByeForm();
private:
Ui::ByeForm *ui;
QPropertyAnimation *mpTransition;
protected:
bool eventFilter(QObject *obj, QEvent *event);
};
源文件
byeform.cpp
#include "byeform.h"
#include "ui_byeform.h"
#include <QDebug>
ByeForm::ByeForm(QWidget *parent) :
QWidget(parent),
ui(new Ui::ByeForm)
{
ui->setupUi(this);
this->installEventFilter(this);
mpTransition = new QPropertyAnimation(this, "windowOpacity");
mpTransition->setDuration(1000);
mpTransition->setStartValue(0.00);
mpTransition->setEndValue(1.00);
}
ByeForm::~ByeForm()
{
delete ui;
}
bool ByeForm::eventFilter(QObject *obj, QEvent *event)
{
if (this == obj && QEvent::Show == event->type())
{
qDebug() << Q_FUNC_INFO << "in show";
mpTransition->setDirection(QAbstractAnimation::Forward);
mpTransition->start();
}
else if (this == obj && (QEvent::Hide == event->type() ||
QEvent::Close == event->type()))
{
mpTransition->setDirection(QAbstractAnimation::Backward);
mpTransition->start();
}
return false;
}
答案 0 :(得分:0)
这可以解决吗?
bool ByeForm::eventFilter(QObject *obj, QEvent *event)
{
if (this == obj && QEvent::Show == event->type())
{
qDebug() << Q_FUNC_INFO << "in show";
mpTransition->setDirection(QAbstractAnimation::Forward);
mpTransition->start();
return true; // you might want to remove this line
}
else if (this == obj && (QEvent::Hide == event->type() ||
QEvent::Close == event->type()))
{
mpTransition->setDirection(QAbstractAnimation::Backward);
mpTransition->start();
return true; // you might want to remove this line
}
return QWidget::eventFilter(obj, event);
}
当然,它不起作用,因为它在您开始动画时已经隐藏了。在动画结束之前,您需要延长可见性。
像这样,也许:
void ByeForm::setVisible(bool visible)
{
if(isVisible() && !visible) // transition to hide
{
// m_bHideCalled = true;
mpTransition->setDirection(QAbstractAnimation::Backward);
mpTransition->start();
QTimer::singleShot(1000, this, SLOT(hide());
}
if(!isVisible() && visible) // transition to show
{
mpTransition->setDirection(QAbstractAnimation::Forward);
mpTransition->start();
show();
}
// if(m_bHideCalled)
// {
// m_bHideCalled = false;
// hide();
// }
}
请注意,您可能需要m_bHideCalled。在构造函数中将其设置为false。这个名字可能会更好。
答案 1 :(得分:0)
它有效,但我认为这不是一个很好的方法(我认为你应该在关闭事件发生前做动画)
bool ByeForm::eventFilter(QObject *obj, QEvent *event)
{
if (this == obj && QEvent::Show == event->type())
{
qDebug() << Q_FUNC_INFO << "in show";
mpTransition->setDirection(QAbstractAnimation::Forward);
mpTransition->start();
}
else if (this == obj && (QEvent::Hide == event->type() ||
QEvent::Close == event->type()))
{
mpTransition->setDirection(QAbstractAnimation::Backward);
mpTransition->start();
while (mpTransition->state() == QAbstractAnimation::Running)
{
QApplication::processEvents();
}
}
return false;
}
其他方法
你也可以像这样覆盖closeEvent方法:
void MainWindow::closeEvent(QCloseEvent* e)
{
mpTransition->setDirection(QAbstractAnimation::Backward);
mpTransition->start();
e->ignore();
}
但是在这种情况下你应该在animate完成后做一些事情(例如连接信号finished
并调用一些方法来关闭窗口/应用程序/等)。
您也应该检查,手动调用关闭事件或用户操作。