4

我工作的应用程序 GUI 需要一个组合框供用户选择项目。当应用程序启动时,组合框将显示类似“请选择”的提示文本,而不是显示组合框的第一项。我在http://doc.qt.io/qt-5/qcombobox.html#currentText-prop中找不到任何设置提示文本的方法。

预先感谢!

4

5 回答 5

5

如果是,则有一个优雅的解决方案QComboBoxeditable

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

QComboBox不是的es 里面editable没有QLineEdits,所以这对那些不起作用。

于 2014-11-06T11:30:13.413 回答
2

对于较新版本的 Qt,请尝试QComboBox::setPlaceholderText()

我碰巧在 Raspberry Pi 上使用旧版本的 Qt (5.11.3),需要不同的解决方案。

这是一个使用代理模型来调整作为占位符添加的额外项目的工作 pyqt5 示例。(归功于这个答案):

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_())
于 2020-10-21T02:29:37.213 回答
1

无法为QComboBox. 但是你可以解决这个问题。使用setEditText( const QString& )插槽设置文本。如果用户在 中选择一个项目comboBox,将设置项目的文本。但是如果用户选择文本,删除它,然后选择其他控制元素(组合框失去焦点),您的文本将不再存在。它可以通过继承QComboBox和重新实现来解决focusOutEvent(...),您检查:if ( currentIndex() == -1 ) setEditText( tr( "Please select" ) );. 并且不要忘记先打电话QComboBox::focusOutEvent(...)

于 2011-06-13T11:49:11.303 回答
0

In Qt Designer you can set place holder text.

enter image description here

If you add items also in designer and you will run code probably it will start with first item selected.

enter image description here

In code you should just call (in ctor or any init part)

comboBox->setCurrentIndex(-1);
于 2021-09-02T07:49:32.073 回答
0

这是 Qt 5.15.2 中占位符文本错误的更简单的解决方法,这是非常重要的版本,因为它是 Qt5 的最后一个非商业版本。它修复了不可见的占位符文本combo.isEditable() == false

#include <QApplication>
#include <QComboBox>
#include <QLabel>
#include <QVBoxLayout>

int main(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 = new QLabel(space + "Select something...");
    combo.setLayout(new QVBoxLayout());
    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();
}
于 2021-11-19T16:35:28.457 回答