QDialog有很多打开和关闭的功能,比如open(),show(),exec(),close(),hide()。我不知道重新实现哪个函数()。
//编辑: 在showEvent()函数中启动动画是一个不错的选择。
答案 0 :(得分:3)
简短回答:void exec()
长答案:void exec()
但是
您需要决定“淡入”工作的方式并了解如何使用QPropertyAnimation
例如,您可以更改对话框的不透明度:
#include <QPropertyAnimation>
int MyDialog::exec()
{
this->setWindowOpacity(0.0);
QPropertyAnimation* anim = new QPropertyAnimation(this, "windowOpacity");
anim->setDuration(5000); // will take 5 seconds
anim->setEasingCurve(QEasingCurve::OutBack); // just demonstration, there are a lot of curves to choose
anim->setStartValue(0.0);
anim->setEndValue(1.0);
anim->start(QAbstractAnimation::DeleteWhenStopped);
return QDialog::exec();
}
int main(int argc, char** argv)
{
QApplication a(argc, argv);
MyDialog w;
int ret = w.exec();
return a.exec();
}
您可以为Property
定义的任何QObject
制作动画,其他所有内容都使用不同的动画和持续时间
编辑:改编使用QDialog::exec()
,在Qt4.8.5,Vs2008,Win7Professionalx64上测试
欢呼声
答案 1 :(得分:0)
覆盖QDialog::open是解决之道。与QDialog::exec不同,它将在调用QDialog::finished时立即返回。另外,文档建议不要使用exec。
下面的代码很好用。
class AnimatedDialog : public QDialog
{
Q_OBJECT
public:
explicit AnimatedDialog(QWidget* parent = nullptr);
void animate(bool reverse = false);
void done(int r) override;
void open() override;
signals:
void reverseAnimStarted();
private:
bool animation_on = false;
};
AnimatedDialog::AnimatedDialog(QWidget* parent) : QDialog{parent}
{
setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::Popup | Qt::NoDropShadowWindowHint);
setAttribute(Qt::WA_TranslucentBackground);
connect(this, &AnimatedDialog::reverseAnimStarted,
[this] {animation_on = true; });
}
// override showEvent if you call show instead
void AnimatedDialog::open()
{
animate(false);
QDialog::open();
}
void AnimatedDialog::done(int r)
{
if (!animation_on) {
animate(true);
setResult(r);
if (r == QDialog::Accepted)
emit accepted();
else if (r == QDialog::Rejected)
emit rejected();
emit finished(r);
}
}
void AnimatedDialog::animate(bool reverse)
{
auto animFade= new QPropertyAnimation(this, "windowOpacity", this);
animFade->setDuration(400);
animFade->setEasingCurve(QEasingCurve::Linear);
auto pos1 = QPoint{ (parentWidget()->pos().x() + parentWidget()->width() / 2 - width() / 2) + 15,
(parentWidget()->pos().y() + parentWidget()->height() + height() / 2) / 2 };
auto pos2 = QPoint{ (parentWidget()->pos().x() + parentWidget()->width() / 2 - width() / 2) + 15,
(parentWidget()->pos().y() + parentWidget()->height() + height() / 2) / 2 - 65 };
auto animMove = new QPropertyAnimation(this, "pos", this);
animMove->setDuration(250);
animMove->setEasingCurve(QEasingCurve::OutQuad);
if (!reverse) {
animFade->setStartValue(0.0);
animFade->setEndValue(1.0);
animMove->setStartValue(pos2);
animMove->setEndValue(pos1);
} else {
emit reverseAnimStarted();
animFade->setStartValue(1.0);
animFade->setEndValue(0.0);
animMove->setStartValue(pos1);
animMove->setEndValue(pos2);
connect(animFade, &QPropertyAnimation::finished,
[this] { QDialog::hide(); });
}
animFade->start(QAbstractAnimation::DeleteWhenStopped);
animMove->start(QAbstractAnimation::DeleteWhenStopped);
}
void UI::viewDialog() {
auto dialog = new AnimatedDialog{ this };
dialog->open();
connect(dialog, &AnimatedDialog::finished,
[=] {}
});
}