如何使用 QComboBox.setPlaceholderText?
Posted
技术标签:
【中文标题】如何使用 QComboBox.setPlaceholderText?【英文标题】:How do i use QComboBox.setPlaceholderText? 【发布时间】:2021-04-25 19:28:56 【问题描述】:在 Qt 5.15 中引入了 placeholderText
属性 - link to documentation
但是使用setPlaceholderText
对我没有任何作用。运行下面的代码时,QComboBox
中没有任何文本(当然,除非我选择三个项目之一)
这是一个错误还是我错过了什么?我怎样才能做到这一点?
import sys
from PyQt5 import QtWidgets
from PyQt5 import QtCore
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
central_w = QtWidgets.QWidget()
self.setCentralWidget(central_w)
vbox = QtWidgets.QVBoxLayout()
central_w.setLayout(vbox)
self.combo_box = QtWidgets.QComboBox()
self.combo_box.addItems(["one", "two", "three"])
self.combo_box.setPlaceholderText("Some placeholder text here")
self.combo_box.setCurrentIndex(-1)
vbox.addWidget(self.combo_box)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
main_window = MainWindow()
main_window.show()
app.exec_()
我没有找到显示占位符文本的方法。我试过在组合框中根本没有项目,但即使这样也不显示占位符文本
这些是我正在运行的版本:
Qt:5.15.2 PyQt(Python 模块)版本:5.15.2(这恰好与 Qt 版本相同,但有时可能略有不同) Python:“3.8.5(默认,2020 年 7 月 28 日,12:59:40)\n[GCC 9.3.0]” 操作系统:Ubuntu 20.04.1 LTS(带 Xfce)PS:如果你想达到类似的效果(即:在可点击区域上有一个文本,点击后显示带有不同选项的下拉菜单)你可以使用 QPushButton
和 setMenu
函数.文档:https://doc.qt.io/qt-5/qpushbutton.html#setMenu
【问题讨论】:
print(app.style().objectName()
的输出是什么?如果不是“融合”,试试app.setStyle(QtWidgets.QStyleFactory.create('fusion'))
@musicamante 我得到了app.style().objectName()='fusion'
。顺便说一句,我不知道这是否重要,但我正在运行 Xfce(我会在问题中更新它)
嗯。您可以尝试其他可用的样式吗?您可以使用静态 QStyleFactory.keys()
查看完整列表。另外,您是否可以尝试通过显式设置placeholderText
角色来更改调色板(确保它具有足够的对比度并且没有alpha)?
尝试PySide2
而不是PyQt5
。我刚刚在 Windows 上对其进行了测试,它确实有效。
【参考方案1】:
查看Qt源代码的修改,发现为了在Qt 5.15.0中添加placeHolderText的功能,修改了currentText():
// https://code.qt.io/cgit/qt/qtbase.git/tree/src/widgets/widgets/qcombobox.cpp?h=5.15.0#n2344
QString QComboBox::currentText() const
Q_D(const QComboBox);
if (d->lineEdit)
return d->lineEdit->text();
else if (d->currentIndex.isValid())
return d->itemText(d->currentIndex);
else
return d->placeholderText;
但这会产生不良影响,QTBUG-86580 中报告了该影响,因此在 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 ;
忘记纠正 placeHolder 不再可见的副作用。我已经报告了这个错误:QTBUG-90522。
考虑到上述情况,有以下备选方案:
使用 PyQt5/PySide2 5.15.0 或 5.15.1。
重写paintEvent方法将placeHolderText设置为currentText:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
# or
# from PySide2 import QtCore, QtGui, QtWidgets
class ComboBox(QtWidgets.QComboBox):
# https://code.qt.io/cgit/qt/qtbase.git/tree/src/widgets/widgets/qcombobox.cpp?h=5.15.2#n3173
def paintEvent(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)
class MainWindow(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_()
【讨论】:
在我看来,除了颜色之外,它都有效。颜色看起来与其他下拉项相同。【参考方案2】:作为 eyllanesc 答案的附录,非常精确,这里只是 Qt 5.15.2 中占位符文本错误的一个更简单的解决方法,这是非常重要的版本,因为它是 Qt5 的最后一个非商业版本。它是 C++,但很容易翻译成 Python。
#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();
【讨论】:
以上是关于如何使用 QComboBox.setPlaceholderText?的主要内容,如果未能解决你的问题,请参考以下文章
如何在自动布局中使用约束标识符以及如何使用标识符更改约束? [迅速]
如何使用 AngularJS 的 ng-model 创建一个数组以及如何使用 jquery 提交?