如何使TextArea具有最大大小和滚动条?

时间:2019-02-04 20:54:27

标签: qt qml qtquick2 qtquickcontrols2

我有一个TextArea,通常只包含大约一行文本。但是,我确实希望用户能够添加更多内容,并使TextArea最多扩展到大约15行,这时可以通过滚动条访问任何其他文本。通过将TextArea包含在Flickable(最终包含在Rectangle中)中,我已经能够使滚动方面起作用。

Rectangle {
    id: rec
    width: 200
    height: 25

    Flickable {
        id: flickable
        anchors.fill: parent
        contentWidth: textArea.width
        contentHeight: textArea.height

        TextArea.flickable:
            TextArea {
            id: textArea
            text: qsTr("Hello, world!")
            wrapMode: Text.WordWrap
        }
        ScrollBar.vertical: ScrollBar { }
    }
}

在这一点上,我将如何使文本框随文本扩展,直到达到一些预定义的最大像素数(例如300)?

修改

好的,几乎在那里,使用Mitch解决方案使文本正确居中只是一个问题。我的main.qml文件包含以下内容:

import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    HelloWorld{
        anchors.centerIn: parent
    }
}

我的HelloWorld.qml文件中都包含以下内容:

import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
import QtQuick.Dialogs 1.2
import QtQuick.Controls.Styles 1.4

ColumnLayout{

    width: 250

    FontMetrics {
        id: fontMetrics
        font: textArea.font
    }

    Flickable {
        id: flickable
        width: parent.width
        height: Math.min(contentHeight, fontMetrics.height * 15)
        contentWidth: width
        contentHeight: textArea.implicitHeight
        clip: true

        TextArea.flickable: TextArea {
            id: textArea
            text: "Hello, world! Hello, world! Hello, world! Hello, world! Hello, world! Hello, world! "
                + "Hello, world! Hello, world! Hello, world! Hello, world! Hello, world! Hello, world! "
            wrapMode: Text.WordWrap
            //padding: 0

            background: Rectangle {
                border.color: "blue"
            }
        }
        ScrollBar.vertical: ScrollBar {}
    }

}

这非常接近工作,但是由于某种原因,当我在main.qml之外使用此代码时,文本将向右下移,直到用户选择为止:

enter image description here

选择文本后,它看起来像这样(这是我希望从其开始的内容): enter image description here

2 个答案:

答案 0 :(得分:2)

height中的Flickable设置为contentHeight300-以较小者为准:

import QtQuick 2.12
import QtQuick.Controls 2.12

ApplicationWindow {
    width: 400
    height: 400
    color: "#444"
    visible: true

    Rectangle {
        anchors.fill: flickable
    }

    Flickable {
        id: flickable
        width: parent.width
        height: Math.min(contentHeight, 300)
        contentWidth: width
        contentHeight: textArea.implicitHeight

        TextArea.flickable: TextArea {
            id: textArea
            text: qsTr("Hello, world! Hello, world! Hello, world! Hello, world! ")
            wrapMode: Text.WordWrap
        }
        ScrollBar.vertical: ScrollBar {}
    }
}

textarea

如果您不希望Rectangle在它的位置(Flickable的兄弟姐妹),则可以将其删除,然后添加

clip: true

Flickable

background: Rectangle {}

TextArea

此外,如果您想更精确一点,可以使用FontMetrics来计算行高:

import QtQuick 2.12
import QtQuick.Controls 2.12

ApplicationWindow {
    width: 400
    height: 400
    color: "#444"
    visible: true

    FontMetrics {
        id: fontMetrics
        font: textArea.font
    }

    Flickable {
        id: flickable
        width: parent.width
        height: Math.min(contentHeight, fontMetrics.height * 15)
        contentWidth: width
        contentHeight: textArea.implicitHeight
        clip: true

        TextArea.flickable: TextArea {
            id: textArea
            text: "Hello, world! Hello, world! Hello, world! Hello, world! Hello, world! Hello, world! "
                + "Hello, world! Hello, world! Hello, world! Hello, world! Hello, world! Hello, world! "
            wrapMode: Text.WordWrap
            padding: 0

            background: Rectangle {}
        }
        ScrollBar.vertical: ScrollBar {}
    }
}

答案 1 :(得分:1)

啊哈!经过大量搜索之后,我终于找到了一个方便的属性paintedHeight,它是TextArea的一部分。这将获取您TextArea中文本的高度,因此我用它来发现每行的大小为13,并且只要编辑了文本,就只需更新基础Rectangle的高度,并且只需使用if语句将其设置为上限即可。这是我古怪的解决方案:

Rectangle {
    property int paintedHeight: 13
    id: rec
    width: 200
    height: paintedHeight * 2

    Flickable {
        id: flickable
        anchors.fill: parent
        contentWidth: textArea.width
        contentHeight: textArea.height

        TextArea.flickable:
            TextArea {
            id: textArea
            wrapMode: Text.WordWrap

            property int maxNumberOfLines: 15
            onTextChanged: {
                rec.height = (lineCount * rec.paintedHeight) + rec.paintedHeight

                // cap the height so that the box stops expanding at maxNumberOfLines
                if(rec.height > rec.paintedHeight * (maxNumberOfLines + 1)){
                    rec.height = rec.paintedHeight * (maxNumberOfLines + 1)
                }
            }
        }
        ScrollBar.vertical: ScrollBar { }
    }
}

万一其他人发现自己处于类似情况,只需执行console.log(paintedHeight)即可获取当前文本的高度(如果一行多行,则进行相应的除法)即可获取文本的高度,如下所示:根据您使用的样式和字体(我使用的是Fusion样式),它可能与我的有所不同。然后只需使用您的大小修改paintedHeight中的Rectangle属性,并使用您希望文本具有的最大行数来修改maxNumberOfLines中的TextArea属性。