如何设置ComboBox宽度以适合最大的项目

时间:2017-07-11 09:02:46

标签: combobox qml qt-quick

我希望我的ComboBox必须将其width修改为我列表中最长的String Item

代码示例:

ComboBox {
    model: [ "Banana", "Apple", "ThisIsTheLongestWordThatIHave,"Coconut" ]
}

知道怎么做吗?

4 个答案:

答案 0 :(得分:4)

Quick-Controls-2组合框中没有内置机制(在撰写本文时,Qt 5.9),所以你必须自己动手。像这样......

main.qml

MyComboBox {
    id: comboBox1
    sizeToContents: false
    model: [ "Banana", "Apple", "ThisIsTheLongestWordThatIHave", "Coconut" ]
}

MyComboBox {
    id: comboBox2
    anchors.top: comboBox1.bottom
    sizeToContents: true
    model: [ "Banana", "Apple", "ThisIsTheLongestWordThatIHave", "Coconut" ]
}

MyComboBox.qml

ComboBox {
    id: control

    property bool sizeToContents
    property int modelWidth

    width: (sizeToContents) ? modelWidth + 2*leftPadding + 2*rightPadding : implicitWidth

    delegate: ItemDelegate {
        width: control.width
        text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole] : model[control.textRole]) : modelData
        font.weight: control.currentIndex === index ? Font.DemiBold : Font.Normal
        font.family: control.font.family
        font.pointSize: control.font.pointSize
        highlighted: control.highlightedIndex === index
        hoverEnabled: control.hoverEnabled
    }

    TextMetrics {
        id: textMetrics
    }

    onModelChanged: {
        textMetrics.font = control.font
        for(var i = 0; i < model.length; i++){
            textMetrics.text = model[i]
            modelWidth = Math.max(textMetrics.width, modelWidth)
        }
    }
}

请注意,如果您将模型类型从QML列表更改为其他类型,例如C ++ QStringListQList<QObject*>QAbstractListModel,那么您需要修改此行{ {1}}以稍微不同的方式从模型项中检索文本。

答案 1 :(得分:1)

@马克章 - MyComboBox确实使用控件2不工作;指示器的宽度未考虑在内,因此如果指示器具有任何宽度都太窄。

它对我有用,将宽度:的分配替换为以下内容:

response = Unirest.post "https://api.remove.bg/v1.0/removebg",
    headers:{
        "X-Api-Key" => "INSERT_YOUR_API_KEY_HERE"
        },
    parameters:{
        "image_url" => "https://www.remove.bg/example.jpg"
        }

答案 2 :(得分:0)

这是另一种方法,该方法较少依赖内部,可与任何类型的模型一起使用,并与其他ComboBox样式(例如“材料”:

我们的想法是只设置currentItem,以每个可能值,并让组合框内部做他们的事;然后观察所得的宽度。 ComboBox.contentItemTextField,而TextField.contentWidth正是我们想要的。我们不必知道如何迭代模型或模拟什么delegate可能会做些什么来改变格式。所需的ComboBox宽度是这些contentWidths的最大值,再加上填充和指示器宽度。

该计算不能直接绑定到width,因为会发生绑定循环。相反,宽度被计算并静态地设定当 onCompleted 发生信号。

请注意:下面的代码还没有处理动态更新的车型。我可能会在以后更新此帖子...

用法:

import QtQuick 2.9
import QtQuick.Controls 2.2
import "ComboBoxHacks.js" as CBH
...
ComboBox {
  id: myCB
  Component.onCompleted: width = CBH.calcComboBoxImplicitWidth(myCB)
  ...
}

这里是JavaScript代码:

/* ComboBoxHacks.js */
function calcComboBoxImplicitWidth(cb) {
  var widest = 0
  if (cb.count===0) return cb.width
  var originalCI = cb.currentIndex
  if (originalCI < 0) return cb.width // currentIndex →  deleted item
  do {
    widest = Math.max(widest, cb.contentItem.contentWidth)
    cb.currentIndex = (cb.currentIndex + 1) % cb.count
  } while(cb.currentIndex !== originalCI)

  return widest + cb.contentItem.leftPadding + cb.contentItem.rightPadding
                + cb.indicator.width
}

答案 3 :(得分:0)

当模型更改时,您只需要更新minimumWidth。

import QtQml 2.12
import QtQuick 2.12
import QtQuick.Controls 2.5
import QtQuick.Layouts 1.12

ComboBox {
    id: root

    onModelChanged: {
        var _maxWidth = 0
        for(var i = 0; i < model.length; i++){
            // TextMetrics does not work with Material Style
            _maxWidth = Math.max((model[i].length+1)*Qt.application.font.pixelSize, _maxWidth)
        }
        Layout.minimumWidth = _maxWidth + implicitIndicatorWidth + leftPadding + rightPadding
    }
}