Qt之悬浮球菜单
一、概述
最近想做一个炫酷的悬浮式菜单,考虑到菜单展开和美观,所以考虑学习下Qt的动画系统和状态机内容,打开QtCreator的示例教程浏览了下,大致发现教程中 2D Painting 程序和Animated Tiles 程序有所帮助,如下图所示,这两个demo讲述了怎么做一个展开动画,感兴趣的同学也可以直接参考
有了这两个demo之后,就可以开始动工写咱们自己的程序。 二、效果展示
如下两幅图就是作者失效的两个悬浮菜单效果图,展示图1代码已上传至CSDN,不需要积分即可下载,效果图2代码暂时不开源,有需要的朋友可以进一步咨询
基础圆形菜单功能,代码已上传CSDN - Qt 失效的 PC 端环形菜单、悬浮球菜单、展开动画
高级悬浮球菜单、支持二级菜单打开
三、实现代码
实现文件比较简单,只有头文件和实现文件,这里先主要放出头文件,然后讲解实现思路,具体实现细节可以通过下载源码进行具体了解 1、菜单项
PopRingItem为菜单展开项、可以通过绑定外部QAction实现与普通菜单相同功能 class PopRingItem : public QLabel { Q_OBJECT public: 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_OBJECT public: PopRingMenu(QWidget *parent = 0); ~PopRingMenu(); signals: void DoubleClicked(); public: void SetActions(const QVector & acts); void SetIcons(const QVector & 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 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(); }
鼠标离开悬浮球时,执行收起动画,与展开动画相反方向 收起动画时有一个细节点,那就是鼠标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; } } } 四、相关文章qt 之菜单项定制 Qt 之 QAbstractItemView 右键菜单 Qt 弹出式 菜单 阴影 Qt 之自定义 QLineEdit 右键 菜单 Qt 之股票组件 - 自选股 -- 列表可以拖拽、右键常用 菜单
新一代国产16nm处理器问世,性能到底如何?能满足日常使用需要吗新一代国产16nm处理器问世,可以说是进步飞快,那么其性能到底如何,能满足日常使用吗?今天我就跟大家聊聊这个话题。近日,兆芯发布了两款16nm工艺处理器,分别是面向消费级市场的开先
世界最大火箭SLS终于飞了,日本月面着陆器搭便车却出了故障当今世界上最大的火箭,美国宇航局太空发射系统(SLS),火箭中的鸽王终于飞了。据中新网11月16日报道,美国当地时间16日凌晨,美国宇航局为了阿尔忒弥斯重返月球计划专门打造的超重型
苹果虚拟现实设备或于明年面世,意味着什么?苹果(AAPL。US)公司布局虚拟现实行业的产品,可能离我们越来越近了。据报道,苹果公司的混合现实(MR)头显或于2023年面世,而且,其新搭配的RealityOS(可能的命名,目
老年人,咳咳咳的原因进入冬季,气温明显下降,很多老人会出现咳嗽咳痰甚至会有喘息,要警惕。今天来说说冬季易发作的慢性支气管炎,如果你是吸烟爱好者,那就要注意啦。要知道烟草中的焦油尼古丁等化学物质会损伤气
药性歌括四百味明代通俗易懂的常用中药介绍药性歌括四百味为明代医家龚廷贤所著,它以四言韵的形式,介绍了400余味常用中药的性味功能主治。其内容简明扼要,通俗易懂,实用性强,押韵和谐,读之朗朗上口,便于诵读记忆,是了解中药知
2022接近完美的4款手机,除了配置全面以外,关键是价格公道您在阅读前请点击上面的关注二字,后续会第一时间为您提供更多有价值的相关内容,感谢您的支持。现在已经到了11月中旬,2022年马上要结束了,在2022年期间发布了很多款手机,其中只有
一大批最猛的国产机型要来了,今年要换手机的别急,再等等有换机需求的先不要急,下半年迎来一波新机潮,这几款手机即将发布,有你喜欢的吗?第一款vivoX90vivoX90系列将有X90X90ProX90Pro三款机型。首发联发科天玑920
跌至1899,6。78英寸LCD屏1亿像素的HUAWEInova9SE性能怎么样?HUAWEInova9SE是今年3月发布的一款智能手机,现已经跌至1899,价格波动很大,那么现在入手怎么样?这款手机又有什么亮点呢?手机屏幕与续航HUAWEInova9SE屏幕是
关于阿波罗任务的奇怪成功月球阴谋论的不知疲倦的追随者经常对阿波罗计划的完美性表示讽刺的惊讶。他们笑着眯着眼睛说,难以置信的复杂和强大的机械和计算机,显然超越了20世纪60年代的技术,怎么可能做到如此完美?
天桥成功搭建武文佳任昕宇科技日报记者付毅飞实习记者都芃据中国载人航天工程办公室消息,北京时间2022年11月17日16时50分,经过约5。5小时的出舱活动,神舟十四号航天员陈冬刘洋蔡旭哲密切协
能源战争中美为什么都要登上月球?终于点火升空了,无论成败,老航天三大鸽王美国波音SLS火箭美国NASA韦伯深空望远镜苏联俄罗斯科学号实验舱是终于都飞向了太空了啊。当地时间2022年11月16日,美国佛罗里达州,美
为什么一到秋天就掉发严重?又该如何缓解古时候,人们形容女子的美貌时,总是离不开对头发的赞美。诗经鄘风君子偕老中记载鬓发浮云,不屑髢也,这句话的意思就是,浓密而漆黑的头发犹如天上的乌云,拥有这样的一头黑发都不屑使用假发鬓
鼓吹数十部,欢腾十余里佛山祖庙庙会庙会(佛山祖庙庙会),广东省佛山市地方传统民俗,国家级非物质文化遗产之一。1hr简介佛山祖庙庙会是流行于珠江三角洲一带的融世俗性群众性娱乐性为一体的民间信仰活动。佛山祖庙庙会的主要
泉州网红景点有哪些?打卡这些景点,逛得开心拍照靓泉州网红景点有西街,海丝电影小镇,小西埕,花巷天主教堂,泉州之眼摩天轮,觅鲤文创园,SHOW天地,源和1916,小岞风车岛,1915艺术空间等。西街,古街区。海丝电影小镇,民国风。
脱衣舞俱乐部ABoogie我与我自己BoogieWitDaHoodie正在兑现他整个月庆祝生日的诺言即使不得不缩短庆祝活动来进行采访!!!这位出生于布朗克斯的说唱明星周五偶然来到早餐俱乐部,在他最近的生日庆祝活动中仍
詹皇灾难性表现,浓眉独木难支,湖人加时输76人今日NBA一场焦点大战中,湖人三巨头客场挑战76人,双方人员齐整。湖人在常规时间最后时刻,顽强地扳平比分,将比赛拖入加时。加时赛76人一波120直接带走比赛,湖人苦吞3连败!此役浓
恩比德3812哈登28分76人加时力克湖人北京时间12月10日,NBA常规赛继续进行,此役76人坐镇主场迎战湖人。首节开打,恩比德狂轰20分无人可挡,帮助费城迅速占据领先优势。詹姆斯浓眉下半程发力,最后时刻浓眉抢断强攻内线
克里斯蒂亚诺罗纳尔多2022年的净资产他如何花钱克里斯蒂亚诺罗纳尔多无疑是历史上最伟大的足球运动员之一。然而,他不是世界上最富有的运动员,也不是世界上最赚钱的名人,但他是世界上Instagram上关注最多的公众人物。毫无疑问,克
再见,c罗随着2022的世界杯渐渐的落下帷幕,葡萄牙在此次世界杯中也惨遭淘汰,c罗也将离开足球运动,他曾是世界上最伟大的足球运动员之一一位技术无与伦比的运动员2020年他离开皇马,签约新球队
4年4000万,再见勇士!库里要争冠勇士放手一搏交易补强无可厚非西部联盟又大变天了,鹈鹕队现在以17胜8负的战绩,坐上了西部第一的宝座。灰熊队屈居第二,太阳队跌到第三,掘金队第四,国王队第五,爵士队第六,独行侠队第七,开拓者队第八,森林狼队第九
马凡舒拒绝球迷合影惹争议,连续主持春晚世界杯,接班董卿稳了?马凡舒有网友在社交平台上更新了一则动态,配文看球赛遇到马凡舒是什么体验。原来这位网友在卡塔尔世甼杯球场偶遇美女主持马凡舒,此视频一出后,很快引起不少网友们的围观。在球场内也有国内的
(卡塔尔世界杯)足球四分之一决赛摩洛哥对阵葡萄牙(18)当日,在卡塔尔多哈阿图玛玛球场进行的2022卡塔尔世界杯足球赛四分之一决赛中,摩洛哥队对阵葡萄牙队。12月10日,摩洛哥队球员齐耶赫(中)在比赛中受伤倒地后。新华社记者兰红光摄12