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.rhkb.cn/news/175144.html

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

相关文章

爱写bug的小邓程序员个人博客

博客网址: http://www.006969.xyz 欢迎来到我的个人博客&#xff0c;这里主要分享我对于前后端相关技术的学习笔记、项目实战经验以及一些技术感悟。 在我的博客中&#xff0c;你将看到以下主要内容&#xff1a; 技术文章 我将会分享我在学习前后端技术过程中的一些感悟&am…

软件工程:小组开发过程技术(VS VSS UNIX C++)

&#xff08;注&#xff1a;这个东西是2007年写的&#xff0c;算是个缅怀&#xff0c;或是个吐槽。所有注都是本次发布新加的。&#xff09; 简介 本文讲述完全没有软件工程经验的软件小组如何借助VS VSS等工具为UNIX开发C程序&#xff0c;实现在小组规模的初级开发过程。这不…

回文链表Java

我们可以采用双指针的办法进行,如下图: 如果链表长度为偶数,则直接从第二个指针的位置开始对链表进行反转;如果是奇数,则从第二指针的下一位进行链表反转 代码实现: public static void main(String[] args) {ListNode next4 new ListNode(1, null);ListNode next3 new Lis…

AssertionError: Torch not compiled with CUDA enabled

Pytorch和CUDA版本不兼容&#xff0c;运行python后&#xff08;终端输入python回车&#xff09;用以下代码测试 import torch print(torch.__version__) print(torch.cuda.is_available())返回False则说明目前的pytorch版本无法使用显卡&#xff0c;如下图所示 接着重装合适版…

实战 | SQL注入

一、资产搜集 我们都知道sql注入的传参有些是明文的&#xff0c;有些是经过编码或者加密的&#xff0c;所以我们搜索的时候不要仅限于inurl:.php?id1&#xff0c;可以额外的尝试搜搜1的base64编码值MQ&#xff0c;即可以搜索inurl:.php?idMQ&#xff0c;或者搜索1的md5加密值…

css实现圆形进度条

能用现成组件就用&#xff0c;实现不行再自己写&#xff0c;因为牵扯到上传文件&#xff0c;进度实时出不来&#xff0c;所以只能使用dom元素操作&#xff1b; 1.实现 效果&#xff1a; 上图是100%&#xff0c;如果需要根据百分比显示&#xff0c;我们需要看下代码里面left和…

Ubuntu20.04下安装MySQL8环境

Ubuntu20.04下安装MySQL8环境 1.下载MySQL客户端和服务器2.配置MySQL3.测试MySQL4.设置MySQL服务开机自启动5.修改root密码MySQL数据库基本使用启动MySQL数据库服务重启MySQL数据库服务停止MySQL数据库服务查看MySQL运行状态设置MySQL服务开机自启动停止MySQL服务开机自启动MyS…

读图数据库实战笔记04_路径与图变异

1. Groovy 1.1. Java编程语言的一个超集 1.2. Gremlin Console的一个特性是能和Groovy配合使用 1.2.1. Gremlin Console会自动地迭代结果 1.3. 从技术上说&#xff0c;Gremlin Console就是Groovy交互式解释器&#xff08;read-eval-print loop&#xff0c;REPL&#xff09;…

【广州华锐互动】城市水处理VR仿真实训平台

随着科技的不断发展&#xff0c;虚拟现实&#xff08;VR&#xff09;技术已经逐渐渗透到各个领域&#xff0c;为我们带来了前所未有的沉浸式体验。在教育领域&#xff0c;VR技术的应用也日益广泛&#xff0c;为传统的教学模式带来了革命性的变革。本文将以城市水处理VR仿真实训…

[架构之路-246/创业之路-77]:目标系统 - 纵向分层 - 企业信息化的呈现形态:常见企业信息化软件系统 - 客户关系管理系统CRM

目录 前言&#xff1a; 一、企业信息化的结果&#xff1a;常见企业信息化软件 1.1 客户关系管理系统CRM 1.1.1 什么是客户关系管理系统 1.1.2 CRM总体架构 1.1.3 什么类型的企业需要CRM 1.1.4 创业公司在什么阶段需要CRM 1.1.5 研发型创业公司什么时候需要CRM 1.1.6 C…

3D RPG Course | Core 学习日记一:初识URP

前言 最近开始学习Unity中文课堂M_Studio&#xff08;麦大&#xff09;的3D RPG Course&#xff0c;学习一下3D RPG游戏核心功能的实现&#xff0c;第一课我们学习到的是地图场景的编辑&#xff0c;其中涉及到了URP渲染。 我们首先进入Unity资源商店把地图素材和人物素材导入好…

stable diffusion简介和原理

Stable Diffusion中文的意思是稳定扩散&#xff0c;本质上是基于AI的图像扩散生成模型。 Stable Diffusion是一个引人注目的深度学习模型&#xff0c;它使用潜在扩散过程来生成图像&#xff0c;允许模型在生成图像时考虑到文本的描述。这个模型的出现引起了广泛的关注和讨论&am…

leetcode-二叉树

B树和B树的区别 B树&#xff0c;也即balance树&#xff0c;是一棵多路自平衡的搜索树。它类似普通的平衡二叉树&#xff0c;不同的一点是B树允许每个节点有更多的子节点。 B树内节点不存储数据&#xff0c;所有关键字都存储在叶子节点上。B树&#xff1a; B树&#xff1a; 二叉…

mac安装并使用wireshark

mac安装并使用wireshark 1 介绍 我们在日常开发过程中&#xff0c;遇到了棘手的问题时&#xff0c;免不了查看具体网络请求情况&#xff0c;这个时候就需要用到抓包工具。比较著名的抓包工具就属&#xff1a;wireshark、fildder。我这里主要介绍wireshark。 2 安装 以mac安装为…

前端开发必备技能!用简单CSS代码绘制三角形,提升用户体验

&#x1f3ac; 江城开朗的豌豆&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 &#x1f4dd; 个人网站 :《 江城开朗的豌豆&#x1fadb; 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! 目录 ⭐ 专栏简介 &#x1f4d8; 文章引言 一、前…

Docker 容器服务的注册、发现及Docker安全

目录 Docker容器服务的注册和发现 1、什么是服务注册与发现&#xff1f; 2、什么是consul consul的部署 1、环境准备 2、部署consul服务器 1&#xff09;建立 Consul 服务 2&#xff09;设置代理&#xff0c;在后台启动 consul 服务端 3&#xff09;查看集群信息 4&a…

图像视觉特效处理工具:Boris FX Optics 2024.0.1

BorisFX光效插件Optics首发2024版&#xff1a;3大新功能详解 2023年9月15日&#xff0c;全球领先的视觉后期软件开发公司BorisFX推出了旗下知名软件Boris FX Optics的全新2024版本&#xff0c;这款备受后期处理爱好者喜爱的Photoshop插件和独立程序再次升级&#xff0c;为您的…

Docker Consul概述及构建

Docker Consul概述及构建 一、Consul概述1.1、什么是Consul1.2、consul 容器服务更新与发现1.3、服务注册与发现的含义1.4、consul-template概述1.5、registrator的作用 二、consul部署2.1、环境配置2.2、在主节点上部署consul2.3 、配置容器服务自动加入nginx集群2.3.1、安装G…

Redis测试新手入门教程

在测试过程中&#xff0c;我们或多或少会接触到Redis&#xff0c;今天就把在小破站看到的三丰老师课程&#xff0c;把笔记整理了下&#xff0c;用来备忘&#xff0c;也希望能给大家带来亿点点收获。 主要分为两个部分&#xff1a; 一、缓存技术在后端架构中是如何应用的&#…

K8s集群

统一时间&#xff1a;ntpdate(都做) ntpdate -b ntp1.aliyun.com */1 * * * * /usr/sbin/ntpdate -b ntp1.aliyun.com systemctl status docker vi /etc/docker/daemon.json systemctl restart docker m: vim kubernetes.sh cat >> /etc/yum.repos.d/kubernetes.repo…