我正在Windows 10专业计算机上使用Qt 5.13.0开发应用程序。我需要创建一个类似于消息视图的Whatsapp,为实现这一点,我使用了GridView组件作为基础。但是,为了正确绘制消息,我需要根据消息文本创建具有不同高度的每个GridView行。
但是令我惊讶的是,尽管我认为这是一个简单的手续,但我在互联网上找不到任何解决方案。我自己尝试了一个解决方案,下面附上了它,但是它不起作用。问题在于,所有行都采用最后一个调整大小的行的高度。
我毫不怀疑Qt可以做到这一点,不幸的是,我已经寻找了好几天,而我找不到解决该问题的方法。我根本不知道如何实现这一目标。因此,有人可以向我解释如何创建具有可变高度的行的GridView,或者如果GridWiew不是执行此操作的适当组件,我应该使用它代替吗?
这是我的qss文件:
import QtQuick 2.12
import QtQuick.Controls 2.5
import QtQuick.Window 2.12
import QtQuick.Layouts 1.11
Window
{
visible: true
width: 640
height: 480
title: qsTr("Grid view")
color: "#ffffff"
ColumnLayout
{
transformOrigin: Item.Center
spacing: 0
x: 0
y: 0
width: parent.width
height: parent.height
/**
* Grid view item
*/
Component
{
id: itGridItem
Item
{
Column
{
Rectangle
{
property int messageWidth: (gvMessageGrid.cellWidth / 2) - 50
id: itemRect
x: senderIsMyself ? 25 : gvMessageGrid.cellWidth - (25 + messageWidth)
y: 5
width: messageWidth
height: itemTextID.height + 20
color: senderIsMyself ? "#d5d5d5" : "#800b940e"
radius: 5
clip: true
Text
{
id: itemTextID
width: parent.width - 20
text: itemText
renderType: Text.NativeRendering
textFormat: TextEdit.RichText
wrapMode: Text.WordWrap
font.family: "Segoe UI Emoji"
font.pixelSize: 18
anchors.margins: 10
anchors.left: parent.left
anchors.top: parent.top
color: "#101010"
}
onHeightChanged: gvMessageGrid.cellHeight = height + 10
}
}
}
}
/**
* Messages grid view
*/
GridView
{
id: gvMessageGrid
y: 0
Layout.fillHeight: true
flickableDirection: Flickable.VerticalFlick
Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
clip: true
contentWidth: 700
contentHeight: 300
cellWidth: contentWidth
cellHeight: 150
model: lmGridModel
delegate: itGridItem
ScrollBar.vertical: ScrollBar
{
visible: true
}
onWidthChanged: cellWidth = width
}
}
}
---于2019年10月18日编辑
在下面的eyllanesc建议之后,以下是我想要和得到的两个屏幕截图:
我想要的
我会得到什么
注意,出于测试目的,我正在使用多种语言,因为我的应用程序必须具有国际支持。但是,我遇到的问题与此无关,即,它不是文本计算错误,因为1.文本周围的绿色矩形大小始终正确,并且2.我遇到的是纯英文文本。 / p>
答案 0 :(得分:1)
我建议您使用ListView而不是GridView。您可以轻松查看全角列表项中的所有内容。让我与您分享旧项目中的ListDelegate
类。注意在锚定绑定中使用isIncoming
属性,例如:
anchors {
left: isIncoming? undefined : parent.left
right: isIncoming? parent.right : undefined
}
完整列表:
import QtQuick 2.5
import "units.js" as Units
Rectangle {
id: chatMsgDelegRoot
property bool isIncoming: !model.out
property bool isSelected: model.isSelected
signal clicked(int index)
width: parent.width
height: dlgColumn.height + Units.gu(2.5)
color: "#edf1f5"
Column {
id: dlgColumn
spacing: Units.gu(4)
width: parent.width
anchors.verticalCenter: parent.verticalCenter
BorderImage {
id: borderImage
source: isIncoming?
(isSelected ? "/images/img/MsgOut_Selected_2.png" : "/images/img/MsgOut_2.png") :
(isSelected ? "/images/img/MsgIn_Selected_2.png" : "/images/img/MsgIn_2.png")
// Texture-dependent.
border {
left: isIncoming? 20 : 30
top: 20
right: isIncoming? 30 : 20
bottom: 35
}
anchors {
left: isIncoming? undefined : parent.left
right: isIncoming? parent.right : undefined
}
width: Math.max(content.width + Units.gu(15), Units.gu(21))
height: content.height + Units.gu(9)
MouseArea {
id: msgDelegateMa
anchors.fill: parent
onClicked: chatMsgDelegRoot.clicked(model.index)
}
Loader {
id: content
sourceComponent: model.type === "Text" ? textComponent : controlComponent
anchors {
left: isIncoming? undefined : parent.left
right: isIncoming? parent.right : undefined
leftMargin: Units.gu(10)
rightMargin: Units.gu(10)
top: parent.top
topMargin: Units.gu(4)
}
}
Text {
text: model.date.toTimeString()
font.pointSize: 8
font.italic: true;
color: "lightgrey"
anchors {
left: isIncoming? undefined : parent.left
right: isIncoming? parent.right : undefined
rightMargin: Units.gu(7.5)
leftMargin: Units.gu(7.5)
bottom: parent.bottom
bottomMargin: Units.gu(1)
}
}
} // BorderImage
} // Column
// TODO To separate files.
Component {
id: textComponent
Rectangle {
id: textComponentRoot
color: "#00000000"
width: msgText.paintedWidth
height: msgText.height
Text {
id: msgText
font.pointSize: 10
textFormat: Text.RichText
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
width: chatMsgDelegRoot.width * 0.7
text: model.body
color: isSelected? "white" : "black"
}
}
} // Component
Component {
id: controlComponent
Rectangle {
id: textComponentRoot
color: "#00000000"
width: innerColumn.width
height: innerColumn.height
Column {
id: innerColumn
spacing: Units.gu(1)
Text {
id: fileNameText
font.pointSize: 10
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
width: chatMsgDelegRoot.width * 0.7
elide: Text.ElideRight
text: "File transfer: " + model.body
color: isSelected? "white" : "black"
}
Row {
id: innerRow
anchors.right: parent.right
spacing: Units.gu(1)
SimpleButton {
id: allowBtn
width: Units.gu(15)
height: Units.gu(8)
text: "Allow"
}
SimpleButton {
id: denyBtn
width: Units.gu(15)
height: Units.gu(8)
text: "Deny"
}
}
} // Column
}
} // Component
}