如何手动滚动ScrollView的TextArea(Qt Quick)?

时间:2014-05-29 12:24:34

标签: qt scrollview qt-quick qtquickcontrols

如果我有TextAreaScrollView,我该如何手动设置滚动位置,理想情况下也会对其做出反应。

这是为了创建一个日志窗口 - 我想要它,这样如果我追加文本并且视图先前已滚动到底部,那么它会再次滚动到那里。

2 个答案:

答案 0 :(得分:3)

你走了:

import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Window 2.0

ApplicationWindow {
    id: app
    title: qsTr("Hello World")
    width: 640
    height: 480

    function getTextLine(i) {
        var textLines = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
        Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
        Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.
        Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.
        Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis.
        At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.
        Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus.
        Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
        Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
        Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.".split("\n");
        return textLines[i].trim();
    }

    Timer {
        property int i: 0
        running: true
        interval: 1000
        repeat: true
        onTriggered: {
            if (i < 10) {
                txt.text = txt.text.toString() + "\n\n" + getTextLine(i)
            }
            i += 1
        }
    }

    ScrollView {
        id: sv
        width: 600
        height: 300
        frameVisible: true

        Flickable {
            id: flickable
            anchors.fill: parent
            contentY: 50
            flickableDirection: Flickable.VerticalFlick
            contentHeight: txt.height
            Component.onCompleted: {
                console.log("Content height:", contentHeight)
                console.log("Height:", height)
                console.log("Implicit Height:", implicitHeight)
                console.log("Content Y:", contentY)
            }

            onContentYChanged: {
                console.log("Content Y:", contentY)
            }

            TextEdit {
                id: txt
                height: contentHeight
                width: 600-30
                wrapMode: TextEdit.Wrap
                onTextChanged: {
                    flickable.contentY = contentHeight - flickable.height
                }
                text: ""
            }
        }
    }
}

答案 1 :(得分:2)

这是我基于Simon Warta的日志窗口的解决方案。它工作得很好,并且大部分都以标准方式运行 - 如果你滚动到底部,它将跟随输出;如果你从那里滚动它停止跟随。这实际上是用Java显然无法做到的事情! (至少Eclipse和IntelliJ做得不对。)

不幸的是,TextEdit中存在一个奇怪的错误,如果您删除文本然后附加一些错误,则会使其无法正确更新。如果有人对此有任何想法,那么最好知道。否则我发现选择了所有文本,然后立即取消选择它的工作原理。可悲的是,这使得无法从窗口复制文本。

无论如何,这是我的代码。

import QtQuick 2.0
import QtQuick.Controls 1.2

ApplicationWindow {

    width: 500
    height: 300

    Timer {
        property int i: 0
        running: true
        interval: 250
        repeat: true
        onTriggered: {
            i += 1;
            root.appendLine(new Array(30).join(i + "_"));
            if (i === 100)
                root.clear();
        }
    }

    ScrollView {
        id: root
        anchors.fill: parent
        frameVisible: true

        property int maxLines: 50

        function appendLine(line)
        {
            // If we are scrolled near the end (up to 30 pixels away)
            // then scroll right to the end.
            var following = flickable.contentY > text.height - flickable.height - 30;

            line = String(line);
            text.lineLengths.push(line.length);
            if (text.lineLengths.length > maxLines)
                text.remove(0, text.lineLengths.shift()+1); // Plus 1 for new line.
            text.append(line);

            // These line work around a weird bug where it doesn't update the view.
            text.selectAll();
            text.deselect();

            if (following && text.height > flickable.height)
                flickable.contentY = text.height - flickable.height;
        }

        function clear()
        {
            text.text = "";
            text.lineLengths = [];
            flickable.contentY = 0;
        }

        Flickable {
            id: flickable
            anchors.fill: parent

            flickableDirection: Flickable.VerticalFlick
            contentHeight: text.height

            TextEdit {
                id: text

                // We have to store the length of each line because TextEdit
                // doesn't provide any *fast* ways to calculate it (accessing `text`
                // is extremely slow since it copies everything to/from javascript).
                property var lineLengths: []

                width: root.width - 30 // Space for scroll bar.
                wrapMode: TextEdit.Wrap

                text: ""
            }
        }
    }
}