主要问题是一旦选择了组合框中的项目,就会发送textActivated 信号。
虽然这看起来很直观,但您必须考虑以下方面。
- 即使项目已经是当前项,也会发送信号
- 由于上述原因,每当用户激活组合中的项目时,它也会始终发送,当用户执行以下操作时也会发生这种情况:
- 使用键盘导航(箭头键、home/end、page up/down);
- 使用键盘在组合项中搜索;
- 在可编辑的组合上按 Enter;
- 点击弹出窗口中的项目;
- 键盘交互或鼠标选择不会立即更新视图的内容,包括
currentText()属性,因为Qt需要一些时间来完成它的工作(通常,如果可编辑的组合有要添加的新项目,则更新组合模型)
另外,需要考虑的一个重要方面是textActivated 是一个相当新的功能(它是在不到一年前的 2019 年底在 Qt 5.14 中引入的),对于您的需求可能不是那么必要。
最后,基于索引的对象的字符串比较很少是个好主意,至少有两个重要原因:
- 在某些时候,您可能需要进行一些本地化;虽然在您的简单情况下,它只是一个数字的字符串表示形式,但有一天,简单的“2”可能会变成“text 2”、“texto 2”、“texte 2”或“testo 2”。
- 基于 UI 的框架有时会自动更改小部件的显示文本;虽然组合框项通常不是这种情况,但 Qt 有时会更改小部件的文本集以包含 助记符:包含可用作键盘加速器的下划线字母的文本,即以
& 开头的字母以编程方式可读;结果是您在按钮上设置了文本“保存”,然后当您调用button.text() 时,您会得到“&Save”。
因此,考虑到上述情况,这是您可能需要的一种可能实现(使用组合项索引而不是字符串):
from PyQt5 import QtWidgets
class ComboTest(QtWidgets.QWidget):
def __init__(self):
super().__init__()
layout = QtWidgets.QGridLayout(self)
self.comboBox = QtWidgets.QComboBox()
layout.addWidget(self.comboBox, 0, 0, 1, 2)
self.comboBox.addItems(['Label 1', 'Label 2'])
self.label_1 = QtWidgets.QLabel('Hello, label 1!')
layout.addWidget(self.label_1, 1, 0)
self.label_2 = QtWidgets.QLabel('Hello, label 2!')
layout.addWidget(self.label_2, 1, 1)
self.label_2.hide()
self.comboBox.currentIndexChanged.connect(self.showLabel)
def showLabel(self, index):
if index == 0:
self.label_1.show()
self.label_2.hide()
elif index == 1:
self.label_1.hide()
self.label_2.show()
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
test = ComboTest()
test.show()
sys.exit(app.exec_())
最后一点。
在显示其父级之前隐藏小部件可能是个问题。在上面的示例中,您会注意到,当您再次选择第二个项目并然后第一个项目时,小部件将自行调整大小。虽然在这种特定情况下它可能不是什么大问题,但对于复杂的布局,从用户体验的角度来看这不是一件好事(用户不喜欢 UI 意外改变其大小)。一种可能的替代方法是改用QStackedWidget,使用addWidget() 添加标签,然后使用组合索引调用其setCurrentIndex()。
from PyQt5 import QtWidgets
class ComboTest(QtWidgets.QWidget):
def __init__(self):
super().__init__()
layout = QtWidgets.QVBoxLayout(self)
self.comboBox = QtWidgets.QComboBox()
layout.addWidget(self.comboBox)
self.comboBox.addItems(['Label 1', 'Label 2'])
self.stackedWidget = QtWidgets.QStackedWidget()
layout.addWidget(self.stackedWidget)
self.label_1 = QtWidgets.QLabel('Hello, label 1!')
self.stackedWidget.addWidget(self.label_1)
self.label_2 = QtWidgets.QLabel('Hello, label 2!')
self.stackedWidget.addWidget(self.label_2)
self.comboBox.currentIndexChanged.connect(
self.stackedWidget.setCurrentIndex)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
test = ComboTest()
test.show()
sys.exit(app.exec_())