QComboBox - How to set hint text on combo box

后端 未结 3 1738
悲&欢浪女
悲&欢浪女 2020-12-11 20:50

The application GUI I working requires a combo box for user to select item. When the application starts, the combo box will show a hint text something like \"Please select\"

相关标签:
3条回答
  • 2020-12-11 20:59

    There is no way to set place holder text for QComboBox. But you can solve this problem. Use setEditText( const QString& ) slot for setting your text. If user selects an item in comboBox, item's text will be set. But if user selects the text, deletes it, and selects other control element (combo box looses its focus), your text won't be there anymore. Its possible to solve by inheriting from QComboBox, and reimplementing focusOutEvent(...), where you check: if ( currentIndex() == -1 ) setEditText( tr( "Please select" ) );. And dont forget to call QComboBox::focusOutEvent(...) first.

    0 讨论(0)
  • 2020-12-11 21:10

    There is an elegant solution if the QComboBox is editable:

    myQComboBox->lineEdit()->setPlaceHolderText("Please select");
    

    QComboBoxes that are not editable do not have QLineEdits in them, so this would not work on those.

    0 讨论(0)
  • 2020-12-11 21:15

    For newer versions of Qt try QComboBox::setPlaceholderText().

    I happened to be working with an older version of Qt (5.11.3) on a Raspberry Pi and needed different solution.

    Here is a working pyqt5 example using a proxy model to adjust for the extra item added as the placeholder. (credit to this answer):

    import sys
    from PyQt5.QtCore import Qt, QT_VERSION_STR, QAbstractProxyModel, QModelIndex, QItemSelection
    from PyQt5.QtGui import QStandardItemModel, QStandardItem
    from PyQt5.QtWidgets import (QApplication, QGridLayout, QWidget, QComboBox)
    from typing import Any
    
    class Main(QWidget):
        def __init__(self):
            super().__init__()
            self.setGeometry(50,50,320,200)
            self.setWindowTitle(f"Qt Version {QT_VERSION_STR}")
    
            layout = QGridLayout()
    
            cmbox = QComboBox()
    
            model = QStandardItemModel()
            
            for i in range(1, 11):
                model.appendRow(QStandardItem(f"Item {i}"))
    
            cmbox.setModel(ProxyModel(model, '---PlaceholderText---'))
            cmbox.setCurrentIndex(0)
            layout.addWidget(cmbox, 0, 0)
            
    
            self.setLayout(layout)
            self.show()
    
    
    class ProxyModel(QAbstractProxyModel):
        def __init__(self, model, placeholderText='---', parent=None):
            super().__init__(parent)
            self._placeholderText = placeholderText
            self.setSourceModel(model)
            
        def index(self, row: int, column: int, parent: QModelIndex = ...) -> QModelIndex:
            return self.createIndex(row, column)
    
        def parent(self, index: QModelIndex = ...) -> QModelIndex:
            return QModelIndex()
    
        def rowCount(self, parent: QModelIndex = ...) -> int:
            return self.sourceModel().rowCount()+1 if self.sourceModel() else 0
    
        def columnCount(self, parent: QModelIndex = ...) -> int:
            return self.sourceModel().columnCount() if self.sourceModel() else 0
    
        def data(self, index: QModelIndex, role: int = Qt.DisplayRole) -> Any:
            if index.row() == 0 and role == Qt.DisplayRole:
                return self._placeholderText
            elif index.row() == 0 and role == Qt.EditRole:
                return None
            else:
                return super().data(index, role)
    
        def mapFromSource(self, sourceIndex: QModelIndex):
            return self.index(sourceIndex.row()+1, sourceIndex.column())
    
        def mapToSource(self, proxyIndex: QModelIndex):
            return self.sourceModel().index(proxyIndex.row()-1, proxyIndex.column())
    
        def mapSelectionFromSource(self, sourceSelection: QItemSelection):
            return super().mapSelection(sourceSelection)
    
        def mapSelectionToSource(self, proxySelection: QItemSelection):
            return super().mapSelectionToSource(proxySelection)
        
        def headerData(self, section: int, orientation: Qt.Orientation, role: int = Qt.DisplayRole):
            if not self.sourceModel():
                return None
            if orientation == Qt.Vertical:
                return self.sourceModel().headerData(section-1, orientation, role)
            else:
                return self.sourceModel().headerData(section, orientation, role)
    
        def removeRows(self, row: int, count: int, parent: QModelIndex = ...) -> bool:
            return self.sourceModel().removeRows(row, count -1)
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        ex = Main()
        sys.exit(app.exec_())
    
    0 讨论(0)
提交回复
热议问题