Qt implements the sidebar slide-out menu effect

1. Renderings

2. Implementation principle

Two widgets are made here, one is a widget that displays the base map, and the other is a widget that displays animations.

These two widgets need to overlap. Animated widgets need to set attributes to be superimposed on the basemap widget. Set the following attributes:

setWindowFlags(Qt::FramelessWindowHint | Qt::SubWindow | Qt::WindowStaysOnTopHint);

The background of the animated widget needs to be made transparent. I put a QFrame on it and then set the style:

QFrame#frame
{
background-color: rgba(255, 255, 255, 100);
}

A QStackedWidget is placed on top of the animated widget. One is used to display the image of > and the other is used to display the menu.

Animation effects: The QPropertyAnimation class provides animation support and changes geometry properties.

 m_slideOutAnimation = new QPropertyAnimation(this,"geometry");
    connect(m_slideOutAnimation, & amp;QPropertyAnimation::finished,this, & amp;SlideAnimationWidget::slotSlideOutFinished);
    m_slideOutAnimation->setEasingCurve(QEasingCurve::OutSine);
    m_slideOutAnimation->setDuration(1300);

    m_slideInAnimation = new QPropertyAnimation(this,"geometry");
    connect(m_slideInAnimation, & amp;QPropertyAnimation::finished,this, & amp;SlideAnimationWidget::slotSlideInFinished);
    m_slideInAnimation->setEasingCurve(QEasingCurve::InSine);
    m_slideInAnimation->setDuration(1300);

Finally, install the event filter: trigger animation effects through mouse entry and exit events.

 ui->label->installEventFilter(this);
 ui->controlWidget->installEventFilter(this);

3. Source code

#ifndef SLIDEANIMATIONWIDGET_H
#define SLIDEANIMATIONWIDGET_H

#include 
#include 
#include 
#include 

namespace Ui {
class SlideAnimationWidget;
}

#define SLIDE_MIN_WIDTH 10 //The minimum width for the sidebar to slide out
#define SLIDE_MAX_WIDTH 300 //The maximum width for the sidebar to slide out

class SlideAnimationWidget : public QWidget
{
    Q_OBJECT

public:
    explicit SlideAnimationWidget(QWidget *parent = 0);
    ~SlideAnimationWidget();

public:
    void setPos(int x,int y);

protected:
    bool eventFilter(QObject *obj, QEvent *event);

private slots:
    void slotSlideOutFinished();

    void slotSlideInFinished();

private:
    Ui::SlideAnimationWidget *ui;

private:
    QPropertyAnimation *m_slideOutAnimation = nullptr;
    QPropertyAnimation *m_slideInAnimation = nullptr;
    bool m_bShowSideflag = false; //Show sidebar
    bool m_bInComboBox = false;

    int m_posX = 0;
    int m_posY = 0;
    bool m_isInit = false;
};

#endif // SLIDEANIMATIONWIDGET_H


#include "SlideAnimationWidget.h"
#include "ui_SlideAnimationWidget.h"
#include 
#include 
#include 

SlideAnimationWidget::SlideAnimationWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::SlideAnimationWidget)
{
    ui->setupUi(this);

    setWindowFlags(Qt::FramelessWindowHint | Qt::SubWindow | Qt::WindowStaysOnTopHint);

    m_slideOutAnimation = new QPropertyAnimation(this,"geometry");
    connect(m_slideOutAnimation, & amp;QPropertyAnimation::finished,this, & amp;SlideAnimationWidget::slotSlideOutFinished);
    m_slideOutAnimation->setEasingCurve(QEasingCurve::OutSine);
    m_slideOutAnimation->setDuration(1300);

    m_slideInAnimation = new QPropertyAnimation(this,"geometry");
    connect(m_slideInAnimation, & amp;QPropertyAnimation::finished,this, & amp;SlideAnimationWidget::slotSlideInFinished);
    m_slideInAnimation->setEasingCurve(QEasingCurve::InSine);
    m_slideInAnimation->setDuration(1300);

    ui->stackedWidget->setCurrentIndex(0);

    ui->label->installEventFilter(this);
    ui->controlWidget->installEventFilter(this);
    ui->cbxFocusMode->view()->installEventFilter(this);
    ui->cbxField->view()->installEventFilter(this);
    ui->cbxFocusStep->view()->installEventFilter(this);

    this->setMaximumWidth(SLIDE_MIN_WIDTH);

}

SlideAnimationWidget::~SlideAnimationWidget()
{
    delete ui;
}

void SlideAnimationWidget::setPos(int x, int y)
{
    m_posX = x;
    m_posY = y;

    move(x,y);
}

bool SlideAnimationWidget::eventFilter(QObject *obj, QEvent *event)
{
    if(obj == ui->cbxFocusMode->view() ||
            obj == ui->cbxField->view() ||
            obj == ui->cbxFocusStep->view())
    {
        if (event->type() == QEvent::FocusIn)
        {
            m_bInComboBox = true;
        }
        else if (event->type() == QEvent::FocusOut)
        {
            m_bInComboBox = false;
        }
    }
    else if(obj == ui->label)
    {
        //When the mouse enters
        if (event->type() == QEvent::Enter & amp; & amp;
                ui->stackedWidget->currentIndex() == 0 & amp; & amp;
                !m_bShowSideflag)
        {
            if(m_slideOutAnimation->state() == QAbstractAnimation::Running)
                return true;

            //qDebug()<<"Enter";

            this->setMaximumWidth(SLIDE_MAX_WIDTH);
            m_slideOutAnimation->setStartValue(QRect(m_posX,m_posY,SLIDE_MIN_WIDTH,this->height()));
            m_slideOutAnimation->setEndValue(QRect(m_posX,m_posY,SLIDE_MAX_WIDTH,this->height()));
            m_slideOutAnimation->start();

            ui->stackedWidget->setCurrentIndex(1);

            m_bShowSideflag = true;
            return true;
        }

        return false;//Other events will be passed to the label object
    }
    else if(obj == ui->controlWidget)
    {
        //When the mouse leaves
        if (event->type() == QEvent::Leave & amp; & amp;
                ui->stackedWidget->currentIndex() == 1 & amp; & amp;
                m_bShowSideflag & amp; & amp; !m_bInComboBox)
        {
            if(m_slideInAnimation->state() == QAbstractAnimation::Running)
                return true;

            //qDebug()<<"Leave";
            m_slideInAnimation->setStartValue(QRect(m_posX,m_posY,SLIDE_MAX_WIDTH,this->height()));
            m_slideInAnimation->setEndValue(QRect(m_posX,m_posY,SLIDE_MIN_WIDTH,this->height()));
            m_slideInAnimation->start();

            m_bShowSideflag = false;
            return true;
        }

        return false;//Other events will be passed to the label object
    }


    // standard event processing
    return QWidget::eventFilter(obj, event);
}

void SlideAnimationWidget::slotSlideOutFinished()
{

}

void SlideAnimationWidget::slotSlideInFinished()
{
    this->setMaximumWidth(SLIDE_MIN_WIDTH);
    ui->stackedWidget->setCurrentIndex(0);
}

Usage: Create a new MainWidget and set the m_animationWidget parent object to this.

Created a void MainWidget::resizeEvent(QResizeEvent *event) event to adapt the height of m_animationWidget according to the size of MainWidget.

#include "MainWidget.h"
#include "ui_MainWidget.h"
#include "SlideAnimationWidget.h"
#include <QDebug>

#define POS_X 5
#define POS_Y 26

MainWidget::MainWidget(QWidget *parent):
    QWidget(parent),
    ui(new Ui::MainWidget)
{
    ui->setupUi(this);

    m_animationWidget = new SlideAnimationWidget(this);
    m_animationWidget->setPos(POS_X,POS_Y);
}

MainWidget::~MainWidget()
{
    delete ui;
}

void MainWidget::resizeEvent(QResizeEvent *event)
{
    m_animationWidget->setFixedHeight(event->size().height()-POS_Y*2);
}

void MainWidget::showEvent(QShowEvent *event)
{
    Q_UNUSED(event);

    if(m_isInit)
        return;


    setWindowState(Qt::WindowFullScreen);
    showMaximized();

    m_isInit = true;
}

4. Related references

Qt event filter (understand in seconds)_qt event filter-CSDN blog

Introduction to Qt event processing mechanism_qt gets the initiator of the event_Mr.codeee’s blog-CSDN blog

Qt custom floating window (with animation, similar to QQ Pinyin input method)_qt floating window setting suspension-CSDN Blog