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.mzph.cn/news/120720.shtml

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

相关文章

Java提升技术,进阶为高级开发和架构师的路线

原文网址&#xff1a;Java提升技术&#xff0c;进阶为高级开发和架构师的路线-CSDN博客 简介 Java怎样提升技术&#xff1f;怎样进阶为高级开发和架构师&#xff1f;本文介绍靠谱的成长路线。 首先点明&#xff0c;只写业务代码是无法成长技术的。提升技术的两个方法是&…

【Docker】Docker-Compose内置DNS负载均衡失效问题

Docker Compose实现负载均衡 还是对前面的例子docker-compose.yml稍微修改&#xff1a; version: "3.8"services:flask-demo:build:context: .dockerfile: Dockerfileimage: flask-demo:latestenvironment:- REDIS_HOSTredis-server- REDIS_PASS${REDIS_PASS}healt…

软考-入侵检测技术原理与应用

本文为作者学习文章&#xff0c;按作者习惯写成&#xff0c;如有错误或需要追加内容请留言&#xff08;不喜勿喷&#xff09; 本文为追加文章&#xff0c;后期慢慢追加 by 2023年10月 入侵检测技术概念 入侵检测技术是指一种计算机安全技术&#xff0c;旨在监测计算机系统、…

回溯法:雀魂启动!

题目链接&#xff1a;雀魂启动&#xff01;_牛客题霸_牛客网 题解&#xff1a; 回溯法 1、用哈希思想构建映射表&#xff0c;标记已有的卡的种类和个数 2、遍历卡池&#xff0c;先从卡池中抽一张卡&#xff0c;因为只能抽一张卡&#xff0c;所以一种卡只判断一次 3、抽到卡后找…

行为型模式-状态模式

在状态模式中&#xff0c;类的行为是基于它的状态改变的。这种类型的设计模式属于行为型模式。 在状态模式中&#xff0c;我们创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象。 意图&#xff1a;允许对象在内部状态发生改变时改变它的行为&#xff0…

jmeter报Java.NET.BindException: Address already in use: connect

1、windows10和window11上&#xff1a; 修改注册表的内容&#xff1a; HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters&#xff1a; 新建dword&#xff08;值&#xff09;的类型&#xff1a; MaxUserPort 65334 TcpTimedWaitDelay 30window

Android Glide限定onlyRetrieveFromCache取内存缓存submit超时阻塞方式,Kotlin

Android Glide限定onlyRetrieveFromCache取内存缓存submit超时阻塞方式,Kotlin import android.os.Bundle import android.util.Log import android.widget.ImageView import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.lifecycleScope import com.b…

Chimera:混合的 RLWE-FHE 方案

参考文献&#xff1a; [HS14] S. Halevi and V. Shoup. Algorithms in HElib. In Advances in Cryptology–CRYPTO 2014, pages 554–571. Springer, 2014.[HS15] S. Halevi and V. Shoup. Bootstrapping for HElib. In Advances in Cryptology–EUROCRYPT 2015, pages 641–6…

K8s概念汇总-笔记

目录 1.Master 1.1在Master上运⾏着以下关键进程 2.什么是Node? 1.2在每个Node上都运⾏着以下关键进程 3.什么是 Pod ? 4. 什么是Label &#xff1f; 5.Replication Controller 6.Deployment 6.1Deployment的典型场景&#xff1a; 7.Horizontal Pod Autoscaler TODO…

【MATLAB源码-第57期】基于matlab的IS95前向链路仿真,输出误码率曲线。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 IS-95&#xff0c;也被称为cdmaOne&#xff0c;是第一代的CDMA&#xff08;Code Division Multiple Access&#xff0c;码分多址&#xff09;数字蜂窝通信标准。IS-95的全称是Interim Standard-95&#xff0c;最初由Qualcomm…

春运压力如何破?V2X技术来解题

近日&#xff0c;国务院发布了2024春节放假方案。春节作为每年中国交通运输系统最繁忙的时期&#xff0c;车流的快速增长带来了道路运载压力和事故风险率。如果想拥有一个不堵车又平安的春节&#xff1f;那就不得不提V2X 技术&#xff0c;以及它在提升交通安全与交通效率、助力…

自定义一个注解,用它标记的执行并于给定值做对比(即简单的junit)

目录 程序设计 程序分析 系列文章 程序设计 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME) @Target(ElementT…

TVRNet网络PyTorch实现

文章目录 文章地址网络各层结构代码实现 文章地址 An End-to-End Traffic Visibility Regression Algorithm文章通过训练搜集得到的真实道路图像数据集&#xff08;Actual Road dense image Dataset, ARD&#xff09;&#xff0c;通过专业的能见度计和多人标注&#xff0c;获得…

10个Golang 数据库最佳实践

如果您使用 Golang 开发数据库支持的应用程序&#xff0c;则应遵循一些最佳实践&#xff0c;以确保您的代码干净、高效且可靠。 在本文中&#xff0c;我们将探讨在 Golang 中使用数据库的 10 种最佳实践。我们将涵盖连接数据库、CRUD 操作以及使用准备好的语句等主题。在本文结…

图像语义分割 pytorch复现DeepLab v1图像分割网络以及网络详解(骨干网络基于VGG16)

图像语义分割 pytorch复现DeepLab v1图像分割网络以及网络详解&#xff08;骨干网络基于VGG16&#xff09; 背景介绍2、 网络结构详解2.1 LarFOV效果分析 2.2 DeepLab v1-LargeFOV 模型架构2.3 MSc&#xff08;Multi-Scale&#xff0c;多尺度(预测)&#xff09;2.3 以VGG16为特…

1-多媒体通信概述

文章目录 媒体和多媒体媒体多媒体VarityIntergrationInteraction 多媒体通信(MMC)业务类型 MMC主要问题和关键技术主要问题关键技术 MMC发展动向重要事件趋势 标准化组织 媒体和多媒体 媒体 承载信息的载体. 感知媒体, 表示媒体, 显示媒体, 存储媒体, 传输媒体. 多媒体 Var…

电脑定时关机

电脑定时关机 1.右键 管理 2. 3. 4. 5. shutdown.exe/s /f /t 06.点击完成就好了 7.这里面可以 看到定时任务和启动 右键有运行 结束 禁用

世微 宽电压降压 DC-DC 电源管理芯片 以太网平衡车工业控制电源驱动12V6A AP8854

1&#xff0c;产品描述 AP8854 一款宽电压范围降压型 DC-D 电源管理芯片&#xff0c;内部集成使能开关控制、基 准电源、误差放大器、过热保护、限流保 护、短路保护等功能&#xff0c;非常适合宽电压输 入降压使用。 AP8854 带使能控制&#xff0c;可以大大节省外 围器件&…

广州华锐互动:VR虚拟现实物理学习平台,开启数字化教学新格局

随着虚拟现实(VR)技术的不断发展&#xff0c;越来越多的领域开始应用这一技术。广州华锐互动开发的VR虚拟现实物理学习平台就得到了广泛应用&#xff0c;平台涉及力学、光学、热学等初中物理知识&#xff0c;还包含了物理名人、实验器具、物理现象的还原和学习&#xff0c;相比…

CSS色域、色彩空间、CSS Color 4新标准 | 京东云技术团队

引言 近期&#xff0c;三大主流浏览器引擎均发布最新版本&#xff0c;支持W3C的CSS Color 4标准&#xff0c;包含新的取色方法color()和相应语法&#xff0c;可展示更多的色域及色彩空间&#xff0c;这意味着web端能展示更丰富更高清的色彩。虽然目前只有最新版本的现代浏览器…