前言

使用Qt在开发桌面程序时,通常会去除默认的程序边框,从而实现自定义的标题栏。然而当设置窗口属性为Qt.FramelessWindowHint后,窗口的拖动,以及在边缘拖动缩放的功能就没有了,在以前的Qt版本中,就需要自己写很多繁琐代码来实现这些功能,尽管Qt为此也提供了一个类 QSizeGrip,但是它仅仅只能在窗口角落进行调整,在窗口上下左右边缘是不行的。
庆幸的是,在Qt5.15中官方在QWindow中提供了两个新的方法:startSystemMove和startSystemResize。这些方法要求窗口管理器接管并启动本机调整大小或移动操作,并且实现起来也非常简单,接下来我们通过示例来看下新接口的使用。

正文

先来看下实际效果:

(以上gif的录制没有将鼠标状态录制进来,所以看不到鼠标,实际上鼠标放在边缘的时候会动态变化其状态)

拖动标题栏可以移动整个窗口,双击标题栏可以最大化窗口。

废话不多说,直接上代码。

import QtQuick 2.12
import QtQuick.Controls 2.3
import QtQuick.Window 2.3Window {id: windowvisible: trueflags: Qt.FramelessWindowHintwidth: 300height: 300color: "white"property int bw: 3function toggleMaximized() {if (window.visibility === Window.Maximized) {window.showNormal();} else {window.showMaximized();}}// The mouse area is just for setting the right cursor shapeMouseArea {anchors.fill: parenthoverEnabled: truecursorShape: {const p = Qt.point(mouseX, mouseY);const b = bw + 10; // Increase the corner size slightlyif (p.x < b && p.y < b) return Qt.SizeFDiagCursor;if (p.x >= width - b && p.y >= height - b) return Qt.SizeFDiagCursor;if (p.x >= width - b && p.y < b) return Qt.SizeBDiagCursor;if (p.x < b && p.y >= height - b) return Qt.SizeBDiagCursor;if (p.x < b || p.x >= width - b) return Qt.SizeHorCursor;if (p.y < b || p.y >= height - b) return Qt.SizeVerCursor;}acceptedButtons: Qt.NoButton // don't handle actual events}DragHandler {id: resizeHandlergrabPermissions: TapHandler.TakeOverForbiddentarget: nullonActiveChanged: if (active) {const p = resizeHandler.centroid.position;const b = bw + 10; // Increase the corner size slightlylet e = 0;if (p.x < b) { e |= Qt.LeftEdge }if (p.x >= width - b) { e |= Qt.RightEdge }if (p.y < b) { e |= Qt.TopEdge }if (p.y >= height - b) { e |= Qt.BottomEdge }window.startSystemResize(e);}}ToolBar {width: parent.width-2*bwheight: 30x:bw;y:bwItem {anchors.fill: parentTapHandler {onTapped: if (tapCount === 2) toggleMaximized()gesturePolicy: TapHandler.DragThreshold}DragHandler {grabPermissions: TapHandler.CanTakeOverFromAnythingonActiveChanged: if (active) { window.startSystemMove(); }}}}
}

拖动并调整窗口主要是在DragHandler 中实现,MouseArea 是为了改变鼠标的样式。

请注意,尽管这是一个跨平台 API,但并非所有平台都支持它。Wayland、X11、macOS 和 Windows 目前支持 startSystemMove,而另一方面,Wayland、X11 和 Windows 支持 startSystemResize,但不支持 macOS。

为了解决这个问题,两种方法都返回一个布尔值,指示是否支持该操作。这意味着如果你也想在 macOS 上实现调整大小,你将不得不检查 startSystemResize 的返回值,并尽力实现一个回退,以防它失败,即:

if (!window.startSystemResize(edges)) { // 手动设置 window.width/height 的后备代码
}

最后要注意,这个新属性是在Qt5.15中提供的,低版本不支持。

最简单的方式实现QML无边框窗口边缘拖动调整大小相关推荐

  1. 【C++·Qt】Qt透明无边框窗口以及拖动

    窗口透明  1.窗口整体透明(包含其子空控件) //窗口以及子控件都透明 //setAttribute(Qt::WA_WState_WindowOpacitySet); //网上说直接设置不起作用,需 ...

  2. QT实现可移动和改变尺寸的无边框窗口

    2019独角兽企业重金招聘Python工程师标准>>> 实现QT无边框窗口的拖动,尺寸改变.需要的时候从该类继承,派生类需要定义为QWidget. 头文件: #ifndef SIZE ...

  3. Electron无边框窗口(最小化、最大化、关闭、拖动)以及动态改变窗口大小

    文章目录 一.目标原型 1. 目标 2. 原型设计 3. 原型初步实现 二.无边框窗口 1. 要点 2. 改造 三.可拖拽区 1. 要点 2. 改造 四.最小化.最大化.关闭 1. 要点 2. 改造 ...

  4. Qt Quick无边框窗口

    开发环境:Qt Creator 5.6 内容:  使用 Qt  Quick创建无边框窗口 Qt Quick是一个无比强大.无比方便快捷的跨平台的开发框架,并且能通过Qt强大的元对象系统实现qml与c+ ...

  5. MFC无边框对话框实现拖动

    解决无标题栏窗口的拖动问题有两种方案,一种方案是使用常规思路来处理鼠标拖拽事件,当窗口获得WM_LBUTTONDOWN(OnLButtonDown)时,通过设置标志并调用CWnd::SetCaptur ...

  6. [乱说]Electron 无边框窗口最大化最小化关闭功能

    title: '[乱说]Electron 无边框窗口最大化最小化关闭功能' date: 2017-11-21 21:43:40 tags: Electron 无边框窗口最大化最小化关闭功能 目的 实现 ...

  7. QT实现完美无边框窗口(可拖动,可调整大小)

    效果如下: 只需定义 nativeEvent 事件即可完成这样的功能 ,但要注意的是,这是通过Windows api实现的. 样例如下:(注意头文件) framelesswidget.h #ifnde ...

  8. 【QT】自定义无边框窗口分享

    [QT/天下wu双]自定义无边框窗口分享 https://www.bilibili.com/video/BV1HA411Y7d4 源码链接:https://github.com/Bili-TianX/ ...

  9. qt禁止拖动_[Qt]QMdiArea,无框架窗口的拖动

    0:QMdiArea中添加子窗口后,想固定or调整窗口的大小 需要在addSubWindow()函数调用后返回子窗口的指针,然后再设置子窗口的大小 注意设置imagelabel的大小是没有效果的,im ...

最新文章

  1. mysql无法解析方程式索引
  2. 格雷码问题:输出当输入为n时的格雷码
  3. ARM不同位数系统int字节数区别
  4. logstash mysql增量_Logstash jdbc 按时间增量更新的一些总结
  5. 喝最烈的酒、挖最大的DONG——工具与技巧篇
  6. freeredius3.0 mysql_EDIUS非线性编辑系统价格,4k视频编辑系统
  7. SmartUpload上传下载使用
  8. python和excel能结合应用吗_通过Python在Excel中使用机器学习
  9. 两个月新增 80万行代码,Linux 内核维护为什么不会崩?
  10. 分布式计算的程序设计,请各位帮忙看看有没有意见
  11. 温州服务器付费方式_新购买的服务器是选择包年包月还是按流量计费呢?
  12. python mysql res_python操作mysql(三)查询
  13. amtlib.dll被McAfee删除之后?
  14. Premiere cc 2019安装教程及安装包
  15. 读书笔记 - 《六神磊磊读唐诗》
  16. 【FireMonkey】StyleBook使用方法
  17. 计算机桌面图片打不开显示内存不足,电脑上的windows图片查看器提示内存不足如何解决...
  18. c语言中的圆方程,高中圆的方程练习题
  19. 最新的 CocoaPods 的使用教程 上传podspec
  20. SQL 模拟生成商品订单表

热门文章

  1. 聚焦场景落地, 看“云+AI”如何激发5G的“隐藏技能”
  2. 0227互联网新闻 | 腾讯与英特尔联合推出云游戏平台“腾讯即玩”;华为企业业务MWC现场发布数字平台...
  3. 普通java项目配置mybatis是总是显示数据库驱动找不到
  4. 【JAVA秒会技术之秒杀面试官】JavaSE常见面试题(二)
  5. Android 5.x Theme 与 ToolBar 实战
  6. Teradata首席分析官Bill Franks:数据分析变革犹如一场工业革命
  7. PHP XML和数组互相转换
  8. apple air装双系统(win7)
  9. 关于Apache虚拟主机的设置
  10. Github标星1.6W+,程序员不得不知的“潜规则”又火了,早知道就不会秃头了