Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

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 ?


  • Qt Champions 2019



  • 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.

    1. https://doc.qt.io/qt-5/qwindow.html#opacity-prop
      This is a property of QWindow 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.
    2. https://doc.qt.io/qt-5/qgraphicsopacityeffect.html#opacity-prop
      This is a property of QGraphicsOpacityEffect, 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.



  • @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_OBJECT

    public:
    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 in QWidget which does the same thing and is more convenient than using QWindow 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
    }
    


  • @Bonnie

    Thank you so much for modifying my code.

    I checked your code you modified. The project worked correctly.

    I appreciate for your help.


Log in to reply