Skip to content Skip to sidebar Skip to footer

How Do I Use Qcombobox.setplaceholdertext?

In Qt 5.15 the placeholderText property was introduced - link to documentation However using setPlaceholderText doesn't do anything for me. When running the code below i don't get

Solution 1:

Reviewing the modifications of the Qt source code, it is observed that to add the functionality of the placeHolderText in Qt 5.15.0, the currentText() was modified:

// https://code.qt.io/cgit/qt/qtbase.git/tree/src/widgets/widgets/qcombobox.cpp?h=5.15.0#n2344QString QComboBox::currentText()const{
    Q_D(const QComboBox);
    if (d->lineEdit)
        return d->lineEdit->text();
    elseif (d->currentIndex.isValid())
        return d->itemText(d->currentIndex);
    elsereturn d->placeholderText;
}

But that generates an undesirable effect that was reported in QTBUG-86580 so that functionality was removed in Qt 5.15.2:

QString QComboBox::currentText()const{
    Q_D(const QComboBox);
    if (d->lineEdit)
        return d->lineEdit->text();
    if (d->currentIndex.isValid())
        return d->itemText(d->currentIndex);
    return {};
}

Forgetting to correct the side effect which is that the placeHolder is no longer visible. I have already reported the bug: QTBUG-90522.

Considering the above, there are the following alternatives:

  • Use PyQt5/PySide2 5.15.0 or 5.15.1.

  • Override the paintEvent method to set the placeHolderText as currentText:

import sys
from PyQt5 import QtCore, QtGui, QtWidgets

# or# from PySide2 import QtCore, QtGui, QtWidgetsclassComboBox(QtWidgets.QComboBox):
    # https://code.qt.io/cgit/qt/qtbase.git/tree/src/widgets/widgets/qcombobox.cpp?h=5.15.2#n3173defpaintEvent(self, event):
        
        painter = QtWidgets.QStylePainter(self)
        painter.setPen(self.palette().color(QtGui.QPalette.Text))

        # draw the combobox frame, focusrect and selected etc.
        opt = QtWidgets.QStyleOptionComboBox()
        self.initStyleOption(opt)
        painter.drawComplexControl(QtWidgets.QStyle.CC_ComboBox, opt)

        if self.currentIndex() < 0:
            opt.palette.setBrush(
                QtGui.QPalette.ButtonText,
                opt.palette.brush(QtGui.QPalette.ButtonText).color().lighter(),
            )
            if self.placeholderText():
                opt.currentText = self.placeholderText()

        # draw the icon and text
        painter.drawControl(QtWidgets.QStyle.CE_ComboBoxLabel, opt)


classMainWindow(QtWidgets.QMainWindow):
    def__init__(self):
        super().__init__()

        self.combo_box = ComboBox()
        self.combo_box.addItems(["one", "two", "three"])
        self.combo_box.setPlaceholderText("Some placeholder text here")
        self.combo_box.setCurrentIndex(-1)

        central_w = QtWidgets.QWidget()
        self.setCentralWidget(central_w)
        vbox = QtWidgets.QVBoxLayout(central_w)
        vbox.addWidget(self.combo_box)


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    main_window = MainWindow()
    main_window.show()
    app.exec_()

Solution 2:

As addendum to eyllanesc's answer, which is very precise, here is just a bit simpler workaround for the placeholder text bug in Qt 5.15.2, which is very important version because it is the last non-commercial version ever for Qt5. It is C++ but it is easy to translate to Python.

#include<QApplication>#include<QComboBox>#include<QLabel>#include<QVBoxLayout>intmain(int argc, char *argv[]){
    QApplication a(argc, argv);
    QComboBox combo;
    combo.show();
    combo.addItem("AAAA");
    combo.addItem("BBBB");

    // The following line does not work e.g. in Qt 5.15.2.//combo.setPlaceholderText("Select something...");// This is a simple workaround:auto space = QString(" ");
    auto placeholder = newQLabel(space + "Select something...");
    combo.setLayout(newQVBoxLayout());
    combo.layout()->setContentsMargins(0, 0, 0, 0);
    combo.layout()->addWidget(placeholder);
    QObject::connect(&combo, &QComboBox::currentIndexChanged, &combo, [placeholder](int index){ placeholder->setVisible(index == -1); });
    combo.setCurrentIndex(-1);

    return a.exec();
}

Post a Comment for "How Do I Use Qcombobox.setplaceholdertext?"