Qt之悬浮球菜单

news/2024/11/24 20:36:55/

一、概述

最近想做一个炫酷的悬浮式菜单,考虑到菜单展开和美观,所以考虑学习下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 之股票组件 - 自选股 -- 列表可以拖拽、右键常用菜单

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

相关文章

【android】悬浮球

效果图 原理 获取windowManager 设定WindowManager.LayoutParams使窗口悬浮 主要涉及的值如下&#xff0c;其中 params.type WindowManager.LayoutParams.TYPE_APPLICATION; 设置悬浮窗在应用内&#xff0c;在弹出dialog会悬浮在dialog下方&#xff0c;如果将这个值设置为…

多功能悬浮球下载_悬浮球app下载

应用介绍&#xff1a; 用过flyme系统没&#xff0c;里面的悬浮球应用非常好用。以至于换了其他rom之后不太习惯&#xff0c;因此自主研发了一个高仿的版本&#xff0c;方便广大用户也一起来体验体验。该应用可以轻松实现返回键、下拉通知栏、锁屏、打开多任务、home键等实用功能…

苹果悬浮球_iPhone手机的悬浮球功能强大!你却不会用?太浪费了

阅读本文前&#xff0c;请您先点击上面的“蓝色字体”&#xff0c;再点击“关注”&#xff0c;这样您就可以继续免费收到文章了。每天都会有分享&#xff0c;都是免费订阅&#xff0c;请您放心关注。注图文来源网络&#xff0c;侵删 …

游戏联运系统SDK iOS悬浮球的实现方法

本文将为大家实现在iOS中悬浮球功能&#xff0c;希望大家阅读完这篇文章后对相关知识有一定的了解。 首先我们创建一个View&#xff0c;在View内新建一个Button作为悬浮按钮&#xff0c;当然你也可以直接继承自UIButton。 这里添加了屏幕旋转监听&#xff0c;以便于做横竖屏适…

过山车大亨3《RollerCoaster Tycoon Complete Edition》 Mac版

关于这款游戏 你的游乐园&#xff0c;一切由你作主 不论你想打造成什么样貌&#xff0c;《RollerCoaster Tycoon 3》都提供充分的工具和自由&#xff0c;让你能尽情建造出梦想中的游乐园。 像企业大亨般管理游乐园&#xff0c;一路攀上颠峰 控管游乐园的财务、商店、服务和…

超级悬浮球,Plus版

前言 说到悬浮球大家可能瞬间就会想到X60、X毒霸、X管家…… 虽说这几家整体上都有些流氓&#xff0c;但悬浮球这个小功能还是非常好用的 今天给大家带来一款开源的超级悬浮球&#xff0c;拥有上述三大应用及火绒的悬浮球样式 还集成了网速显示、壁纸切换、文本翻译、文字识…

过山车大亨1android,过山车大亨最新版

过山车大亨最新版是一款非常好玩的趣味模拟经营游戏。在这款游戏中玩家将要去建造一家属于自己的游乐场来吸引更多的顾客&#xff0c;令人兴奋的平面玩乐景点&#xff0c;积极的游客&#xff0c;用户自定义的内容&#xff0c;强大的社交功能以及更多 – 尽在这款大型娱乐游戏之…

过山车大亨3拉拉地通关要诀【亲测可用】

整个过山车大亨3就只有拉拉地可能卡关&#xff0c;即使使用秘籍也难以通关。 接下来就是攻略要诀&#xff1a; 第一步&#xff1a;基本没问题 记得开局卖掉观光塔&#xff0c;否则会卡很多人。 第二步&#xff1a;vip经过烟花的时候手动点开烟花编辑器&#xff0c;然后手动播…