城市直播房产教育博客汽车
投稿投诉
汽车报价
买车新车
博客专栏
专题精品
教育留学
高考读书
房产家居
彩票视频
直播黑猫
投资微博
城市上海
政务旅游

Qt无边框窗体最大化时支持拖拽还原

8月8日 火云谷投稿
  一、概述
  用Qt进行开发界面时,既想要实现友好的用户交互又想界面漂亮,那么自定义界面就必不可少。其中有一个操作就是是我们每一个Qter开发者都要会的,而且是经常进行的。
  Qt::FramelessWindowHint这个属性想必大家都使用过,有些同学可能对这个属性很了解,也用的是炉火纯青,今天我们也来说说这个属性。
  关于这个无边框属性网上也有一些文章,有些谈论的是bug,当然了这是针对不同os而言,也有些是跟其他第三方库混合使用时的问题。可是问题归问题,想要实现自定义的优秀界面这个属性也是必不可少的。
  今天我们就来实现一个无边框窗体最大化时,支持拖拽标题栏进行还原的功能。
  无边框窗体支持缩放、移动这些不属于本篇文章的内容,本篇文章主要讲解怎么实现最大化时拖拽标题栏进行还原窗体,本篇文章的代码依赖于博主之前封装的一个拖拽代理类。二、效果展示
  如效果图所示,做了一个简单的事例,双击标题栏窗体最大化,这个时候如果进行标题栏拖拽,当鼠标按下并移动一段距离时窗体恢复normal状态。
  恢复normal状态下的窗体仍然支持放大和缩小,有接口可以设置。
  三、demo制作
  demo的制作过程还是比较简单的,分为如下几步1、设计窗体
  通过desinger设计器我们拖拽了一个大致窗体内容,为了更好的展示效果,标题栏加上了icon和背景色
  2、双击放大
  鼠标双击标题栏放大这个功能实现起来方法也比较多,这里博主选择了代码量最少并且实现起来最简单的方式,直接把标题栏的事件循环安装到了主窗体上。ui。widgetinstallEventFilter(this);
  接下来我们就需要重写主窗口的eventFilter函数即可boolDragWidget::eventFilter(QObjectwatched,QEventevent){if(watchedui。widget){if(eventtype()QEvent::MouseButtonDblClick){if(isMaximized()){showNormal();mhandler。setWidgetResizable(true);mhandler。setWidgetMovable(true);}else{showMaximized();mhandler。setWidgetResizable(false);mhandler。setWidgetMovable(false);}}}returnQWidget::eventFilter(watched,event);}
  细心的同学就会发现代码里有一个mhandler变量,这个类就是博主之前自己封装的一个拖拽代理,通过接口可以设置被代理的窗体,并设置需要代理哪些行为。
  本篇文章中所演示的事例代码,我们代理了主窗口上标题栏部分的移动事件和整个窗体的缩放事件,设置代码如下所示mhandler。activateOn(this);mhandler。useLocalMoveabled(true);mhandler。addLocalWidget(ui。widget);mhandler。setMaximumMove(true,true);
  拖拽代理类内容比较多,本篇文章暂不讲解。四、拖拽
  为了更好的理解本篇文章,这里需要把拖拽代理类的头文件放出来,这样更有利于大家理解。
  接口都比较简单,代码中也有注释,大家自行阅读。classWidgetResizeHandler:publicQObject{public:explicitWidgetResizeHandler(QObjectparent0);WidgetResizeHandler();public:voidactivateOn(QWidgettopLevelWidget);添加topLevelWidget事件代理voidremoveFrom(QWidgettopLevelWidget);移除topLevelWidget事件代理Qt::CursorShapeCursorShape(QWidgetwidget);窗口移动default:truevoidsetWidgetMovable(boolmovable);boolisWidgetMovable();大小可变default:truevoidsetWidgetResizable(boolresizable);boolisWidgetResizable();橡胶式窗口移动default:falsevoiduseRubberBandOnMove(booluse);boolisUsingRubberBandOnMove();橡胶式修改大小default:falsevoiduseRubberBandOnResize(booluse);boolisUsingRubberBandOnResisze();voidsetBorderWidth(intnewBorderWidth);intborderWidth();局部可移动voiduseLocalMoveabled(booluse);voidaddLocalWidget(QWidget);最大化时支持拖拽参数2表示是否可放大缩小voidsetMaximumMove(boolmove,boolresizefalse);protected:virtualbooleventFilter(QObjectobj,QEventevent)QDECLOVERRIDE;private:WidgetResizeHandlerI};
  值得注意的是最后一个setMaximumMove接口,他就是我们今天的猪脚是否支持最大化时拖拽。当我们设置了这个接口后,窗体最大化时也就能进行拖拽,并还原到之前的normal状态。
  文章第三小节讲解demo时,说过主窗体已经被代理拖拽类进行了事件代理,那么主窗体的所有事件首先都会传递给这个代理类,这里我们需要重点关注下鼠标按下时移动事件。voidWidgetData::handleMouseMoveEvent(QMouseEventevent){if(mLeftButtonPressed){if(dptrmWidgetResizablemPressedMousePos。onEdges){resizeWidget(eventglobalPos());}elseif(dptrmWidgetMovable){moveWidget(eventglobalPos());}elseif(dptrmMaxMovable){if(mWidgetisMaximized()TryMoveWidget(event)){dptrmWidgetMdptrmWidgetR}}}elseif(dptrmWidgetResizable){updateCursorShape(eventglobalPos());}}
  这段代码包含有其他缩放窗体和正常移动的逻辑,最大化时支持移动的逻辑应该不难找木九十TryMoveWidget这个函数,该函数中我们进行了充分的逻辑判断,一旦触发了窗体移动,那么我们把mWidgetMovable变量置为true,下一次鼠标按下移动事件就会触发正常的拖拽逻辑。
  仔细思考上边一段话,其中有2个关键信息触发窗体移动,并还原到之前的normal状态进行了第一步后,需要把mWidgetMovable变量置为true,之后走正常的窗体移动流程
  窗体移动
  尝试移动窗体,当鼠标当前位置距离鼠标按下时的距离大于20px时,进行窗体还原操作,并返回true,代表窗体已经被重置到normal态。boolWidgetData::TryMoveWidget(QMouseEventevent){QPointdistanceeventglobalPos()mDragPintlengthdistance。manhattanLength();if(length20){QRectrectmWidgetnormalGeometry();intdesXmDragPos。x()rect。width()mWidgetgeometry()。width();intdesYmDragPos。y();rect。moveTopLeft(eventglobalPos()QPoint(desX,desY));mWidgetshowNormal();mWidgetsetGeometry(rect);mDragPosQPoint(desX,desY);mIsMaxM}}
  上述代码中的mIsMaxMove标识是为了在一次窗体还原操作后,释放鼠标时可以正常的设置缩放标识而设。
  有了上述代码之后,窗体就能还原到最大化之前的大小,并且为之也移动到了鼠标相应的位置,关于这个新位置的计算这里需要说明下。
  x坐标
  x轴坐标使用了比例计算方式。窗体全屏时鼠标按下的位置在窗体上的位置在窗体还原后依然保持不变,这样计算比较简单而且不会出错,保证窗体还原后,鼠标会一直在标题栏内。
  如果需要优化x轴坐标的计算方法,只需要重新计算上述代码中的desX值即可。
  y坐标
  y轴坐标这里没有做特殊处理。因为窗体还原时,标题栏的高度是没有发生变化的,因此这里不需要做特殊处理。
投诉 评论 转载

央视未经授权转发世界杯相关内容将面临高额罚款!看细则不踩线头条创作挑战赛2022卡塔尔世界杯开始了,不少朋友或自媒体都躁(激动)动起来,有些自媒体还对世界杯的官方节目进行了二次创作,一时间球星表情包、比赛回放、慢放、剪辑、转播、点播、……截至目前,盘点2022年搭载高素质人像镜头的手机【1】小米12SPro搭载第一代骁龙8处理器,采用台积电4nm制程工艺,性能更强,功耗表现也得到大幅度的改善,体验也跃升新高正面是一块6。73英寸的三星E5发光材料……如果你也有不完美的父母这几年心理学普及最大的成果之一,是能够让我们重新审视自己和父母的关系,了解父母对我们成长的影响;副作用则是,父母不幸从备受尊重的家庭权威,变成了心理问题的替罪羊。经常有人跟我说……Qt无边框窗体最大化时支持拖拽还原一、概述用Qt进行开发界面时,既想要实现友好的用户交互又想界面漂亮,那么自定义界面就必不可少。其中有一个操作就是是我们每一个Qter开发者都要会的,而且是经常进行的。……三种专坑外行的酒,看似便宜,实则都是坑要说到现代人买东西最怕什么?那一定是交智商税说到白酒,相信很多人也都不陌生,但是要是说起专业知识,比如酒的香型和酿造过程,可能很多人都不知道,但事实是不了解这些,极其容易被交智……距离产生了思念,惦念形成了挂牵执手岁月人生在生命里写下了爱的永恒无论相隔地北天南将思念穿越了万水千山飞进了你的心间带着爱意的缕缕情丝把两颗心紧紧地连在一……绿源极影智速版测评最高时速80KMh,续航160公里,支持超您在阅读前请点击上面的关注二字,后续会第一时间为您提供更多有价值的相关内容,感谢您的支持。电动车厂家除了生产符合新国标标准的电动自行车以外,最近很多品牌都推出了高速度、高……娃又咳嗽了!吃药还是去医院?儿科专家建议这样做大家感受到冬天的温度了吗?最近也太!冷!了!从得知要大降温开始,到实实在在感觉到这冻人的温度,咱老妈子的心真是揪得紧紧的。第一个闪入脑海的,不是担心没衣服穿、上班路上冷,……销量持续下跌!荣威品牌到底怎么了?最近几年车市的变局非常大,合资车企销量下滑,新势力造车突飞猛进,比亚迪疯狂发展,长城也开始面临危机。但这些品牌都是一些知名度相对较高的品牌,还有一个品牌最近出现了非常明显的问题……欧国联法国vs奥地利多名主力伤缺,法国队主场能否大胜奥地利?本文作者jun本场最球突破点作为欧国联的卫冕冠军,法国现在的情况是非常糟糕的,6月的四场欧国联比赛2平2负一胜难求。作为世界杯前的最后一个国际比赛日,主教练德……网红参加铁人三项,穿着被批不得体,本尊无奈回复运动服不是泳衣如今的网友不知道是不是管的太宽,连运动员穿什么都要点评一下,如今一位叫阿爽的国家级运动员,就遭遇到了这样的意外吐槽。阿爽平时是一位非常积极向上,喜欢运动的网红,拥有着几十万的粉……上海松江绘就文旅融合新画卷成功创建首批国家全域旅游示范区;二陆文化小镇、佘山体育小镇、华阳湖影视小镇等一批以人文松江为特质的文旅目的地项目正在加快推进;泗泾下塘、永丰仓城、中山府城、华阳老街等历史风貌区……
苦瓜对生长环境的要求管理者世界之目标管理关节不好的人们应该吃什么?医生这6组食物,或可端上饭桌社会上兄弟情义的句子走出软件作坊思维导图读书笔记大S真是恋爱里的勇者比尔盖茨这项技术的出现即将淘汰移动手机?江苏人喝酒必备的4道硬菜,道道经典特色,外地人尝过都说好20个见证爱情的美景地,一定要和最爱的人一起走遍,你走过几个这6款国货劝你不要用,怕你用了以后变的越来越漂亮男士快速祛痘的方法有哪些能净化空气的神奇仿真鲜花凭什么产销两旺那么火乐乐茶车厘子酪酪多少钱一杯乐乐茶车厘子酪酪好喝吗曾经的金融副省长,掌舵光大银行掌握九点婆媳难题迎刃而解皇马清洗第一人确定!俱乐部下周通知他走人,腾出年薪买巨星借船过河洞察你真实的人性和欲望2010年终感悟从对方的内部下手削笔刀的自述很威风的一个字王再看古人的造字智慧行政机关强拆违建犯法吗?直肠息肉手术多少钱(直肠息肉和痔疮有什么区别)揭秘!接管组组长详解包商银行接管始末,细数公司治理“六宗罪”

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找