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. Why my scrollbars are not updating their total scroll size when content size changes?
QtWS25 Last Chance

Why my scrollbars are not updating their total scroll size when content size changes?

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
zoomscrollscroll barsizepage
2 Posts 2 Posters 847 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.
  • J Offline
    J Offline
    jeanmilost
    wrote on 25 Nov 2021, 19:03 last edited by
    #1

    I'm trying to create a view, representing an a4 page which may be scrolled, and in which the user may zoom in or out.

    I created a prototype for a such view, available in the below code:

    import QtQuick 2.15
    import QtQuick.Controls 2.15
    import QtQuick.Window 2.15
    import QtQuick.Shapes 1.15
    
    ApplicationWindow
    {
        // advanced properties
        property int m_PageWidth:  794//2480
        property int m_PageHeight: 1123//3508
    
        // common properties
        id:           ctPageView
        objectName:   "ctPageView"
        visible: true
        width: 800
        height: 600
    
        /**
        * Page viewport
        */
        Rectangle
        {
            // common properties
            id: rcPageViewport
            objectName: "rcPageViewport"
            anchors.fill: parent
            clip: true
    
            /**
            * Page mouse area
            */
            MouseArea
            {
                // advanced properties
                property var  m_Target:      parent
                property int  m_PrevX:       0
                property int  m_PrevY:       0
                property real m_ScaleFactor: 1
                property bool m_Panning:     false
    
                // common properties
                id: maPage
                objectName: "maPage"
                anchors.fill: parent
                hoverEnabled: true
    
                /// called when mouse wheel was rolled above page
                onWheel: function(mouseWheel)
                {
                    if (mouseWheel.modifiers & Qt.ControlModifier)
                    {
                        let offset     = mouseWheel.angleDelta.y * 0.001;
                        m_ScaleFactor += offset;
    
                        //rcPageContent.pageScaleChanged(m_ScaleFactor);
                        return;
                    }
    
                    mouseWheel.accepted = true;
                }
            }
    
            Rectangle
            {
                id: rcPageContainer
                objectName: "rcPageContainer"
                x: (rcPageViewport.width  < width)  ? -sbHorz.position * width  : 0
                y: (rcPageViewport.height < height) ? -sbVert.position * height : 0
                width: m_PageWidth * maPage.m_ScaleFactor
                height: m_PageHeight * maPage.m_ScaleFactor
                transform: Scale
                {
                    origin.x: 0
                    origin.y: 0
                    xScale: maPage.m_ScaleFactor
                    yScale: maPage.m_ScaleFactor
                }
    
                Rectangle
                {
                    x: 0
                    y: 0
                    width: 100
                    height: 80
                    color: "red"
                }
                Rectangle
                {
                    x: m_PageWidth - width
                    y: 0
                    width: 100
                    height: 80
                    color: "green"
                }
                Rectangle
                {
                    x: 0
                    y: m_PageHeight - height
                    width: 100
                    height: 80
                    color: "blue"
                }
                Rectangle
                {
                    x: m_PageWidth - width
                    y: m_PageHeight - height
                    width: 100
                    height: 80
                    color: "yellow"
                }
            }
    
            /**
            * Horizontal scrollbar
            */
            ScrollBar
            {
                // common properties
                id: sbHorz
                hoverEnabled: true
                active: hovered || pressed
                orientation: Qt.Horizontal
                size: rcPageViewport.width / rcPageContainer.width
                anchors.left: parent.left
                anchors.right: parent.right
                anchors.bottom: parent.bottom
                anchors.rightMargin: sbVert.width
            }
    
            /**
            * Vertical scrollbar
            */
            ScrollBar
            {
                // common properties
                id: sbVert
                hoverEnabled: true
                active: hovered || pressed
                orientation: Qt.Vertical
                size: rcPageViewport.height / rcPageContainer.height
                anchors.top: parent.top
                anchors.right: parent.right
                anchors.bottom: parent.bottom
                anchors.bottomMargin: sbHorz.height
            }
    
            /// called when page viewport width changed
            onWidthChanged:
            {
                sbHorz.size     = rcPageViewport.width / rcPageContainer.width
                sbHorz.position = Math.min(Math.max(sbHorz.position, 0.0), 1.0 - (sbHorz.size));
            }
    
            /// called when page viewport height changed
            onHeightChanged:
            {
                sbVert.size     = rcPageViewport.height / rcPageContainer.height
                sbVert.position = Math.min(Math.max(sbVert.position, 0.0), 1.0 - (sbVert.size));
            }
        }
    }
    

    With this code, I can scroll the page, as well as zoom in or out when I roll the mouse wheel. However, every time I change the zoom level, the scroll size is not updated, despite of all my efforts to update the page content size.

    To zoom the page, I use the transform property of my Rectangle component, and I know that this property doesn't affect the width and height of the rectangle. However I also explicitly change the page content width and height, but despite of that, the scrollbars doesn't update the scroll total size.

    I also tried to use a Flickable view, in order to let Qt take care of he scrollbars, however a such component interfere strongly with my MouseArea, and I need it to perform very important operations that I cannot do without (not joined in the above sample code). For that reason I don't want to use a Flickable here.

    What I'm I doing wrong in the above code, and how should I modify it to keep my scroll size up to date while I change the zoom level? Or what is the correct way to implement a zoom onto a scrollable view in qml?

    1 Reply Last reply
    0
    • A Offline
      A Offline
      arun-holoplot
      wrote on 29 Nov 2021, 13:19 last edited by
      #2

      @jeanmilost
      Your logic seems to be correct.
      What you have to do is to move the re-calculation of Scrollbar size & position to the Rectangle rcPageContainer because you are applying scale for that.

              Rectangle
               {
                id: rcPageContainer
                objectName: "rcPageContainer"
                ...
              /// called when page viewport width changed
              onWidthChanged:
              {
                  sbHorz.size     = rcPageViewport.width / rcPageContainer.width
                  sbHorz.position = Math.min(Math.max(sbHorz.position, 0.0), 1.0 - (sbHorz.size));
              }
      
              /// called when page viewport height changed
              onHeightChanged:
              {
                  sbVert.size     = rcPageViewport.height / rcPageContainer.height
                  sbVert.position = Math.min(Math.max(sbVert.position, 0.0), 1.0 - (sbVert.size));
              }
      }
      1 Reply Last reply
      0

      2/2

      29 Nov 2021, 13:19

      • Login

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