我有一个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
之外使用此代码时,文本将向右下移,直到用户选择为止:
答案 0 :(得分:2)
将height
中的Flickable
设置为contentHeight
或300
-以较小者为准:
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 {}
}
}
如果您不希望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
属性。>