QML无边框窗口(可拖动)

一、实现原理

        在 QML 中实现无边框且可以拖动的窗口,要比 Qt PyQt 简单的多。只要隐藏掉窗体、去掉标题栏,然后用一个和原窗体相同大小的 Rectangle 作为新窗体。

        最后在新窗体上再加一个小一些的 Rectangle 作为标题栏,在标题栏中放一个 MouseArea 来监测鼠标位置,同时更新窗体的位置,即 x值即可。

二、具体步骤步骤

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种状态,分别是:按下、松开、位置移动。

        在按下状态时,我们获取鼠标的位置。在松开的时候判断鼠标是否移动,在鼠标移动时,我们将鼠标当前位置减去原窗体位置并赋值给窗体的 xy,即实现了鼠标拖动窗体的功能。

        这一步的代码比较长,小伙伴们可以对照下面的完整代码来理解,我就不一一拆开说明了。

三、完整代码

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 的更多知识与技巧,如果你也有兴趣,可以再关注我一下,感谢!

 

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
QML 中,可以通过设置窗口的 `flags` 属性来启用窗口的拖拽效果。具体实现方法如下: 1. 在窗口的 `Component.onCompleted` 信号中设置窗口的 `flags` 属性: ``` Component.onCompleted: { flags: Qt.Window | Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.X11BypassWindowManagerHint } ``` 2. 在窗口的 `MouseArea` 中添加鼠标事件处理程序: ``` MouseArea { anchors.fill: parent cursorShape: Qt.SizeAllCursor onPressed: { if (mouse.button === Qt.LeftButton) { mouse.accepted = true window.startDrag() } } onMouseXChanged: { if (mouse.button === Qt.LeftButton && mouse.accepted) { window.drag(x - mouse.startX, y - mouse.startY) } } onReleased: { if (mouse.button === Qt.LeftButton && mouse.accepted) { window.stopDrag() } } } ``` 其中,`startDrag()` 方法用于启动窗口的拖拽效果,`drag()` 方法用于实现窗口的拖拽,`stopDrag()` 方法用于停止窗口的拖拽。 3. 在窗口的 `onDragStarted`、`onDragUpdated` 和 `onDragFinished` 信号中实现窗口的拖拽效果: ``` onDragStarted: { startX = x startY = y } onDragUpdated: { window.x = startX + offsetX window.y = startY + offsetY } onDragFinished: { startX = 0 startY = 0 offsetX = 0 offsetY = 0 } ``` 其中,`startX` 和 `startY` 分别表示鼠标按下时窗口的位置,`offsetX` 和 `offsetY` 分别表示鼠标移动的偏移量。在 `onDragUpdated` 信号中,根据鼠标移动的偏移量更新窗口的位置,最后在 `onDragFinished` 信号中重置参数。 通过以上步骤,就可以实现窗口的拖拽效果了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

喵呜角角

如果对你有所帮助,哪怕1毛钱~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值