基于用户选择的标签组合框状态
Combo box state of labels based on the user`s choice
我有一个带有两个选项的组合框,我希望组合框中的选择能够确定两个标签的状态。我的意思是,例如,如果用户选择“1”,我希望他只看到第一个标签,如果他选择“2”,第二个标签将出现。我成功地做到了,但问题是在选择一次之后,这个实现不再起作用了,我的意思是当做出新的选择时我不能让它起作用
所以这是我的代码:
self.comboBox.textActivated['QString'].connect(self.on_combobox_changed)
self.label_2.hide()
def on_combobox_changed(self):
if self.comboBox.currentText() == "2":
self.label_2.show()
好的,我刚刚添加了一个类似的 for 循环,它似乎可以工作,但我不确定它是否是一个好的实现
编辑:
def on_combobox_changed(self):
for x in range(0, 1000):
if self.comboBox.currentText() == "2":
self.label_2.show()
else:
self.label_2.hide()
主要问题是 textActivated
信号在组合框中的项目被 select 编辑后立即发送。
虽然这看起来很直观,但您必须考虑以下几个方面。
- 即使该项目已经是当前一个
也会发送信号
- 由于上述原因,每当用户激活组合中的项目时,它也会始终发送,这也会发生在用户:
- 使用键盘导航(箭头键,home/end,页面 up/down);
- 使用键盘在组合项中搜索;
- 在可编辑的组合上按回车键;
- 点击弹出窗口中的项目;
- 键盘交互或鼠标selection 不会立即更新视图的内容,包括
currentText()
属性,因为Qt需要一些时间来完成它的东西(通常,如果可编辑组合有要添加的新项目,则更新组合模型)
此外,需要考虑的一个重要方面是 textActivated
是一个相当新的功能(它是在 2019 年底的 Qt 5.14 中引入的,不到一年前),并且您的需求可能是没那么必要。
最后,index-based 对象的字符串比较很少是个好主意,至少有两个重要原因:
- 在某些时候,您可能需要进行一些本地化;虽然在您的简单情况下,它只是数字的字符串表示形式,但总有一天,简单的“2”可能会变成“text 2”、“texto 2”、“texte 2”或“testo 2”。
基于 - UI 的框架有时会自动更改小部件的显示文本;虽然组合框项通常不是这种情况,但 Qt 有时会更改小部件的文本集以包含 mnemonics:包含可用作键盘快捷键的带下划线字母的文本这在编程上是可读的,因为该字母前面有
&
;结果是您在按钮上设置文本“保存”,然后当您调用 button.text()
时,您会得到“&保存”。
因此,考虑到上述情况,这是您可能需要的一种可能实现方式(使用组合项索引而不是字符串):
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_())
最后一点。
在 之前 隐藏小部件显示它们的父级可能是个问题。在上面的示例中,您会注意到,当您再次 select 第二个项目并 然后 第一个时,小部件将自行调整大小。虽然在这种特定情况下,这可能不是什么大问题,但对于复杂的布局来说,从用户体验的角度来看这不是一件好事(用户不喜欢 UI 意外更改其大小)。一种可能的替代方法是使用 QStackedWidget instead, add the labels to it with addWidget()
, and use the combo index to call its 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_())
我有一个带有两个选项的组合框,我希望组合框中的选择能够确定两个标签的状态。我的意思是,例如,如果用户选择“1”,我希望他只看到第一个标签,如果他选择“2”,第二个标签将出现。我成功地做到了,但问题是在选择一次之后,这个实现不再起作用了,我的意思是当做出新的选择时我不能让它起作用
所以这是我的代码:
self.comboBox.textActivated['QString'].connect(self.on_combobox_changed)
self.label_2.hide()
def on_combobox_changed(self):
if self.comboBox.currentText() == "2":
self.label_2.show()
好的,我刚刚添加了一个类似的 for 循环,它似乎可以工作,但我不确定它是否是一个好的实现
编辑:
def on_combobox_changed(self):
for x in range(0, 1000):
if self.comboBox.currentText() == "2":
self.label_2.show()
else:
self.label_2.hide()
主要问题是 textActivated
信号在组合框中的项目被 select 编辑后立即发送。
虽然这看起来很直观,但您必须考虑以下几个方面。
- 即使该项目已经是当前一个 也会发送信号
- 由于上述原因,每当用户激活组合中的项目时,它也会始终发送,这也会发生在用户:
- 使用键盘导航(箭头键,home/end,页面 up/down);
- 使用键盘在组合项中搜索;
- 在可编辑的组合上按回车键;
- 点击弹出窗口中的项目;
- 键盘交互或鼠标selection 不会立即更新视图的内容,包括
currentText()
属性,因为Qt需要一些时间来完成它的东西(通常,如果可编辑组合有要添加的新项目,则更新组合模型)
此外,需要考虑的一个重要方面是 textActivated
是一个相当新的功能(它是在 2019 年底的 Qt 5.14 中引入的,不到一年前),并且您的需求可能是没那么必要。
最后,index-based 对象的字符串比较很少是个好主意,至少有两个重要原因:
- 在某些时候,您可能需要进行一些本地化;虽然在您的简单情况下,它只是数字的字符串表示形式,但总有一天,简单的“2”可能会变成“text 2”、“texto 2”、“texte 2”或“testo 2”。 基于
- UI 的框架有时会自动更改小部件的显示文本;虽然组合框项通常不是这种情况,但 Qt 有时会更改小部件的文本集以包含 mnemonics:包含可用作键盘快捷键的带下划线字母的文本这在编程上是可读的,因为该字母前面有
&
;结果是您在按钮上设置文本“保存”,然后当您调用button.text()
时,您会得到“&保存”。
因此,考虑到上述情况,这是您可能需要的一种可能实现方式(使用组合项索引而不是字符串):
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_())
最后一点。
在 之前 隐藏小部件显示它们的父级可能是个问题。在上面的示例中,您会注意到,当您再次 select 第二个项目并 然后 第一个时,小部件将自行调整大小。虽然在这种特定情况下,这可能不是什么大问题,但对于复杂的布局来说,从用户体验的角度来看这不是一件好事(用户不喜欢 UI 意外更改其大小)。一种可能的替代方法是使用 QStackedWidget instead, add the labels to it with addWidget()
, and use the combo index to call its 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_())