简体   繁体   English

记住QML元素中的滚动位置

[英]Remember scroll position in QML element

I have some qml that acts as the output from the application (kind of like a read-only console). 我有一些qml充当应用程序的输出(有点像只读控制台)。 However, it's annoying to use because as it prints information it scrolls back to the top. 然而,使用它很烦人,因为它打印信息时会滚动回顶部。

For example, lets say I print a line to my TextArea every second, after a minute or so, I'll have enough lines that I now have a scroll bar. 例如,假设我每秒都会在TextArea打印一行, TextArea一分钟后,我会有足够的行,我现在有一个滚动条。 I scroll to the bottom, a second later, a line of text is printed causing it to scroll back to the top. 我滚动到底部,一秒钟之后,打印出一行文本,使其滚动回到顶部。

The desired functionality I would like is to automatically scroll to the bottom (much like how a console is when it prints stuff out) unless the user overrides this by scrolling up, then the text should stay put. 我想要的功能是自动滚动到底部(就像控制台打印出来的时候一样),除非用户通过向上滚动覆盖它,然后文本应保持不变。 I hope that made sense, here is some code: 我希望这是有道理的,这里有一些代码:

        ScrollArea {
            id: helpTextScrollArea
            anchors.left: parent.left
            anchors.right: parent.right
            anchors.top: myButton.bottom
            anchors.topMargin: 5
            anchors.bottom: parent.bottom
            visible: false
            horizontalScrollBar.visible: false

            onVisibleChanged: {
                helpText.visible = visible
            }

            HelpTextArea {
                id: helpText
                width: parent.parent.width - helpTextScrollArea.verticalScrollBar.width
                text: "Oops, no documentation."

                onVisibleChanged: {
                    if(helpTextScrollArea.visible != visible) {
                        helpTextScrollArea.visible = visible
                    }
                }
            }
        }

        Flickable
        {
            id: flick

            anchors.left: parent.left
            anchors.right: parent.right
            anchors.top: runStopButton.bottom
            anchors.bottom: parent.bottom
            anchors.topMargin: 5


            TextArea{

                id: messageArea
                anchors.fill: parent

                focus: true

                readOnly: true

                visible: !helpTextScrollArea.visible

                wrapMode: TextEdit.Wrap

                function addText(newText) {
                    text += newText + "\n"
                }
            }
        }

Note: I don't think my Flickable does anything, it was part of my experimenting to fix the problem. 注意:我认为我的Flickable没有做任何事情,这是我尝试修复问题的一部分。 Also, I use the function addText to print to the text area. 另外,我使用addText函数打印到文本区域。 I hardly know anything about qml and most of this code was written by someone else and I'm trying to work with it. 我对qml几乎一无所知,大部分代码都是由其他人编写的,我正在尝试使用它。 Thank you! 谢谢!

You can bind contentY property of Flickable to an expression that will calculate proper position. 您可以将Flickable contentY属性绑定到将计算正确位置的表达式。

Flickable {
    id: flick
    states: State {
        name: "autoscroll"
        PropertyChanges {
            target: flick
            contentY: messageArea.height - height
        }
    }
    onMovementEnded: {
        if (contentY === messageArea.height - height) {
            state = "autoscroll"
        }
        else {
            state = ""  // default state
        }
    }
    // ...
}

Flickable has got 4 readonly properties in called visibleArea.* (you can read their meaning in the QML documentation) : Flickable在visibleArea中有4个只读属性。*(你可以在QML文档中读到它们的含义):

  • visibleArea.xPosition : xPosition = contentX / contentWidth visibleArea.xPosition :xPosition = contentX / contentWidth
  • visibleArea.yPosition : yPosition = contentY / contentHeight visibleArea.yPosition :yPosition = contentY / contentHeight
  • visibleArea.widthRatio : widthRatio = width / contentWidth visibleArea.widthRatio :widthRatio = width / contentWidth
  • visibleArea.heightRatio : heightRatio = height / contentHeight visibleArea.heightRatio :heightRatio = height / contentHeight

If you are using GridView instead of Flickable, you can use these methods. 如果您使用的是GridView而不是Flickable,则可以使用这些方法。

positionViewAtBeginning()

positionViewAtEnd()

positionViewAtIndex(int index, PositionMode mode)

I found these to be really helpful, as when the line of text is being added, just call the positionViewAtEnd() method inside of the GridView . 我发现这些非常有用,因为在添加文本行时,只需调用GridView中positionViewAtEnd()方法即可。

Hope it helps 希望能帮助到你

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM