Home > Blockchain >  Conflict of MouseArea with Toolbar Qml
Conflict of MouseArea with Toolbar Qml

Time:01-21

I'm working on making nice Ui using qml, first I have4 to make the window frameless, then reimplement move and resize behavior from within qml, I found an answer for that on stackoverflow. However, when I try to add some components especially a Toolbar inside a ColumnLayout or a Column I cannot resize the window from the edges where the toolbar exists.
A snippet of my code reproduces this problem try to compile it and resize the window from top, top left or top right edges.

PS: I'm using Qt 6.2.1 same behavior with glitches in Qt 6.4

import QtQuick
import QtQuick.Controls
import QtQuick.Layouts

Window {
    id:window
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")
    flags: Qt.FramelessWindowHint | Qt.Window
    MouseArea{
        id:mouseArea
        anchors.fill: parent
        hoverEnabled: true
        acceptedButtons: Qt.LeftButton
        propagateComposedEvents: true
        property int edges: 0
        property int edgeOffset: 5

        function setEdges(x,y){
            edges = 0;
            if (x < edgeOffset) edges |= Qt.LeftEdge;
            if (x > (width - edgeOffset)) edges |= Qt.RightEdge;
            if (y < edgeOffset) edges |= Qt.TopEdge;
            if (y > (height - edgeOffset)) edges |= Qt.BottomEdge;
        }

        cursorShape: {
            return !containsMouse ? Qt.ArrowCursor:
                                    edges == 3 || edges == 12 ? Qt.SizeFDiagCursor :
                                    edges == 5 || edges == 10 ? Qt.SizeBDiagCursor :
                                    edges & 9 ? Qt.SizeVerCursor :
                                    edges & 6 ? Qt.SizeHorCursor : Qt.ArrowCursor;
        }

        onPositionChanged: setEdges(mouseX, mouseY);
        onPressed: {
            setEdges(mouseX, mouseY);
            if(edges && containsMouse){
                window.startSystemResize(edges);
            }
        }
    }

    ColumnLayout{
        width: parent.width
        height: 50
        ToolBar{
            DragHandler{
                onActiveChanged: if(active) startSystemMove()
            }

            Layout.fillHeight: true
            Layout.fillWidth: true
            RowLayout{
                Layout.fillWidth: true
                Layout.fillHeight: true
                ToolButton{
                    text: " "
                    onClicked: {
                        console.log("Hello World")
                    }
                }
                Label{
                   text: "title"
                   horizontalAlignment: Qt.AlignHCenter
                   verticalAlignment: Qt.AlignVCenter
                   Layout.fillWidth: true
                }
                ToolButton{
                    text: "x"
                    onClicked: close()
                }
            }
        }
    }
}

enter image description here

CodePudding user response:

I would put the MouseArea on top by changing the order or the z property and use the MouseEvent accepted property to tell the MouseArea that the event wasn't consumed and needs to be send further down.

But the bigger issue is that the system move in the DragHandler doesn't stop when releasing the mouse button. I tried to solve this by using pressAndHold of the MouseArea, but without any luck yet.

import QtQuick
import QtQuick.Controls
import QtQuick.Layouts

Window {
    id: window
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")
    flags: Qt.FramelessWindowHint | Qt.Window

    ColumnLayout {
        width: parent.width
        height: 50

        ToolBar {
            id: toolBar
            Layout.fillHeight: true
            Layout.fillWidth: true

            RowLayout {
                Layout.fillWidth: true
                Layout.fillHeight: true

                ToolButton {
                    text: " "
                    onClicked: console.log("Hello World")
                }
                Label {
                   text: "title"
                   horizontalAlignment: Qt.AlignHCenter
                   verticalAlignment: Qt.AlignVCenter
                   Layout.fillWidth: true
                }
                ToolButton {
                    text: "x"
                    onClicked: window.close()
                }
            }
        }
    }

    MouseArea {
        id: mouseArea
        anchors.fill: parent
        hoverEnabled: true
        acceptedButtons: Qt.LeftButton

        property int edges: 0
        property int edgeOffset: 5

        function setEdges(x, y) {
            mouseArea.edges = 0
            if (x < mouseArea.edgeOffset) mouseArea.edges |= Qt.LeftEdge
            if (x > (mouseArea.width - mouseArea.edgeOffset)) mouseArea.edges |= Qt.RightEdge
            if (y < mouseArea.edgeOffset) mouseArea.edges |= Qt.TopEdge
            if (y > (mouseArea.height - mouseArea.edgeOffset)) mouseArea.edges |= Qt.BottomEdge
        }

        cursorShape: {
            switch(mouseArea.edges) {
                case Qt.LeftEdge | Qt.TopEdge:
                case Qt.RightEdge | Qt.BottomEdge:
                    return Qt.SizeFDiagCursor
                case Qt.LeftEdge | Qt.BottomEdge:
                case Qt.RightEdge | Qt.TopEdge:
                    return Qt.SizeBDiagCursor
                case Qt.LeftEdge:
                case Qt.RightEdge:
                    return Qt.SizeHorCursor
                case Qt.TopEdge:
                case Qt.BottomEdge:
                    return Qt.SizeVerCursor
                default:
                    return Qt.ArrowCursor
            }
        }

        onPositionChanged: function(mouse) {
            mouseArea.setEdges(mouse.x, mouse.y)
        }
        onPressed: function(mouse) {
            mouseArea.setEdges(mouse.x, mouse.y)
            if (mouseArea.edges && mouseArea.containsMouse)
                window.startSystemResize(mouseArea.edges)

            mouse.accepted = mouseArea.edges
        }
    }
}

CodePudding user response:

It seems to me that everything is very clear here. The Toolbar overlaps that MouseArea. You probably have to add some margins for the toolbar item. for example:

ColumnLayout{
    anchors.top: window.contentItem.top
    anchors.left: window.contentItem.left
    anchors.right: window.contentItem.right
    anchors.margins: 5
    height: 50
    ...
}

Another issue, your RowLayout inside the toolbar isn't inside some Layout so Layout.fill* are not applicable for that. You can replace it with anchors.fill: parent

  • Related