QML TextArea:使用 QtQuick.Controls > 2.0 与 1.4 时的不同行为
QML TextArea: different behavior when using QtQuick.Controls > 2.0 vs 1.4
我是 Qml 的新手,但我想尝试一下,看看是否值得使用它来代替旧的 Qt Widgets,尤其是因为我听说它更适合移动设备。我将 Qml 用于 GUI,同时将几个 C++ classes 用于核心逻辑。
我需要一个可滚动的 TextArea,就像在文本编辑器中一样,所以我发现我必须使用嵌套在 ScrollView 中的 TextArea,如下所示:
ScrollView {
...
TextArea {
...
}
}
我喜欢我的深色 QML 应用程序的结果,在我的深色背景上有一个漂亮的文本编辑器和漂亮的滚动条。
当我需要在代码中实现 scrollTo 函数时,问题出现了。我的应用程序是一种播放器,它会突出显示文本并在达到 1/4 高度时向下滚动。我发现我可以使用 flickableItem.contentY 属性 来调整文本在我的 ScrollView 中的相对位置,但是 属性 不存在即使其他答案也提到了它。
我找到了 Qt 文档,但没有任何迹象,只有一个 contentItem 属性。所以我尝试调整 contentItem.y 属性 但结果很糟糕。文本和整个背景都在平移,覆盖了我的顶部工具栏。
所以我在文档中搜索了 TextArea 的其他实现,发现 QtQuick.Controls 1.4 有一个继承了 ScrollView class 的 TextArea 实现。这就是解决方案,我想。我切换到旧的实现并设法使整个事情正常进行。现在我可以通过 flickableItem.contentY 属性 和 contentHeight 与 height 以编程方式滚动我的 TextArea 计算我有多少空间的属性。
这里的问题是 1.4 版本的滚动条看起来很难看,我觉得使用旧版本有点像 hack。他们从 ScrollView 中删除 flickableItem 属性 是有原因的吗?有没有其他方法可以对新的控件版本做同样的事情?
这是我的代码:
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.
来测试它
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
}
}
}
}
}
}
运行 长文本对我来说是这样的输出示例:
qml: scrollVar: 0.15625
qml: scrollVar: 0.35625
qml: scrollVar: 0.55625
qml: scrollVar: 0.7562500000000001
qml: scrollVar: 0.95625
qml: scrollVar: 1
我是 Qml 的新手,但我想尝试一下,看看是否值得使用它来代替旧的 Qt Widgets,尤其是因为我听说它更适合移动设备。我将 Qml 用于 GUI,同时将几个 C++ classes 用于核心逻辑。 我需要一个可滚动的 TextArea,就像在文本编辑器中一样,所以我发现我必须使用嵌套在 ScrollView 中的 TextArea,如下所示:
ScrollView {
...
TextArea {
...
}
}
我喜欢我的深色 QML 应用程序的结果,在我的深色背景上有一个漂亮的文本编辑器和漂亮的滚动条。
当我需要在代码中实现 scrollTo 函数时,问题出现了。我的应用程序是一种播放器,它会突出显示文本并在达到 1/4 高度时向下滚动。我发现我可以使用 flickableItem.contentY 属性 来调整文本在我的 ScrollView 中的相对位置,但是 属性 不存在即使其他答案也提到了它。
我找到了 Qt 文档,但没有任何迹象,只有一个 contentItem 属性。所以我尝试调整 contentItem.y 属性 但结果很糟糕。文本和整个背景都在平移,覆盖了我的顶部工具栏。
所以我在文档中搜索了 TextArea 的其他实现,发现 QtQuick.Controls 1.4 有一个继承了 ScrollView class 的 TextArea 实现。这就是解决方案,我想。我切换到旧的实现并设法使整个事情正常进行。现在我可以通过 flickableItem.contentY 属性 和 contentHeight 与 height 以编程方式滚动我的 TextArea 计算我有多少空间的属性。
这里的问题是 1.4 版本的滚动条看起来很难看,我觉得使用旧版本有点像 hack。他们从 ScrollView 中删除 flickableItem 属性 是有原因的吗?有没有其他方法可以对新的控件版本做同样的事情?
这是我的代码:
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.
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
}
}
}
}
}
}
运行 长文本对我来说是这样的输出示例:
qml: scrollVar: 0.15625
qml: scrollVar: 0.35625
qml: scrollVar: 0.55625
qml: scrollVar: 0.7562500000000001
qml: scrollVar: 0.95625
qml: scrollVar: 1