如何将 QML Combox 的大小调整为其较大元素的宽度?
How to size a QML Combox to the width of its bigger element?
我有一个 ComboBox,在纯 QML 代码中定义为一个组件(因此没有后端),我想将其宽度自动设置为其最宽的元素。目前,它采用最后选定元素的宽度,因此其弹出窗口无法正确显示其内容。
这是一个 mcve
Window {
id: mainWindow
title: "Test"
width: 500
height: 200
modality: Qt.WindowModal
flags: Qt.Dialog | Qt.WindowSystemMenuHint | Qt.WindowTitleHint | Qt.WindowCloseButtonHint
//color: "#E3E3E3"
GridLayout {
anchors.fill: parent
anchors.margins: 25
columnSpacing: 10
rowSpacing: 10
columns: 2
Label {
text: "Foo"
}
Loader {
id: loadCombo1
sourceComponent: niceComboBox
Binding {
target: loadCombo1.item
property: "model"
value: [{'value': "none",'text': "None"},
{'value': "medium",'text': "Some medium length text"},
{'value': "long",'text': "A pretty very long string that shouldn't be hidden"}]
}
}
}
Component {
id: niceComboBox
ComboBox {
id: control
delegate: ItemDelegate { // requiert QuickControls 2.2
width: control.width
contentItem: Text {
text: modelData.text
anchors.verticalCenter: parent.verticalCenter
}
highlighted: control.highlightedIndex === index
}
contentItem: Text {
text: control.model ? control.model[control.currentIndex].text : ""
anchors.verticalCenter: parent.verticalCenter
leftPadding: 10
rightPadding: 10
topPadding: 5
bottomPadding: 5
verticalAlignment: Text.AlignVCenter
}
FontMetrics {
id: fontMetric
font.family: control.contentItem.font.family
}
Component.onCompleted: {
//computeWidth();
}
Behavior on model {
ScriptAction {
script: computeWidth()
}
}
function computeWidth() {
if (control.model == null) {
return;
}
var longest = "";
for (var i = 0; i < model.length; i++) {
var txt = model[i].text;
if (txt.length > longest.length)
longest = txt;
}
var pwidth = fontMetric.boundingRect(longest).width;
pwidth += control.contentItem.rightPadding + control.contentItem.leftPadding;
pwidth += control.indicator.width
width = pwidth;
}
}
}
}
问题是当执行 Component.onCompleted
时,加载程序尚未指定模型。并且无法正确处理宽度的计算。
我尝试添加 Behavior on model
脚本来检测模型中的变化,但它没有做任何事情。
我该怎么办?
谢谢
我仅限于这些版本:QtQuick 2.9 和 QtQuick.Controls 2.2
[编辑] 我合并了@Mitch 的评论。
在 Qt 6 中,您可以使用 implicitContentWidthPolicy 属性:
import QtQuick.Controls
ApplicationWindow {
width: 640
height: 480
visible: true
ComboBox {
anchors.centerIn: parent
implicitContentWidthPolicy: ComboBox.WidestTextWhenCompleted
model: ["String", "A longer string", "A very, very long string"]
}
}
我想到了这个解决方案:
import QtQuick 2.9
import QtQuick.Controls 2.2
ComboBox {
id: control
model: []
delegate: ItemDelegate { // requiert QuickControls 2.2
width: control.width
contentItem: Text {
text: modelData.text
anchors.verticalCenter: parent.verticalCenter
}
highlighted: control.highlightedIndex === index
}
contentItem: Text {
text: control.model[control.currentIndex].text
anchors.verticalCenter: parent.verticalCenter
leftPadding: 10
rightPadding: 10
topPadding: 5
bottomPadding: 5
verticalAlignment: Text.AlignVCenter
}
FontMetrics {
id: fontMetric
font.family: control.contentItem.font.family
}
Binding on implicitWidth {
value: computeWidth(model)
}
popup.implicitWidth: computeWidth(model)
function computeWidth(mdl) {
if (mdl == null) {
return;
}
var longest = "";
for (var i = 0; i < mdl.length; i++) {
var txt = mdl[i].text;
if (txt.length > longest.length)
longest = txt;
}
var pwidth = fontMetric.boundingRect(longest).width;
pwidth += control.contentItem.rightPadding + control.contentItem.leftPadding;
pwidth += control.indicator.width
return pwidth;
}
}
我有一个 ComboBox,在纯 QML 代码中定义为一个组件(因此没有后端),我想将其宽度自动设置为其最宽的元素。目前,它采用最后选定元素的宽度,因此其弹出窗口无法正确显示其内容。
这是一个 mcve
Window {
id: mainWindow
title: "Test"
width: 500
height: 200
modality: Qt.WindowModal
flags: Qt.Dialog | Qt.WindowSystemMenuHint | Qt.WindowTitleHint | Qt.WindowCloseButtonHint
//color: "#E3E3E3"
GridLayout {
anchors.fill: parent
anchors.margins: 25
columnSpacing: 10
rowSpacing: 10
columns: 2
Label {
text: "Foo"
}
Loader {
id: loadCombo1
sourceComponent: niceComboBox
Binding {
target: loadCombo1.item
property: "model"
value: [{'value': "none",'text': "None"},
{'value': "medium",'text': "Some medium length text"},
{'value': "long",'text': "A pretty very long string that shouldn't be hidden"}]
}
}
}
Component {
id: niceComboBox
ComboBox {
id: control
delegate: ItemDelegate { // requiert QuickControls 2.2
width: control.width
contentItem: Text {
text: modelData.text
anchors.verticalCenter: parent.verticalCenter
}
highlighted: control.highlightedIndex === index
}
contentItem: Text {
text: control.model ? control.model[control.currentIndex].text : ""
anchors.verticalCenter: parent.verticalCenter
leftPadding: 10
rightPadding: 10
topPadding: 5
bottomPadding: 5
verticalAlignment: Text.AlignVCenter
}
FontMetrics {
id: fontMetric
font.family: control.contentItem.font.family
}
Component.onCompleted: {
//computeWidth();
}
Behavior on model {
ScriptAction {
script: computeWidth()
}
}
function computeWidth() {
if (control.model == null) {
return;
}
var longest = "";
for (var i = 0; i < model.length; i++) {
var txt = model[i].text;
if (txt.length > longest.length)
longest = txt;
}
var pwidth = fontMetric.boundingRect(longest).width;
pwidth += control.contentItem.rightPadding + control.contentItem.leftPadding;
pwidth += control.indicator.width
width = pwidth;
}
}
}
}
问题是当执行 Component.onCompleted
时,加载程序尚未指定模型。并且无法正确处理宽度的计算。
我尝试添加 Behavior on model
脚本来检测模型中的变化,但它没有做任何事情。
我该怎么办? 谢谢
我仅限于这些版本:QtQuick 2.9 和 QtQuick.Controls 2.2
[编辑] 我合并了@Mitch 的评论。
在 Qt 6 中,您可以使用 implicitContentWidthPolicy 属性:
import QtQuick.Controls
ApplicationWindow {
width: 640
height: 480
visible: true
ComboBox {
anchors.centerIn: parent
implicitContentWidthPolicy: ComboBox.WidestTextWhenCompleted
model: ["String", "A longer string", "A very, very long string"]
}
}
我想到了这个解决方案:
import QtQuick 2.9
import QtQuick.Controls 2.2
ComboBox {
id: control
model: []
delegate: ItemDelegate { // requiert QuickControls 2.2
width: control.width
contentItem: Text {
text: modelData.text
anchors.verticalCenter: parent.verticalCenter
}
highlighted: control.highlightedIndex === index
}
contentItem: Text {
text: control.model[control.currentIndex].text
anchors.verticalCenter: parent.verticalCenter
leftPadding: 10
rightPadding: 10
topPadding: 5
bottomPadding: 5
verticalAlignment: Text.AlignVCenter
}
FontMetrics {
id: fontMetric
font.family: control.contentItem.font.family
}
Binding on implicitWidth {
value: computeWidth(model)
}
popup.implicitWidth: computeWidth(model)
function computeWidth(mdl) {
if (mdl == null) {
return;
}
var longest = "";
for (var i = 0; i < mdl.length; i++) {
var txt = mdl[i].text;
if (txt.length > longest.length)
longest = txt;
}
var pwidth = fontMetric.boundingRect(longest).width;
pwidth += control.contentItem.rightPadding + control.contentItem.leftPadding;
pwidth += control.indicator.width
return pwidth;
}
}