0

我需要使用 a 滚动 QT Graph scrollbar,为此,我创建了自己的自定义scrollbar使用RectangleMouseArea并且可以拖动。

当我尝试使用ScrollRightScrollLeft方法滚动图表时,我无法将其ScrollBar XChartView内容 X 链接/绑定。以下是代码:

import QtQuick 2.6
import QtQuick.Window 2.2
import QtQuick.Controls 2.2
import QtCharts 2.0

Window {
    id: window
    width: 640
    height: 480
    visible: true

    ChartView {
        id: chartview
        width: parent.width
        height: 300

        LineSeries {
            name: "LineSeries"
            axisX: ValueAxis {
                min: 0
                max: 100
                tickCount: 12
                labelFormat: "%.0f"
            }

            axisY: ValueAxis {
                min: 0
                max: 70
                tickCount: 5
                labelFormat: "%.0f"
            }
            XYPoint { x: 0; y: 0.0 }
            XYPoint { x: 1.1; y: 3.2 }
            XYPoint { x: 1.9; y: 2.4 }
            XYPoint { x: 2.1; y: 2.1 }
            XYPoint { x: 2.9; y: 2.6 }
            XYPoint { x: 3.4; y: 2.3 }
            XYPoint { x: 200.1; y: 3.1 }
        }
    }

    /* Rectangle base for horizontal scroll bar */
    Rectangle{
        id:rectHorScrollBase
        width:parent.width
        height:parent.height * 0.10
        anchors.top:chartview.bottom
        anchors.topMargin: (parent.height * 0.01)
        color:"transparent"
        visible: true

        /* Rectangle indicating scroll path*/
        Rectangle {
            id:rectHorScrollPath
            width: parent.width
            height: parent.height
            anchors.left:parent.left

            radius: 2
            color: "lightblue"
        }

        /* Actual scroll rectaangle which will be dragged */
        Rectangle {
            id: rectHorScroll
            property var prevX : 0

            anchors.top : parent.top
            width: 50
            height: parent.height
            color: "green"

            /* Mouser area to drag the rectangle and to move Chart */
            MouseArea {
                id:mouseAreaHorScroll

                anchors.fill: parent
                drag.target: parent
                drag.minimumX: 0
                drag.maximumX: chartview.width - width
                drag.axis: Drag.XAxis

                onReleased: {
                    console.log("x in Released ===",rectHorScroll.x)
                    rectHorScroll.prevX = rectHorScroll.x
                }
            }

            onXChanged: {

                // HOW TO HANDLE THE SCROLL BASED ON x ? 
                if(mouseAreaHorScroll.drag.active)
                {
                    if(x > prevX)
                    {
                        chartview.scrollRight(x) // NOT WORKING
                    }
                    else
                    {
                        chartview.scrollLeft(x) //NOT WORKING
                    }
                }
            }
        }
    }
}

1)如何scrollBar XChartView内容映射X

2)scrollbar不应超过 X 轴的最大值和最小值。怎么做?

ScrollBar3)和之间应该有同步ChartView

4

1 回答 1

1

基本上它按预期工作。让我们分析一下你在做什么:

onXChanged: {

    // HOW TO HANDLE THE SCROLL BASED ON x ?
    if(mouseAreaHorScroll.drag.active)
    {
        if(x > prevX)
        {
            chartview.scrollRight(x) // NOT WORKING
        }
        else
        {
            chartview.scrollLeft(x) //NOT WORKING
        }
    }
}

首先,你scrollRightwhenx大于prevX- 完美。但是你scrollRightx像素 - 它随着移动而增长,所以移动与滚动条的移动不是线性的。

scrollLeft确实(几乎)从未调用过,这很明显:只有prevXx === 0 ( = prevX)scrollLeft(0)- 它不移动时,您才不会更新。

我们需要应用的第一个更改是prevX在处理程序结束时进行更新。
第二个变化是,我们只想移动自上次运行代码以来移动手柄的距离。

因此,解决方案如下所示:

onXChanged: {

    // HOW TO HANDLE THE SCROLL BASED ON x ?
    if(mouseAreaHorScroll.drag.active)
    {
        if(x > prevX)
        {
            chartview.scrollRight(x - prevX) // Only move the difference
        }
        else
        {
            chartview.scrollLeft(prevX - x) //Only move the difference
        }
        prevX = x // Update prevX
    }
}

除了手动处理这些东西并调用这些函数,您还可以将轴的可见部分映射到 x - 为此删除您的句柄并相应地更改axisX:

axisX: ValueAxis {
    min: rectHorScroll.x / (rectHorScrollBase.width - rectHorScroll.width) * 100
    max: rectHorScroll.x / (rectHorScrollBase.width - rectHorScroll.width) * 100 + 100
    tickCount: 12
    labelFormat: "%.0f"
}

在这里,您需要找到应用映射的正确方法,以获得正确的范围。

然后你也可以使用常规组件,比如 aSlider来模拟滚动条:

import QtQuick 2.6
import QtQuick.Window 2.2
import QtQuick.Controls 2.0
import QtCharts 2.0

ApplicationWindow {
    id: window
    width: 640
    height: 480
    visible: true

    ChartView {
        id: chartview
        width: parent.width
        height: 300

        LineSeries {
            name: "LineSeries"
            axisX: ValueAxis {
                property real minValue: 0
                property real maxValue: 200
                property real range: 100
                min: minValue + sb.position * (maxValue - minValue - range)
                max: minValue + sb.position * (maxValue - minValue - range) + range
                tickCount: 12
                labelFormat: "%.0f"
            }

            axisY: ValueAxis {
                min: 0
                max: 70
                tickCount: 5
                labelFormat: "%.0f"
            }
            XYPoint { x: 0; y: 0.0 }
            XYPoint { x: 1.1; y: 3.2 }
            XYPoint { x: 1.9; y: 2.4 }
            XYPoint { x: 2.1; y: 2.1 }
            XYPoint { x: 2.9; y: 2.6 }
            XYPoint { x: 3.4; y: 2.3 }
            XYPoint { x: 200.1; y: 3.1 }
        }


    }

    Slider {
        id: sb
        anchors {
            bottom: parent.bottom
            left: parent.left
            right: parent.right
        }
        height: 30
    }
}
于 2017-10-26T11:52:42.200 回答