首页 > 解决方案 > QT无框窗口调整大小捕捉

问题描述

我有一个无框窗口,我正在使用 MouseArea 来调整它的大小。它大部分都在工作(我需要添加更多调整大小的句柄)。但是,如果我将窗口拖到 Windows 的顶部或侧面,它不会像带框的那样“捕捉”到填充一半屏幕或填充全屏。QML 有没有办法处理这个我听说有一个我可以处理的 WM_CHITTEST 事件,但是如何在 QML 中响应这样的本机事件?

import QtQuick 2.12
import QtQuick.Layouts 1.12
import QtQuick.Controls 2.12
import QtQuick.Window 2.12
import "Themes"

ApplicationWindow
{
    id: mainWindow
    width: 640
    height: 480
    visible: true
    color: Theme.primaryBackgroundColor
    title: qsTr("SmartDraw")
    flags: Qt.FramelessWindowHint | Qt.Window
    readonly property real grabThickness: 4 

    header: Rectangle {
        id: windowHeader
        height: 38
        width: parent.width
        color: Theme.secondaryBackgroundColor

        MouseArea {
            id: windowResizeTopLeft
            width: mainWindow.grabThickness
            height: mainWindow.grabThickness
            anchors.top: parent.top
            anchors.left: parent.left
            cursorShape: Qt.SizeFDiagCursor

            property point lastMousePos: Qt.point(0,0)

            onPressed: {
                lastMousePos = Qt.point(mouse.x,mouse.y)
            }

            onMouseXChanged: {
                var dx = (mouseX - lastMousePos.x)
                mainWindow.x += dx
                mainWindow.width -= dx
            }

            onMouseYChanged: {
                var dy = (mouseY - lastMousePos.y)
                mainWindow.y += dy
                mainWindow.height -= dy
            }
        }

        MouseArea {
            id: windowResizeUp
            height: mainWindow.grabThickness

            anchors.top: parent.top
            anchors.left: windowResizeTopLeft.right
            anchors.right: minimize.left
            cursorShape: Qt.SizeVerCursor

            property real lastMousePosY: 0

            onPressed: {
                lastMousePosY = mouse.y
            }
            onMouseYChanged:
            {
                var dy = (mouseY - lastMousePosY)
                mainWindow.y += dy
                mainWindow.height -= dy
            }
        }

        MouseArea {
            id: windowDragArea
            height: parent.height - mainWindow.grabThickness
            anchors.bottom: parent.bottom
            anchors.left: parent.left
            anchors.right: minimize.left

            property point lastMousePos: Qt.point(0, 0)
            onPressed: { lastMousePos = Qt.point(mouseX, mouseY); }
            onMouseXChanged: mainWindow.x += (mouseX - lastMousePos.x)
            onMouseYChanged: mainWindow.y += (mouseY - lastMousePos.y)
        }

        Button {
            id: minimize
            width: 30
            height: parent.height
            anchors.right: maximize.left
            onClicked: mainWindow.showMinimized()

            background: Rectangle {
                width: parent.width
                height: parent.height
                color: windowHeader.color
            }

            Rectangle {
                color: "white"
                height: 2
                width: Math.round(parent.width*(2.0/3.0))
                anchors.centerIn: parent
            }
        }

        Button {
            id: maximize
            width: 30
            height: parent.height
            anchors.right: close.left
            onClicked: mainWindow.visibility == Window.Maximized ? mainWindow.showNormal() : mainWindow.showMaximized()

            background: Rectangle {
                width: parent.width
                height: parent.height
                color: windowHeader.color
            }

            Rectangle {
                color: "white"
                width: 15
                height: 15
            }
        }

        Button {
            id: close
            width: 30
            anchors.right: parent.right
            height: parent.height
            onClicked: Qt.quit()

            background: Rectangle {
                width: parent.width
                height: parent.height
                color: windowHeader.color
            }

            Text {
               color: "white"
               text: "X"
            }
        }
    }


    footer: Rectangle {
        id: windowFooter
        color: "#0e6afa"
        height: 23

        MouseArea {
            id: windowResizeBottomLeft
            width:  mainWindow.grabThickness
            height: mainWindow.grabThickness
            anchors.left: parent.left
            anchors.bottom: parent.bottom
            cursorShape: Qt.SizeBDiagCursor

            property point lastMousePos: Qt.point(0,0)

            onPressed: {
                lastMousePos = Qt.point(mouse.x,mouse.y)
            }

            onMouseYChanged:
            {
                var dx = (mouseX - lastMousePos.x)
                var dy = (mouseY - lastMousePos.y)

                mainWindow.x += dx
                mainWindow.width -= dx
                mainWindow.height += dy
            }
        }

        MouseArea {
            id: windowResizeBottom
            x: mainWindow.grabThickness
            height: mainWindow.grabThickness
            anchors.bottom: parent.bottom
            anchors.left: windowResizeBottomLeft.right
            anchors.right: windowResizeBottomRight.left
            cursorShape: Qt.SizeVerCursor

            property real lastMousePosY: 0

            onPressed: {
                lastMousePosY = mouse.y
            }

            onMouseYChanged:
            {
                var dy = (mouseY - lastMousePosY)
                mainWindow.height += dy
            }
        }

        MouseArea {
            id: windowResizeBottomRight
            width: mainWindow.grabThickness
            height: mainWindow.grabThickness
            anchors.right: parent.right
            anchors.bottom: parent.bottom
            cursorShape: Qt.SizeFDiagCursor

            property point lastMousePos: Qt.point(0,0)

            onPressed: {
                lastMousePos = Qt.point(mouse.x,mouse.y)
            }

            onMouseYChanged:
            {
                var dx = (mouseX - lastMousePos.x)
                var dy = (mouseY - lastMousePos.y)

                mainWindow.width += dx
                mainWindow.height += dy
            }
        }
    }
}

标签: qtqml

解决方案


最好的方法是使用从 5.15 开始startSystemResize添加到 Qt 中的 which 。QWindow您可以以不同的方式使用,但我的具体方式是这样的:

    MouseArea{
    id : resizearea
    width: 5
    height: 5
    anchors.bottom: parent.bottom
    anchors.right: parent.right


    cursorShape: Qt.SizeAllCursor
    acceptedButtons: Qt.LeftButton
    pressAndHoldInterval: 100
    onPressAndHold:
    {
        mainview.startSystemResize(Qt.BottomEdge | Qt.RightEdge)
    }

我认为这是在 qml 中调整无框窗口大小的最佳方法


推荐阅读