基于用户选择的标签组合框状态

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 编辑后立即发送。

虽然这看起来很直观,但您必须考虑以下几个方面。

  1. 即使该项目已经是当前一个
  2. 也会发送信号
  3. 由于上述原因,每当用户激活组合中的项目时,它也会始终发送,这也会发生在用户:
    • 使用键盘导航(箭头键,home/end,页面 up/down);
    • 使用键盘在组合项中搜索;
    • 在可编辑的组合上按回车键;
    • 点击弹出窗口中的项目;
  4. 键盘交互或鼠标selection 不会立即更新视图的内容,包括currentText() 属性,因为Qt需要一些时间来完成它的东西(通常,如果可编辑组合有要添加的新项目,则更新组合模型)

此外,需要考虑的一个重要方面是 textActivated 是一个相当新的功能(它是在 2019 年底的 Qt 5.14 中引入的,不到一年前),并且您的需求可能是没那么必要。

最后,index-based 对象的字符串比较很少是个好主意,至少有两个重要原因:

  1. 在某些时候,您可能需要进行一些本地化;虽然在您的简单情况下,它只是数字的字符串表示形式,但总有一天,简单的“2”可能会变成“text 2”、“texto 2”、“texte 2”或“testo 2”。
  2. 基于
  3. 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_())