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