关于qt:QML TextArea:使用QtQuick.Controls> 2.0 vs 1.4时的行为不同

QML TextArea: different behavior when using QtQuick.Controls > 2.0 vs 1.4

我是Qml的新手,但是我想尝试一下它,看看是否值得代替旧的Qt Widgets使用,尤其是因为我听说它对移动设备更好。我将Qml用于GUI以及几个C ++类用于核心逻辑。
我需要一个可滚动的TextArea,就像在文本编辑器中一样,所以我发现必须使用嵌套在ScrollView中的TextArea,如下所示:

1
2
3
4
5
6
ScrollView {
    ...
    TextArea {
        ...
    }
}

我喜欢深色QML应用程序中的结果,它在深色背景上带有漂亮的文本编辑器和漂亮的滚动条。

当我需要在代码中实现scrollTo函数时,就会出现问题。我的应用程序是一种播放器,可突出显示文本并在达到高度的1/4时向下滚动。我发现我可以使用flickableItem.contentY属性来调整文本在ScrollView中的相对位置,但是即使其他答案引用了该属性,该属性也不存在。

我到达了Qt文档,没有任何迹象,只有contentItem属性。所以我试图调整contentItem.y属性,但是结果很糟糕。文本和整个背景都在平移,覆盖了我的顶部工具栏。

因此,我在文档中搜索了TextArea的其他实现,并发现QtQuick.Controls 1.4具有继承了ScrollView类的TextArea实现。我想这就是解决方案。我改用较旧的实现,并设法使整个工作正常进行。现在,我可以通过flickableItem.contentY属性以及contentHeight与height属性以编程方式滚动TextArea,以计算出我有多少房间。

这里的问题是1.4版本的滚动条看起来很丑陋,我觉得使用旧版本的滚动条有点不合时宜。他们为什么要从ScrollView中删除flickableItem属性?有没有其他方法可以对新的控件版本执行相同的操作?

这是我的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import QtQuick 2.12
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.12

TextArea {
    id: textArea

    anchors.fill: parent
    backgroundVisible: false

    /*background: Rectangle {
        anchors.fill: parent
        color:"#000000"
    }*/

    //color:"#ffffff"

    textColor:"#ffffff"
    selectByKeyboard: true
    selectByMouse: true
    verticalScrollBarPolicy: Qt.ScrollBarAlwaysOn

    function scrollToY(y) {
        if ((contentHeight-y) > flickableItem.height && y > flickableItem.height/4) {
            flickableItem.contentY = y - flickableItem.height/4
        }
    }
}


我不知道Qt Quick Controls 1和Qt Quick Controls 2之间实现更改背后的原因。但是,Qt Quick Controls 2中的ScrollView可以通过编程方式滚动到ScrollBar.vertical.position。 我编写了一个示例代码,该代码使用计时器来移动内容,直到计时器停止滚动为止。 请注意,如果内容适合可见区域,则会禁用滚动条,并且不会启动计时器,因为不需要移动内容。 您可以通过将布尔useLongText值更改为false来进行测试。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import QtQuick.Window 2.2
import QtQuick 2.9
import QtQuick.Controls 2.2

Window {
    visible: true
    width: 400
    height: 400
    color:"blue"
    property string exampleTextShort:"Lorem Ipsum is simply dummy text of the printing and typesetting industry."

    property string exampleTextLong:"Lorem Ipsum is simply dummy text of the printing and typesetting industry.

Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.

It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged.

It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
"

    property bool useLongText: true // Change this to test with short text too

    Timer {
        id: timer
        running: scrollView.wholeTextSeen ? false : true
        repeat: true
        interval: 2000
        onTriggered: {
            scrollView.scrollDown()
        }
    }

    Rectangle{
        id: rect
        anchors.centerIn: parent
        width: parent.width*0.2;
        height: parent.height*0.2;
        ScrollView {
            id: scrollView
            anchors.fill: parent
            clip: true
            property bool wholeTextSeen: ScrollBar.vertical.size >= 1 ? true : false
            ScrollBar.vertical.policy: ScrollBar.vertical.size >= 1 ? ScrollBar.AlwaysOff : ScrollBar.AlwaysOn
            TextArea {
                readOnly: true
                text: useLongText ? exampleTextLong : exampleTextShort
                wrapMode: Text.WordWrap
            }

            function scrollDown() {
                if (wholeTextSeen) {
                    timer.running = false
                } else {
                    var scrollVar = ScrollBar.vertical.position + ScrollBar.vertical.size
                    console.log("scrollVar:",scrollVar)
                    if (scrollVar >= 1) {
                        wholeTextSeen = true
                    } else {
                        var step = 0.2
                        step = scrollVar + step > 1 ? 1 - scrollVar : step
                        ScrollBar.vertical.position = ScrollBar.vertical.position + step
                    }
                }
            }
        }
    }
}

运行长文本时的示例输出对我来说是这样的:

1
2
3
4
5
6
qml: scrollVar: 0.15625
qml: scrollVar: 0.35625
qml: scrollVar: 0.55625
qml: scrollVar: 0.7562500000000001
qml: scrollVar: 0.95625
qml: scrollVar: 1