Qt 如何使用QML图表的ScrollFT和ScrollRight方法

Qt 如何使用QML图表的ScrollFT和ScrollRight方法,qt,qml,qtquick2,qtcharts,Qt,Qml,Qtquick2,Qtcharts,我需要使用scrollbar滚动QT图,为此,我使用Rectangle和MouseArea创建了自己的自定义scrollbar,可以拖动 当我尝试使用ScrollRight和ScrollLeft方法滚动图表时,我无法将滚动条X与图表视图内容X链接/绑定。下面是代码: import QtQuick 2.6 import QtQuick.Window 2.2 import QtQuick.Controls 2.2 import QtCharts 2.0 Window { id: windo

我需要使用
scrollbar
滚动QT图,为此,我使用
Rectangle
MouseArea
创建了自己的自定义
scrollbar
,可以拖动

当我尝试使用
ScrollRight
ScrollLeft
方法滚动图表时,我无法将
滚动条
X
图表视图
内容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) 如何使用
图表视图
内容
X
映射
滚动条X

2)
滚动条
不应超过X轴的最大值和最小值。怎么做


3) 在
滚动条
图表视图
之间应该有一个同步

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

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
        }
    }
}
首先,当
x
大于
prevX
时,您可以
scrollRight
,这非常有效。但是,对于
x
像素,您可以使用
scrollRight
,这会随着移动而增加,因此移动与滚动条的移动不是线性的

scrollLeft
确实(几乎)从未被调用,这是显而易见的:您不更新
prevX
,因此只有当
x==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"
}
在这里,您需要找到正确的方法来应用映射,从而获得正确的范围

然后,您还可以使用常规组件,如
滑块
来模拟滚动条:

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
    }
}

嗨@derM这两种解决方案都非常有效。如果数据是实时生成的,您能建议如何移动图形吗?。我已经更新了我的问题,请检查。嗯。。。我以后要查一下那个图表。我还没有用过。随着图表的发展,您需要找到最小值和最大值x。。。也许你可以问一个新问题。我现在不知道,但我觉得你的更新超出了一个问题的范围,可能与其他问题无关。ofc。也许真的很简单。我将把它作为一个新问题发布。感谢它为我提供了实时实施的新思路。