我工作的应用程序 GUI 需要一个组合框供用户选择项目。当应用程序启动时,组合框将显示类似“请选择”的提示文本,而不是显示组合框的第一项。我在http://doc.qt.io/qt-5/qcombobox.html#currentText-prop中找不到任何设置提示文本的方法。
预先感谢!
我工作的应用程序 GUI 需要一个组合框供用户选择项目。当应用程序启动时,组合框将显示类似“请选择”的提示文本,而不是显示组合框的第一项。我在http://doc.qt.io/qt-5/qcombobox.html#currentText-prop中找不到任何设置提示文本的方法。
预先感谢!
如果是,则有一个优雅的解决方案:QComboBox
editable
myQComboBox->lineEdit()->setPlaceHolderText("Please select");
QComboBox
不是的es 里面editable
没有QLineEdit
s,所以这对那些不起作用。
对于较新版本的 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_())
无法为QComboBox
. 但是你可以解决这个问题。使用setEditText( const QString& )
插槽设置文本。如果用户在 中选择一个项目comboBox
,将设置项目的文本。但是如果用户选择文本,删除它,然后选择其他控制元素(组合框失去焦点),您的文本将不再存在。它可以通过继承QComboBox
和重新实现来解决focusOutEvent(...)
,您检查:if ( currentIndex() == -1 ) setEditText( tr( "Please select" ) );
. 并且不要忘记先打电话QComboBox::focusOutEvent(...)
。
这是 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();
}