Qt 实现侧边栏滑出菜单效果

1.效果图

2.实现原理

这里做了两个widget,一个是 展示底图widget,一个是 展示动画widget。

这两个widget需要重合。动画widget需要设置属性叠加到底图widget上面,设置如下属性:

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

动画widget背景需要做成透明,我在上面放了一个QFrame,然后设置style:

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

动画widget上面放了一个QStackedWidget。一个用于显示 > 的图像,另一个则显示菜单。

动画效果:QPropertyAnimation类提供动画支持,改变geometry属性。

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

最后安装事件过滤器:通过鼠标进入和离开事件,触发动画效果。

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

3.源码

#ifndef SLIDEANIMATIONWIDGET_H
#define SLIDEANIMATIONWIDGET_H#include <QWidget>
#include <QPropertyAnimation>
#include <QEvent>
#include <QRect>namespace Ui {
class SlideAnimationWidget;
}#define SLIDE_MIN_WIDTH 10      //侧边栏滑出最小的宽度
#define SLIDE_MAX_WIDTH 300     //侧边栏滑出最大的宽度class SlideAnimationWidget : public QWidget
{Q_OBJECTpublic: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;   //显示侧边栏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 <QAbstractItemView>
#include <QListView>
#include <QMouseEvent>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,&QPropertyAnimation::finished,this,&SlideAnimationWidget::slotSlideOutFinished);m_slideOutAnimation->setEasingCurve(QEasingCurve::OutSine);m_slideOutAnimation->setDuration(1300);m_slideInAnimation = new QPropertyAnimation(this,"geometry");connect(m_slideInAnimation,&QPropertyAnimation::finished,this,&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){//鼠标进入的时候if (event->type() == QEvent::Enter &&ui->stackedWidget->currentIndex() == 0 &&!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;//别的事件会传给label对象}else if(obj == ui->controlWidget){//鼠标离开的时候if (event->type() == QEvent::Leave &&ui->stackedWidget->currentIndex() == 1 &&m_bShowSideflag && !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;//别的事件会传给label对象}// standard event processingreturn QWidget::eventFilter(obj, event);
}void SlideAnimationWidget::slotSlideOutFinished()
{}void SlideAnimationWidget::slotSlideInFinished()
{this->setMaximumWidth(SLIDE_MIN_WIDTH);ui->stackedWidget->setCurrentIndex(0);
}

使用:新建一个MainWidget,将m_animationWidget父对象设置为this。

做了一个void MainWidget::resizeEvent(QResizeEvent *event)事件,根据MainWidget的尺寸,自适应m_animationWidget的高度。

#include "MainWidget.h"
#include "ui_MainWidget.h"
#include "SlideAnimationWidget.h"
#include <QDebug>#define POS_X 5
#define POS_Y 26MainWidget::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.相关参考

Qt 事件过滤器(秒懂)_qt事件过滤器-CSDN博客

Qt 事件处理机制简介_qt获取事件的发起者_Mr.codeee的博客-CSDN博客 

Qt 自定义悬浮窗(带动画,类似QQ拼音输入法)_qt 浮动窗口设置悬浮-CSDN博客 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/151978.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【优选算法系列】第二节.双指针(202. 快乐数和11. 盛最多水的容器)

作者简介&#xff1a;大家好&#xff0c;我是未央&#xff1b; 博客首页&#xff1a;未央.303 系列专栏&#xff1a;优选算法系列 每日一句&#xff1a;人的一生&#xff0c;可以有所作为的时机只有一次&#xff0c;那就是现在&#xff01;&#xff01;&#xff01;&#xff01…

基于java+springboot的人事招聘信息网站

运行环境 开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven 项目介绍 开发过程…

锐捷EG易网关 phpinfo.view.php 信息泄露

致未经身份验证获取敏感信息 访问漏洞url&#xff1a; /tool/view/phpinfo.view.php漏洞证明&#xff1a; 文笔生疏&#xff0c;措辞浅薄&#xff0c;望各位大佬不吝赐教&#xff0c;万分感谢。 免责声明&#xff1a;由于传播或利用此文所提供的信息、技术或方法而造成的任何…

【强化学习】10 —— DQN算法

文章目录 深度强化学习价值和策略近似RL与DL结合产生的问题深度强化学习的分类 Q-learning回顾深度Q网络&#xff08;DQN&#xff09;经验回放优先经验回放 目标网络算法流程 代码实践CartPole环境代码结果 参考 深度强化学习 价值和策略近似 我们可以利用深度神经网络建立这些…

设计模式(19)命令模式

一、介绍&#xff1a; 1、定义&#xff1a;命令模式&#xff08;Command Pattern&#xff09;是一种行为设计模式&#xff0c;它将请求封装为一个对象&#xff0c;从而使你可以使用不同的请求对客户端进行参数化。命令模式还支持请求的排队、记录日志、撤销操作等功能。 2、组…

Python深度学习实战-基于tensorflow原生代码搭建BP神经网络实现分类任务(附源码和实现效果)

实现功能 前面两篇文章分别介绍了两种搭建神经网络模型的方法&#xff0c;一种是基于tensorflow的keras框架&#xff0c;另一种是继承父类自定义class类&#xff0c;本篇文章将编写原生代码搭建BP神经网络。 实现代码 import tensorflow as tf from sklearn.datasets import…

哈希算法:如何防止数据库中的用户信息被脱库?

文章来源于极客时间前google工程师−王争专栏。 2011年CSDN“脱库”事件&#xff0c;CSDN网站被黑客攻击&#xff0c;超过600万用户的注册邮箱和密码明文被泄露&#xff0c;很多网友对CSDN明文保存用户密码行为产生了不满。如果你是CSDN的一名工程师&#xff0c;你会如何存储用…

debian 10 安装apache2 zabbix

nginx 可以略过&#xff0c;改为apache2 apt updateapt-get install nginx -ynginx -v nginx version: nginx/1.14.2mysql 安装参考linux debian10 安装mysql5.7_debian apt install mysql5.7-CSDN博客 Install and configure Zabbix for your platform a. Install Zabbix re…

SpringCore完整学习教程5,入门级别

本章从第6章开始 6. JSON Spring Boot提供了三个JSON映射库的集成: Gson Jackson JSON-B Jackson是首选的和默认的库。 6.1. Jackson 为Jackson提供了自动配置&#xff0c;Jackson是spring-boot-starter-json的一部分。当Jackson在类路径上时&#xff0c;将自动配置Obj…

uniapp 中添加 vconsole

uniapp 中添加 vconsole 一、安装 vconsole npm i vconsole二、使用 vconsole 在项目的 main.js 文件中添加如下内容 // #ifdef H5 // 提交前需要注释 本地调试使用 import * as vconsole from "vconsole"; new vconsole() // 使用 vconsole // #endif三、成功

[17]JAVAEE-HTTP协议

目录 一、什么是HTTP协议 什么时候会用到HTTP协议&#xff1f; HTTP协议的工作流程 二、HTTP的报文格式 抓包 HTTP请求报文格式 1.首行 2.header 常见键值对&#xff1a; 3.空行 4.正文&#xff08;body&#xff09;&#xff08;有的时候可以没有&#xff09; HTTP…

数据分析和互联网医院小程序:提高医疗决策的准确性和效率

互联网医院小程序已经在医疗领域取得了显著的进展&#xff0c;为患者和医疗从业者提供了更便捷和高效的医疗服务。随着数据分析技术的快速发展&#xff0c;互联网医院小程序能够利用大数据来提高医疗决策的准确性和效率。本文将探讨数据分析在互联网医院小程序中的应用&#xf…