ScrollView and drawning a selection region with a mouse



  • Hello,

    I've started learning Qt 5 some time ago but I've encountered an issue that I cannot solve by myself and also cannot find any solution to it.

    A bit of background: for training purposes I'm writing an app that manipulates Mandelbrot's Set. App is supposed to work under X11 - currently I don't need it to work in other types of platforms. It's based on QML with some components written in C++.

    The problem is following: one of the functionality is that user should be able to rescale a region by selecting an area with a mouse. And it works fine. But when I'm using ScrollView in the way that it contains painted area with the fractal (and also MouseArea for region selection) the selection behaves weird: I can do selection only for a split-second then selection stops working.

    I'm using Qt 5.12.6 but I've checked 5.14.0 and the problem still persist.

    I've isolated the issue into simpler app:

    import QtQuick 2.12
    import QtQuick.Window 2.12
    import QtQuick.Controls 2.12
    
    Window {
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
    
    
        //test
        ScrollView {
    
            width: 300
            height: 300
            clip: true
            ScrollBar.vertical.policy: ScrollBar.AlwaysOn
            ScrollBar.horizontal.policy: ScrollBar.AlwaysOn
    
            contentWidth: 400
            contentHeight: 400
    
            Rectangle {
    
                id: scrollItem
                width: 400
                height: 400
                color: "green"
    
                Rectangle {
    
                    id: selectArea
                    width: 1
                    height: 1
                    visible: false
                    color: "red"
    
                    border.width: 1
                    border.color: "darkgrey"
    
                    antialiasing: false
    
                }
    
                MouseArea {
    
                    anchors.fill: parent
                    hoverEnabled: true
    
                    property var rectStartingPoint: Qt.point(0,0)
    
                    onPositionChanged: {
    
                        if ( pressed ) {
    
                            var dx = mouseX - rectStartingPoint.x
                            var dy = mouseY - rectStartingPoint.y
    
                            if( dx >= 0){
                                selectArea.width = dx
                            }else{
                                selectArea.x = mouseX
                                selectArea.width = -dx
                            }
    
                            if( dy >= 0){
                                selectArea.height = dy
                            }else{
                                selectArea.y = mouseY
                                selectArea.height = -dy
                            }
                        }
                    }
    
                    onPressed: {
    
                        selectArea.visible = true
    
                        rectStartingPoint.x = mouseX
                        rectStartingPoint.y = mouseY
    
                        selectArea.x = rectStartingPoint.x
                        selectArea.y = rectStartingPoint.y
    
                    }
    
                    onReleased: {
    
                        selectArea.visible = false
                        selectArea.width = 1
                        selectArea.height = 1
    
                    }
    
                }//MouseArea
            }//Rectangle
        }//ScrollView
        //test
    
    }
    

    Try to draw a selection inside the green rectangle.

    Note: whenScrollView.width = ScrollView.contentWidth and ScrollView.height = ScrollView.contentHeight selection works as expected but then ScrollView is not much of use.

    What am I doing wrong?



  • @SoKaI Hi. All you need is changing interactive property of scrollview when pressed and released:

    import QtQuick 2.11
    import QtQuick.Window 2.11
    import QtQuick.Controls 2.4
    
    Window {
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
    
    
        //test
        ScrollView {
    
            id: scrollView
    
            width: 300
            height: 300
            clip: true
            ScrollBar.vertical.policy: ScrollBar.AlwaysOn
            ScrollBar.horizontal.policy: ScrollBar.AlwaysOn
    
            contentWidth: 400
            contentHeight: 400
    
    
    
            Rectangle {
    
                id: scrollItem
                width: 400
                height: 400
                color: "green"
    
                Rectangle {
    
                    id: selectArea
                    width: 1
                    height: 1
                    visible: false
                    color: "red"
    
                    border.width: 1
                    border.color: "darkgrey"
    
                    antialiasing: false
    
                }
    
                MouseArea {
    
                    anchors.fill: parent
                    hoverEnabled: true
    
                    property var rectStartingPoint: Qt.point(0,0)
    
                    onPositionChanged: {
    
                        if ( pressed ) {
    
                            var dx = mouseX - rectStartingPoint.x
                            var dy = mouseY - rectStartingPoint.y
    
                            if( dx >= 0){
                                selectArea.width = dx
                            }else{
                                selectArea.x = mouseX
                                selectArea.width = -dx
                            }
    
                            if( dy >= 0){
                                selectArea.height = dy
                            }else{
                                selectArea.y = mouseY
                                selectArea.height = -dy
                            }
                        }
                    }
    
                    onPressed: {
                        scrollView.contentItem.interactive = false
    
                        selectArea.visible = true
    
                        rectStartingPoint.x = mouseX
                        rectStartingPoint.y = mouseY
    
                        selectArea.x = rectStartingPoint.x
                        selectArea.y = rectStartingPoint.y
    
                    }
    
                    onReleased: {
    
                        selectArea.visible = false
                        selectArea.width = 1
                        selectArea.height = 1
    
                        scrollView.contentItem.interactive = true
    
    
                    }
    
                }//MouseArea
            }//Rectangle
        }//ScrollView
        //test
    
    }
    
    
    

    You can also check this post



  • @SoKaI Hi. All you need is changing interactive property of scrollview when pressed and released:

    import QtQuick 2.11
    import QtQuick.Window 2.11
    import QtQuick.Controls 2.4
    
    Window {
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
    
    
        //test
        ScrollView {
    
            id: scrollView
    
            width: 300
            height: 300
            clip: true
            ScrollBar.vertical.policy: ScrollBar.AlwaysOn
            ScrollBar.horizontal.policy: ScrollBar.AlwaysOn
    
            contentWidth: 400
            contentHeight: 400
    
    
    
            Rectangle {
    
                id: scrollItem
                width: 400
                height: 400
                color: "green"
    
                Rectangle {
    
                    id: selectArea
                    width: 1
                    height: 1
                    visible: false
                    color: "red"
    
                    border.width: 1
                    border.color: "darkgrey"
    
                    antialiasing: false
    
                }
    
                MouseArea {
    
                    anchors.fill: parent
                    hoverEnabled: true
    
                    property var rectStartingPoint: Qt.point(0,0)
    
                    onPositionChanged: {
    
                        if ( pressed ) {
    
                            var dx = mouseX - rectStartingPoint.x
                            var dy = mouseY - rectStartingPoint.y
    
                            if( dx >= 0){
                                selectArea.width = dx
                            }else{
                                selectArea.x = mouseX
                                selectArea.width = -dx
                            }
    
                            if( dy >= 0){
                                selectArea.height = dy
                            }else{
                                selectArea.y = mouseY
                                selectArea.height = -dy
                            }
                        }
                    }
    
                    onPressed: {
                        scrollView.contentItem.interactive = false
    
                        selectArea.visible = true
    
                        rectStartingPoint.x = mouseX
                        rectStartingPoint.y = mouseY
    
                        selectArea.x = rectStartingPoint.x
                        selectArea.y = rectStartingPoint.y
    
                    }
    
                    onReleased: {
    
                        selectArea.visible = false
                        selectArea.width = 1
                        selectArea.height = 1
    
                        scrollView.contentItem.interactive = true
    
    
                    }
    
                }//MouseArea
            }//Rectangle
        }//ScrollView
        //test
    
    }
    
    
    

    You can also check this post



  • Thank you, it works!