Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I set the ComboBox width to fit the largest item

I would like that my ComboBox has to adapt its width to the longest String Item of my list.

Code Example:

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

Any idea of how to do it?

like image 740
Ed Nio Avatar asked Jul 11 '17 09:07

Ed Nio


2 Answers

There is no built-in mechanism for this in Quick-Controls-2 combobox (at the time of writing, Qt 5.9), so you have to do it yourself. Something like this...

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)
        }
    }
}

Note that if you change the model type from a QML List to a different type, such as C++ QStringList, QList<QObject*> or QAbstractListModel, then you migth need to modify this line textMetrics.text = model[i] to retrieve the text from the model items in a slightly different way.

like image 176
Mark Ch Avatar answered Nov 15 '22 10:11

Mark Ch


As of Qt 6, this is now possible by setting the ComboBox's implicitContentWidthPolicy to either ComboBox.WidestText , which will update whenever the model changes, or ComboBox.WidestTextWhenCompleted, which will check just once, when the ComboBox is loaded. (Keep in mind that the latter might not work as expected if the model isn't already available at the instant the ComboBox is loaded.)

like image 36
CrazyChucky Avatar answered Nov 15 '22 09:11

CrazyChucky