简体   繁体   中英

QT frameless window resize snap

I have a frameless window I am using MouseArea to allow it to be resizeable. It is working for the most part (I need to add some more resize handles). However, if I drag the window to the top or side on Windows it doesn't 'snap' like a framed one would to filling half the screen or filling the fullscreen. Is there a way with QML to handle this I've heard there is a WM_CHITTEST event I could potentially handle, but how would one be able to respond to a native event like this in 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
            }
        }
    }
}

Best way to do this is to use startSystemResize which added to Qt QWindow since 5.15. You can use in different ways, but my specific way is like this :

    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)
    }

I think this is the best way to resize frameless window in qml

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM