Show and hide a window slowly in QWidet
-
Hello.
I am trying to show and hide a window slowly in QWidet. I mean I want to control the duration of the time to show and hide a window. Because when I used "setvisible" property to show and hide a window, I felt like being fast about the duration.
Maybe if I use "QPropertyAnimation" property , I think I can implement what I want to do. But I do not understand how to use "QPropertyAnimation".
For example, there being one button on a window , if I push the button , a new window like a popup displays slowly.
Do you have any tips how to solve my problem ? -
see for example here: https://doc.qt.io/qt-5/animation-overview.html#easing-curves
-
Thank you for replying.
And how do you show and hide a window ?
If I use "setVisible" property in QWidget , I can show and hide a window.
But I don't know how I should implement using "setVisible" and "QPropertyAnimation".
In case of "setVisible", the argument is bool value. But in case of "setStartValue" and setEndValue in "QPropertyAnimation", I guess the argument is some values.
That's why I don't understand what I have implement using "QPropertyAnimation".
-
@morita
Yeah, I think "visible" property cannot be used to make animation.
I guess you want fade-in and fade-out effect? That seems to need setting the opacity.First, without thinking about opacity, you can consider setting the geometry property.
Showing from very small to the actually size, and vice versa. Or from screen edge to the center, and so on...
It seems easier.And you can totally refer to the examples in the doc.Then, if you really want to set the opacity, I haven't tried those but I can think of two methods.
- https://doc.qt.io/qt-5/qwindow.html#opacity-prop
This is a property ofQWindow
so you can only use it on a window widget. Get it from QWidget::windowHandle().
And it only works when the system supports window opacity. - https://doc.qt.io/qt-5/qgraphicsopacityeffect.html#opacity-prop
This is a property ofQGraphicsOpacityEffect
, you need to new a effect and set to your widget by QWidget::setGraphicsEffect.
But there's a note from the doc: graphics effects are not supported for OpenGL-based widgets.
And remember to call show() before a showing animation and hide() after a hiding animation.
- https://doc.qt.io/qt-5/qwindow.html#opacity-prop
-
@Bonnie said in Show and hide a window slowly in QWidet:
QWidget::windowHandle()
Hello.
Thank you for your advice.
I want to fade-in and fade-out.
As you say , I was trying to do cording.
But there is something wrong with cording because my project didn't work correctly.
For the first time, how do you use QWidget::windowHandle() ?
I didn't understand how to use that. So I didn't use that and that may influence my project.If you can, I would like to check my project about which is wrong.
■widget.h
#include <QWidget>
#include <QDebug>
#include "secdialog.h"
#include <QPropertyAnimation>
#include <QGraphicsOpacityEffect>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECTpublic:
Widget(QWidget *parent = nullptr);
~Widget();bool bClicked; void setAnimationDisp(bool bDispVisible);
private slots:
void on_pushButton_clicked();private:
Ui::Widget *ui;
SecDialog *secdialog;
QGraphicsOpacityEffect *eff;
QPropertyAnimation *m_Animation;
};■widget.cpp
#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
secdialog = new SecDialog(this); ←//new window
eff = new QGraphicsOpacityEffect(this);
m_Animation = new QPropertyAnimation(eff,"opacity");
bClicked = true;
}Widget::~Widget()
{
delete ui;
}void Widget::on_pushButton_clicked()
{
if ( bClicked == true ) {
secdialog->show();
bClicked = false;
this->setAnimationDisp(bClicked);
qDebug() << "a";
} else {
bClicked = true;
this->setAnimationDisp(bClicked);
secdialog->hide();
qDebug() << "b";
}
}void Widget::setAnimationDisp(bool bDispVisible)
{
this->setGraphicsEffect(eff);if( bDispVisible ){ m_Animation->setStartValue(1.0); m_Animation->setEndValue(0); m_Animation->setEasingCurve(QEasingCurve::OutBack); m_Animation->setDuration(100000); m_Animation->start(QPropertyAnimation::DeleteWhenStopped); qDebug() << "false"; } else { m_Animation->setStartValue(0); m_Animation->setEndValue(1.0); m_Animation->setEasingCurve(QEasingCurve::InBack); m_Animation->setDuration(100000); m_Animation->start(QPropertyAnimation::DeleteWhenStopped); qDebug() << "true"; }
}
-
@morita I've tested the two methods, it looks like QGraphicsOpacityEffect cannot be used on a window widget.
But QWindow works well. Here's my test code.
[Added]
Hey, I found there is a windowOpacity property inQWidget
which does the same thing and is more convenient than usingQWindow
directly.
I've updated my code to use that.#include "widget.h" #include "ui_widget.h" Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui->setupUi(this); bDialogShown = false; secdialog = new SecDialog(this); //new window m_Animation = new QPropertyAnimation(secdialog, "windowOpacity", this); connect(m_Animation, &QPropertyAnimation::finished, this, &Widget::animationFinished); } Widget::~Widget() { delete ui; } void Widget::on_pushButton_clicked() { this->setAnimationDisp(bDialogShown); bDialogShown = !bDialogShown; } void Widget::animationFinished() { if(!bDialogShown) secdialog->hide(); //hide after animation finished } void Widget::setAnimationDisp(bool currentlyVisible) { m_Animation->stop();//stop the current animation if running if( currentlyVisible ){ //To hide m_Animation->setStartValue(1.0); m_Animation->setEndValue(0.0); } else { //To show secdialog->setWindowOpacity(0.0); secdialog->show();//show before animation, but set opacity first to make sure it doesn't "jump out" suddenly m_Animation->setStartValue(0.0); m_Animation->setEndValue(1.0); } m_Animation->setEasingCurve(QEasingCurve::Linear); m_Animation->setDuration(1000);//100000ms is way too long for a fading animation, don't you think? I set it to 1s m_Animation->start();//don't set the animation to be deleted when stopped, we'll keep using it }