Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Connect custom Scrollbar and Flickable

Connect custom Scrollbar and Flickable

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
1 Posts 1 Posters 178 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • F Offline
    F Offline
    fryn3
    wrote on last edited by
    #1

    I have a virtual large table, and an area that is real drawn. Depending on the position of the content, a certain part of the virtual table is displayed.
    And now I'm trying in different ways to synchronize the content and the scrollbar.
    In this case, the scrollbar jumps with the content.

    AreaScrollBar.qml

    import QtQuick 2.15
    import QtQuick.Controls 2.15
    
    ScrollBar {
        id: root
        /// Virtual content size
        /// 50000
        property real virtualContentSize: 0
    
        /// Real content size
        /// 2000
        property real contentSize: 0
    
        /// Visible content size
        /// 500
        property real visibleSize: orientation === Qt.Horizontal ? width : height
    
        /// Position offset step.
        /// 100
        property real stepAreaPosition: 1
    
        /// The position of the component area [0 .. virtualContentSize - contentSize]
        property real areaPosition: 0
    
        /// [0 .. contentSize - visibleSize]
        property real positionInArea: 0
    
        property QtObject priv: QtObject {
            /// В запасе после перестроения
            readonly property real buffer: 0.2 * contentSize - (0.2 * contentSize) % stepAreaPosition
        }
    
        size: (orientation === Qt.Horizontal ? width : height) / virtualContentSize
        policy: ScrollBar.AlwaysOn
        onPositionChanged: {
            console.log('onPosChanged', position)
            let arP = -1
            let pia = -1
            if (position < 0) {
                position = 0
            } else if (position + size > 1) {
                position = 1 - size
            }
    
            if (position * virtualContentSize + visibleSize
                    > areaPosition + 0.9 * contentSize) {
                pia = priv.buffer
            } else if (position * virtualContentSize - areaPosition < 0.1 * contentSize) {
                pia = contentSize - (priv.buffer + visibleSize)
            } else {
                positionInArea = position * virtualContentSize - areaPosition
                return
            }
    
            arP = position * virtualContentSize - pia
            let arp2 = 0
            if (arP < 0) {
                arp2 = 0
            } else if (arP > virtualContentSize - contentSize) {
                arp2 = virtualContentSize - contentSize
            } else {
                arp2 = arP - (arP % stepAreaPosition)
            }
    
            positionInArea = position * virtualContentSize - arp2
            areaPosition = arp2
        }
    }
    

    main.qml

    import QtQuick 2.15
    import QtQuick.Window 2.15
    import QtQuick.Controls 2.15
    import QtQuick.Layouts 1.15
    
    Window {
        width: 600
        height: 600
        visible: true
        title: qsTr("Hello World")
    
        Column {
            focus: true
            Keys.onDownPressed:  vSb.position += 10 / vSb.virtualContentSize
            Keys.onUpPressed:    vSb.position -= 10 / vSb.virtualContentSize
            Keys.onLeftPressed:  hSb.position -= 10 / hSb.virtualContentSize
            Keys.onRightPressed: hSb.position += 10 / hSb.virtualContentSize
            Row {
                Column {
                    Text { text: qsTr("vSb.position %1").arg(vSb.position) }
                    Text { text: qsTr("vSb.areaPosition %1").arg(vSb.areaPosition) }
                    Text { text: qsTr("vSb.positionInArea %1").arg(vSb.positionInArea) }
                }
                Item {
                    width: 100
                    height: 1
                }
    
                Column {
                    Text { text: qsTr("hSb.position %1").arg(hSb.position) }
                    Text { text: qsTr("hSb.areaPosition %1").arg(hSb.areaPosition) }
                    Text { text: qsTr("hSb.positionInArea %1").arg(hSb.positionInArea) }
                }
            }
    
    
            Rectangle {
                id: mainArea
                width: 500
                height: 500
                clip: true
                color: "gray"
                border.color: "darkgray"
                border.width: 3
                property int _rows: 50
                property int _columns: 10
                property int _virtualRows: 500
                property int _virtualColumns: 50
                property int _rectWidth: 90
                property int _rectHeight: 90
                property int _spacing: 10
                property int _virtualContentWidth: _virtualColumns * (_rectWidth + _spacing)
                property int _virtualContentHeight: _virtualRows * (_rectHeight + _spacing)
    
                Flickable {
                    id: _flick
                    anchors.fill: parent
                    contentWidth: mainArea._columns * (mainArea._rectWidth + mainArea._spacing)
                    contentHeight: mainArea._rows * (mainArea._rectHeight + mainArea._spacing)
                    Column {
                        spacing: mainArea._spacing
                        Repeater {
                            model: mainArea._rows
                            Row {
                                property int rowInd: index
                                spacing: mainArea._spacing
                                Repeater {
                                    model: mainArea._columns
                                    Rectangle {
                                        id: rect
                                        property int columnInd: index
                                        width: mainArea._rectWidth
                                        height: mainArea._rectHeight
                                        color: "#3c324a"
                                        Column {
                                            Repeater {
                                                model: rect.height / 10
                                                Rectangle {
                                                    width: rect.width
                                                    height: 10
                                                    color: Qt.lighter(rect.color, 1 + index * 0.1)
                                                }
                                            }
                                        }
                                        Text {
                                            anchors.fill: parent
                                            horizontalAlignment: Text.AlignLeft
                                            verticalAlignment: Text.AlignTop
                                            text: '[%2, %3]'.arg(rowInd).arg(columnInd)
                                            font.pointSize: 7
                                        }
                                        Text {
                                            anchors.fill: parent
                                            horizontalAlignment: Text.AlignHCenter
                                            verticalAlignment: Text.AlignVCenter
                                            text: ('content\n[%1, %2]'
                                                   .arg(vSb.areaPosition / vSb.stepAreaPosition + rowInd)
                                                   .arg(hSb.areaPosition / hSb.stepAreaPosition + columnInd))
                                            font.pixelSize: 15
                                        }
                                    }
                                }
                            }
                        }
                    }
                    interactive: true
    
                    Binding on contentX {
                        value: {
                            console.log('_flick.contentX', _flick.contentX, hSb.positionInArea)
                            return hSb.positionInArea
                        }
                    }
    
                    Binding on contentY {
                        value: {
                            console.log('_flick.contentY', _flick.contentY, vSb.positionInArea)
                            return vSb.positionInArea
                        }
                    }
                }
                AreaScrollBar {
                    id: vSb
                    orientation: Qt.Vertical
                    stepAreaPosition: mainArea._rectHeight + mainArea._spacing
                    virtualContentSize: mainArea._virtualRows * stepAreaPosition
                    contentSize: mainArea._rows * stepAreaPosition
                    anchors.top: parent.top
                    anchors.right: parent.right
                    anchors.bottom: hSb.top
    
                    Binding on position {
                        value: {
                            console.log('vSb.position', _flick.contentY,
                                        vSb.areaPosition, vSb.virtualContentSize)
                            return (_flick.contentY + vSb.areaPosition) / vSb.virtualContentSize
                        }
                    }
                }
    
                AreaScrollBar {
                    id: hSb
                    orientation: Qt.Horizontal
                    stepAreaPosition: mainArea._rectWidth + mainArea._spacing
                    virtualContentSize: mainArea._virtualColumns * stepAreaPosition
                    visibleSize: mainArea.width
                    anchors.bottom: parent.bottom
                    anchors.left: parent.left
                    anchors.right: vSb.left
                    Binding on position {
                        value: {
                            console.log('hSb.position', _flick.contentX,
                                        hSb.areaPosition, hSb.virtualContentSize)
                            return (_flick.contentX + hSb.areaPosition) / hSb.virtualContentSize
                        }
                    }
                }
            }
        }
    }
    

    performance

    Error when I try to drag the canvas
    error

    1 Reply Last reply
    0

    • Login

    • Login or register to search.
    • First post
      Last post
    0
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Get Qt Extensions
    • Unsolved