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

Posted

技术标签:

【中文标题】基于用户选择的标签组合框状态【英文标题】:Combo box state of labels based on the user`s choice 【发布时间】:2020-10-09 20:59:30 【问题描述】:

我有一个包含两个选项的组合框,我希望组合框中的选择将确定两个标签的状态。我的意思是,例如,如果用户选择“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() 

【问题讨论】:

请提供minimal reproducible example 不,使用循环当然不是一个好的实现。你为什么使用textActivated 而不是currentTextChanged?你为什么使用[QString] 语法?对于只有一种可能签名的信号(如 QComboBox 的所有信号),不需要选择信号签名。最后,如果要检查文本,信号已经在参数中提供了它,无需检查currentText() 属性。 您好,首先感谢您的回答。其次,我对 Gui 这个东西和 pyqt5 真的很陌生,所以我只是凭直觉做的。最后,我可以请你给我看一个它应该如何工作的例子吗?我没成功l。 @musicamante 【参考方案1】:

主要问题是一旦选择了组合框中的项目,就会发送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_())

【讨论】:

好的,谢谢您的详细解答。从那个答案中学到了很多。欣赏它。

以上是关于基于用户选择的标签组合框状态的主要内容,如果未能解决你的问题,请参考以下文章

下拉菜单(选择标签、组合框)在 GeckoView 实现中不起作用

将标签和组合框放在一起

如何为组合框和列表中的选项添加标签?

用户选择Combobox然后根据数据库MS Access c#标签

combotree(组合树)的使用

影响 Access 中报告长度的不可见标签和组合框