一、实现原理
在 QML 中实现无边框且可以拖动的窗口,要比 Qt 和 PyQt 简单的多。只要隐藏掉窗体、去掉标题栏,然后用一个和原窗体相同大小的 Rectangle 作为新窗体。
最后在新窗体上再加一个小一些的 Rectangle 作为标题栏,在标题栏中放一个 MouseArea 来监测鼠标位置,同时更新窗体的位置,即 x、y 值即可。
二、具体步骤步骤
1. 去掉标题栏、隐藏窗体
color 属性设置为透明即可,防止后面覆盖上来的 Rectangle 有黑边。
flags: Qt.FramelessWindowHint
color: "#00000000"
2. 用Rectangle替代原窗体
要使 Rectangle 能覆盖原窗口,只要把它的宽高设置成和原窗体的宽高一致即可。然后我给它又加了圆角和渐变。如果你不需要圆角,那上面步骤中的 color 属性可以不用设置。
Rectangle
{
width: parent.width
height: parent.height
gradient: Gradient
{
GradientStop{ position: 0.0; color:"#1f005c"}
GradientStop{ position: 1.0; color:"#ffb56b"}
}
radius: 15
...
}
3. 新的标题栏,实现拖动
做到第二步,窗体还不能拖动,是一块固定区域。一般软件的窗体都是通过鼠标按住标题栏,然后移动鼠标,从而窗体跟随鼠标移动,松开鼠标时则窗体停留在此处。
标题栏实现很简单,就是再用一个 Rectangle 来替代就行,这个 Rectangle 和窗体的 Rectangle 是等宽不等高的,高度需要多少,你可以自己设置。
因为标题栏一般都在窗体的顶部,所以我们将这2个 Rectangle 的顶部锚定在一起。
在标题栏中,我们填充一个 MouseArea,在这个 MouseArea 中我们要监测鼠标的3种状态,分别是:按下、松开、位置移动。
在按下状态时,我们获取鼠标的位置。在松开的时候判断鼠标是否移动,在鼠标移动时,我们将鼠标当前位置减去原窗体位置并赋值给窗体的 x、y,即实现了鼠标拖动窗体的功能。
这一步的代码比较长,小伙伴们可以对照下面的完整代码来理解,我就不一一拆开说明了。
三、完整代码
import QtQuick
import QtQuick.Controls
Window {
id: root
width: 640
height: 480
visible: true
title: qsTr("Hello World")
color: "#00000000"
flags: Qt.FramelessWindowHint
property int dragX: 0
property int dragY: 0
property bool dragging: false
Rectangle
{
width: parent.width
height: parent.height
gradient: Gradient
{
GradientStop{ position: 0.0; color:"#1f005c"}
GradientStop{ position: 1.0; color:"#ffb56b"}
}
radius: 15
Rectangle
{
width: parent.width
height: 50
color: "grey"
anchors.top: parent.top
MouseArea
{
anchors.fill: parent
onPressed:
{
root.dragX = mouseX
root.dragY = mouseY
root.dragging = true
}
onReleased: root.dragging = false
onPositionChanged:
{
if(root.dragging)
{
root.x += mouseX - root.dragX
root.y += mouseY - root.dragY
}
}
}
}
}
}
四、结语
码字不易,如果对你有所帮助,请随手点个赞吧!我还会继续更新有关 QML 的更多知识与技巧,如果你也有兴趣,可以再关注我一下,感谢!