Qt 之悬浮球菜单

news/2024/11/24 18:42:21/

朝十晚八

Qt 之悬浮球菜单

目录

  • 一、概述
  • 二、效果展示
  • 三、实现代码
    • 1、菜单项
    • 2、悬浮球
    • 3、关键点
  • 四、相关文章

原文链接:Qt 之悬浮球菜单

一、概述

最近想做一个炫酷的悬浮式菜单,考虑到菜单展开和美观,所以考虑学习下 Qt 的动画系统和状态机内容,打开 QtCreator 的示例教程浏览了下,大致发现教程中 2D Painting 程序和 Animated Tiles 程序有所帮助,如下图所示,这两个 demo 讲述了怎么做一个展开动画,感兴趣的同学也可以直接参考

有了这两个 demo 之后,就可以开始动工写咱们自己的程序。

二、效果展示

如下两幅图就是作者失效的两个悬浮菜单效果图,展示图 1 代码已上传至 CSDN,不需要积分即可下载,效果图 2 代码暂时不开源,有需要的朋友可以进一步咨询

基础圆形菜单功能,代码已上传 CSDN - Qt 失效的 PC 端环形菜单、悬浮球菜单、展开动画

高级悬浮球菜单、支持二级菜单打开

三、实现代码

实现文件比较简单,只有头文件和实现文件,这里先主要放出头文件,然后讲解实现思路,具体实现细节可以通过下载源码进行具体了解

1、菜单项

PopRingItem 为菜单展开项、可以通过绑定外部 QAction 实现与普通菜单相同功能

class PopRingItem : public QLabel
{Q_OBJECTpublic:PopRingItem(QWidget *parent = 0);~PopRingItem();void SetRadius(int radius);int GetRadius() const;void BindAction(QAction * action);signals:void MouseEvent(bool);protected:virtual void enterEvent(QEvent * event) override;virtual void leaveEvent(QEvent * event) override;virtual void paintEvent(QPaintEvent * event) override;protected:int m_iRadius = 50;QAction * m_actAction = nullptr;
};

2、悬浮球

悬浮球为菜单入口,继承自菜单项,与菜单项有相似功能

class QVariantAnimation;
class QPropertyAnimation;
class PopRingMenu : public PopRingItem
{Q_OBJECTpublic:PopRingMenu(QWidget *parent = 0);~PopRingMenu();signals:void DoubleClicked();public:void SetActions(const QVector<QAction *> & acts);void SetIcons(const QVector<QString> & icons);void SetAnimationEnabled(bool enabled);bool IsAnimationEnabled() const;void SetSlowlyFade(bool enabled);bool IsSlowlyFade() const;void SetDistanced(int distance);int GetDistanced() const;void SetStartAngle(int angle);int GetStartAngle() const;void SetStepAngle(int angle);int GetStepAngle() const;void SetNormalMenuSize(int size);int GetNormalMenuSize() const;void SetNormalItemSize(int size);int GetNormalItemSize() const;protected:virtual void enterEvent(QEvent * event) override;virtual void leaveEvent(QEvent * event) override;virtual void mouseDoubleClickEvent(QMouseEvent * event) override;virtual void timerEvent(QTimerEvent * event) override;virtual bool event(QEvent * event) override;private slots:void OnMouseEvent(bool);private:void UpdateActions(int msecond);void ExpandMenu();void CollapseMenu();void SlowlyFade();void QuicklyLighter();bool IsUnderMouse() const;void TryCollapseMenu();void KillHideTimer();private:int m_iDistance = 70;int m_iStartAngle = 0;int m_iStepAngle = 60;int m_iMenuSize = 70;int m_iItemSize = 60;int m_iTimerID = -1;QPropertyAnimation * m_pOpacityAnimation = nullptr;QVariantAnimation * m_pItemAnimation = nullptr;QVector<PopRingItem *> m_items;
};

3、关键点

初始化动画对象,指定动画时长和动画起始、终止值

动画具体实现函数未 UpdateAction,根据当前动画进度值在动画起始值和终止值所占比例,进行计算当前动画时刻菜单项的位置和大小

m_pItemAnimation = new QVariantAnimation(this);m_pItemAnimation->setEasingCurve(QEasingCurve::InCubic);
m_pItemAnimation->setStartValue(ShowMenuStartValue);
m_pItemAnimation->setEndValue(ShowMenuEndValue);
m_pItemAnimation->setDuration(ShowMenuDuration);connect(m_pItemAnimation, &QVariantAnimation::valueChanged, this, [this](const QVariant & v){UpdateActions(v.toInt());
});

鼠标进入悬浮球时,执行展开动画

void PopRingMenu::ExpandMenu()
{if (m_pItemAnimation){if (m_pItemAnimation->state() != QAbstractAnimation::Running&& m_pItemAnimation->currentValue().toInt() != ShowMenuEndValue){m_pItemAnimation->setDirection(QVariantAnimation::Forward);m_pItemAnimation->start();}}else{UpdateActions(ShowMenuEndValue);}KillHideTimer();QuicklyLighter();
}
  1. 鼠标离开悬浮球时,执行收起动画,与展开动画相反方向
  2. 收起动画时有一个细节点,那就是鼠标 hover 在菜单项上时,也不能收起
void PopRingMenu::CollapseMenu()
{if (false == IsUnderMouse()){if (m_pItemAnimation){m_pItemAnimation->setDirection(QVariantAnimation::Backward);m_pItemAnimation->start();}else{UpdateActions(ShowMenuStartValue);}KillHideTimer();SlowlyFade();}
}

展开和收起动画实现细节,根据动画指定帧数,按比例进行缩放和移动菜单项

void PopRingMenu::UpdateActions(int msecond)
{int curDistance = msecond * m_iDistance / ShowMenuEndValue;for (int i = 0; i < m_items.size(); ++i){PopRingItem * item = m_items.at(i);double radians = qDegreesToRadians(m_iStepAngle * i * 1.0 + m_iStartAngle);int offx = curDistance * qCos(radians);int offy = curDistance * qSin(radians);item->move(pos() + QPoint(offx, offy));int curSize = msecond * m_iItemSize / ShowMenuEndValue;item->SetRadius(curSize);item->setVisible(ShowMenuStartValue != msecond);};::SetWindowPos(HWND(winId()), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
}

悬浮球指定时间未激活时,淡出,减少对用户视觉冲击

void PopRingMenu::SetSlowlyFade(bool enabled)
{if (enabled){if (nullptr == m_pOpacityAnimation){m_pOpacityAnimation = new QPropertyAnimation(this, "opacity");m_pOpacityAnimation->setEasingCurve(QEasingCurve::OutCubic);m_pOpacityAnimation->setStartValue(SlowlyStartValue);m_pOpacityAnimation->setEndValue(SlowLyEndValue);m_pOpacityAnimation->setDuration(SlowlyFadeDuration);}}else{if (m_pOpacityAnimation){delete m_pOpacityAnimation;m_pOpacityAnimation = nullptr;}}
}

四、相关文章

  1. qt 之菜单项定制
  2. Qt 之 QAbstractItemView 右键菜单
  3. Qt 弹出式菜单阴影
  4. Qt 之自定义 QLineEdit 右键菜单
  5. Qt 之股票组件 - 自选股 -- 列表可以拖拽、右键常用菜单

值得一看的优秀文章:

  1. 财联社 - 产品展示
  2. 广联达 - 产品展示
  3. Qt 定制控件列表
  4. 牛逼哄哄的 Qt 库

如果您觉得文章不错,不妨给个打赏,写作不易,感谢各位的支持。您的支持是我最大的动力,谢谢!!!
 


很重要 -- 转载声明

  1. 本站文章无特别说明,皆为原创,版权所有,转载时请用链接的方式,给出原文出处。同时写上原作者:朝十晚八 or Twowords

  2. 如要转载,请原文转载,如在转载时修改本文,请事先告知,谢绝在转载时通过修改本文达到有利于转载者的目的。


奋斗中的无名小卒。。。

分类: qt 项目案例 , qt 经典文章 , qt 学习案例 , 定制控件


http://www.ppmy.cn/news/877749.html

相关文章

android 悬浮球代码,Android 悬浮球

闲来无事,搞一波悬浮球,此球: 无需权限 主要代码只有一个类,简简单单放进自己的工程 悬浮球可以用来干啥: 打开侧滑界面 打开一排小按钮 打开客服等等 功能: 显示红点(接收到信息等场景) 关闭红点(关闭消息提示) 自动贴边 显示球 隐藏球 自定义点击事件及回调 可以说你能…

悬浮球多功能_一个悬浮球,怎么可以这么贴心~

原标题&#xff1a;一个悬浮球&#xff0c;怎么可以这么贴心~ 一个悬浮球 满足你N个愿望 ※ 专题&#xff5c;图文&#xff5c;悬浮球上手指南 这个小蛋蛋是不少小朋友喜爱的零食&#xff0c;因为它能满足小朋友好几个愿望&#xff0c;能吃又能玩的零食哪个小朋友会不喜欢&…

android 悬浮球 (所有界面可用) 开发

创建 service 后台启动 public class FBService extends Service {private static final String TAG "FBService";public static final int TYPE_ADD 0;public static final int TYPE_DEL 1;private FloatBallManager mFBManager;Overridepublic void onCreate()…

自定义View:悬浮球与加速球

先来看一张动态图 昨天跟着视频学了如何自定义View并做成仿360悬浮球与加速球的样式 可以看出来&#xff0c;做成的效果有&#xff1a; 点击按钮后退出Activity&#xff0c;呈现一个圆形的悬浮球&#xff0c;可以随意拖动并会自动依靠到屏幕一侧&#xff0c;且拖动时会变成一…

移动端悬浮球示例

实现思路效果图代码 注意:此例子只适用于移动端; 实现思路 1.拖动元素 2.当拖放位置在左屏时,停靠屏幕在左边,右屏时,停靠在右边 3.当元素顶部(底部)在屏幕外时,停靠在屏幕顶部(底部); 效果图 代码 <!DOCTYPE html> <html lang"en"> <head>…

【app】1.1 悬浮球_绘制

前言 测试时需要抓取QXDM log&#xff0c;但是需要连接到电脑上&#xff0c;通过adb口下diag命令&#xff0c;打算编写apk&#xff0c;运行时显示一个悬浮球&#xff0c;可以直接通过apk的service去下diag命令。 设置悬浮球是因为录制音频软件时&#xff0c;如果退出当前录音…

android悬浮球代码,Android 仿360悬浮球与加速球

先来看一张动态图 昨天跟着视频学了如何自定义View并做成仿360悬浮球与加速球的样式 可以看出来&#xff0c;做成的效果有&#xff1a; 点击按钮后退出Activity&#xff0c;呈现一个圆形的悬浮球&#xff0c;可以随意拖动并会自动依靠到屏幕一侧&#xff0c;且拖动时会变成一张…

《深度学习推荐系统》笔记

目录 一、推荐系统是什么1.作用和意义2.推荐系统的架构2.1 逻辑架构2.2 技术架构 二、传统的推荐系统方法1. 协同过滤算法1.1 userCF&&ItemCF1.3 矩阵分解算法 2. 逻辑回归算法3. 因子分解机3.1 POLY2模型3.2 FM模型3.3 FFM模型3.4 小结 4. 组合模型4.1 GBDTLR组合模型…