Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Update: Forum Guidelines & Code of Conduct


    Qt World Summit: Early-Bird Tickets

    Show and hide a window slowly in QWidet

    General and Desktop
    3
    7
    890
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • M
      morita last edited by

      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 ?

      1 Reply Last reply Reply Quote 0
      • Christian Ehrlicher
        Christian Ehrlicher Lifetime Qt Champion last edited by

        see for example here: https://doc.qt.io/qt-5/animation-overview.html#easing-curves

        Qt has to stay free or it will die.

        1 Reply Last reply Reply Quote 0
        • M
          morita last edited by

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

          B 1 Reply Last reply Reply Quote 0
          • B
            Bonnie @morita last edited by

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

            1 Reply Last reply Reply Quote 0
            • M
              morita last edited by

              @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";
              }
              

              }

              B 1 Reply Last reply Reply Quote 0
              • B
                Bonnie @morita last edited by Bonnie

                @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
                }
                
                M 1 Reply Last reply Reply Quote 2
                • M
                  morita @Bonnie last edited by

                  @Bonnie

                  Thank you so much for modifying my code.

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

                  I appreciate for your help.

                  1 Reply Last reply Reply Quote 0
                  • First post
                    Last post