Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QComboBox specify width less than content



  • A window has a whole bunch of widgets for filtering. The combos have a set of strings to choose from. Some choice strings are "wide", so that the combo takes up a lot of screen estate. Note that I do not wish to truncate the choice texts.

    I have to develop for various flavors of Linux plus Windows. However, I only have access to an Ubuntu box running GNOME desktop/window manager. There I am able to use QComboBox::setMaximumWidth, and what I see is nice narrow combo on screen, when the user clicks to display the dropdown that is show widened to accommodate the wide strings in the dropdown only, without widening the non-dropdown combo width.

    This is perfect for me. Can anybody tell me whether this behaviour is "supported" across Linux/Windows platforms? Will it come out like this under Windows, or will the combo widget (in non-dropdown state) automatically get widened to the long strings?



  • I have finally just discovered that changing the Qt combo's view width (QComboBox::view()::setMinimumWidth(), combined with measuring items' maximum width using QComboBox::fontMetrics()) is exactly how to widen the dropdown beyond the combo's width, and does work under Windows, as well as Linux/GNOME.

    I am somewhat surprised nobody mentioned exactly this perfectly simple solution. Is nobody aware of it?

    class JComboBox(QComboBox):
        def showPopup(self):
            # we like the popup to always show the full contents
            # we only need to do work for this when the combo has had a maximum width specified
            maxWidth = self.maximumWidth()
            # see https://doc.qt.io/qt-5/qwidget.html#maximumWidth-prop for the 16777215 value
            if maxWidth and maxWidth < 16777215:
                self.setPopupMinimumWidthForItems()
    
            # call the base method now to display the popup
            super().showPopup()
    
        def setPopupMinimumWidthForItems(self):
            # we like the popup to always show the full contents
            # under Linux/GNOME popups always do this
            # but under Windows they get truncated/ellipsised
            # here we calculate the maximum width among the items
            # and set QComboBox.view() to accomodate this
            # which makes items show full width under Windows
            view = self.view()
            fm = self.fontMetrics()
            maxWidth = max([fm.width(self.itemText(i)) for i in range(self.count())])
            if maxWidth:
                view.setMinimumWidth(maxWidth)
    

  • Lifetime Qt Champion

    Hi,

    IIRC, there has been some issues related to comboboxes and size on macOS (but it's old memory).

    Can you provide a small test sample to check that ?



  • @SGaist

    import sys
    from PyQt5 import QtWidgets
    
    
    if __name__ == '__main__':
        app = QtWidgets.QApplication(sys.argv)
    
        dlg = QtWidgets.QDialog()
        dlg.setFixedSize(400, 300)
        dlg.setLayout(QtWidgets.QVBoxLayout())
    
        combo = QtWidgets.QComboBox()
        dlg.layout().addWidget(combo)
    
        combo.addItem("this is short")
        combo.addItem("this is medium this is medium ")
        combo.addItem("this is long this is long this is long this is long ")
        combo.setCurrentIndex(1)
    
        combo.setMaximumWidth(150)
    
        dlg.show()
    
        sys.exit(app.exec_())
    

    The lengths of some of the combo items exceed the setMaximumWidth(150) (which is required to make the combo fit OK onto the dialog).. I can't take a screenshot showing the combo items dropped down, but under Linux/GNOME at least it's quite happy to show the dropdown list wider than the combo box. (The combo itself does not widen to accommodate the long text.) This is precisely what I want.

    I have to target Windows as well as Linux, though not MacOS fortunately.

    Does it work same under Windows? Thinking about it, I imagine Qt uses the native combobox capabilities of its host, so it's probably a question about native combobox behaviour rather than any Qt own code?



  • I now understand from my users that the behaviour under Windows is different: if a QComboBox with a maximum width has dropdown selection items wider than the combobox they are shown with some sort of truncation ellipsis ... on the text, rather than the dropdown being allowed to display items at their full width.

    If that is so, it's shame nobody was able to say this is Windows behaviour :(


  • Lifetime Qt Champion

    What version of Windows is it ?



  • @SGaist
    Errr, the guy who told me would be running Windows 10.

    He told me the long text got shortened, I think with ellipsis at the right-hand side, I guess so that the text wouldn't overspill the combo width. In my Linux/GNOME, the dropdown just completely overwrites the combo and is wide enough to accommodate any text. The Windows one might constrain the dropdown to be "inside" the combo, I don't know. This may of course be windowing behaviour, nothing to do with Qt, unless there is some style I can set.


  • Lifetime Qt Champion

    Hi
    Default i get this. ( win 10, Qt 5.13)
    seems it put ... in the middle of text.
    alt text



  • @mrjj
    Thanks for confirming. Unfortunately I needed to know that is Windows behaviour before I changed combobox width code over to suit Linux/GNOME, and then received Windows users complaints because the ellipsis truncation is not acceptable to them :(

    I wonder whether this behaviour is built-in and unchangeable under Windows, or whether I can alter it with a flag or something from Qt...?


  • Lifetime Qt Champion

    Hi
    Btw. if you ever want a windows to test on, you can get one legally and free for 3 months.
    https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/
    And using vmware/virtual box snapshot function it can last forever.



  • @mrjj
    I have no shortage of Windows boxes. But since I hate Windows and am working on the Qt stuff (under Linux) for free, I have no intention of going through the rigmarole of attempting to install all the dependencies for Python/PyCharm/Qt/MySQL and the hundreds of other dependencies and Windows installation tweaks the software has in order to develop/test it under Windows.

    I love Qt because it gives me platform-independence, isolating me from the vagaries of Windows. I realize others may criticise me saying I'm being short-sighted and need to be prepared to use Windows if I want to see how the Qt stuff actually comes out under Windows. But I actually ask few if any questions about Qt under Windows --- this was about the only one I needed to know about before changing the code over.

    Meanwhile, getting back to the behaviour. Googling around (e.g. windows combobox ellipsis) I'm seeing questions saying "how can I truncate/ellipsize combo texts which are too long for the combobox?". This makes me think/wonder whether the ellipsization we are seeing is a newer-Windows phenomenon...? I am struggling to find a statement on this behaviour as to what a Windows combobox actually does with long text, possibly varying by which version of Windows...?

    Now I'm wondering: if people are asking how to truncate/ellipsize under Windows, maybe this behaviour we are seeing is a feature of Qt code (under Windows) after all...??



  • I have finally just discovered that changing the Qt combo's view width (QComboBox::view()::setMinimumWidth(), combined with measuring items' maximum width using QComboBox::fontMetrics()) is exactly how to widen the dropdown beyond the combo's width, and does work under Windows, as well as Linux/GNOME.

    I am somewhat surprised nobody mentioned exactly this perfectly simple solution. Is nobody aware of it?

    class JComboBox(QComboBox):
        def showPopup(self):
            # we like the popup to always show the full contents
            # we only need to do work for this when the combo has had a maximum width specified
            maxWidth = self.maximumWidth()
            # see https://doc.qt.io/qt-5/qwidget.html#maximumWidth-prop for the 16777215 value
            if maxWidth and maxWidth < 16777215:
                self.setPopupMinimumWidthForItems()
    
            # call the base method now to display the popup
            super().showPopup()
    
        def setPopupMinimumWidthForItems(self):
            # we like the popup to always show the full contents
            # under Linux/GNOME popups always do this
            # but under Windows they get truncated/ellipsised
            # here we calculate the maximum width among the items
            # and set QComboBox.view() to accomodate this
            # which makes items show full width under Windows
            view = self.view()
            fm = self.fontMetrics()
            maxWidth = max([fm.width(self.itemText(i)) for i in range(self.count())])
            if maxWidth:
                view.setMinimumWidth(maxWidth)
    

Log in to reply