PyQt中的Qcombobox,我如何在一个组合框中设置选项取决于其他组合框的选择?

问题描述:

例如,带有选项A和选项B的第一个组合框。 如果我在第一个组合框中选择选项A,则第二个组合框包含选项1,2,3,4,5。 如果我在第一个组合框中选择选项B,第二个组合框包含选项a,b,c,d,e。PyQt中的Qcombobox,我如何在一个组合框中设置选项取决于其他组合框的选择?

我怎么能在PyQt5中做到这一点?我搜索了Qcombobox类,有2个类activatedcurrentIndexChanged,但不知道我需要使用哪一个以及如何在PyQt5中使用它。

这是我会怎么做:

import sys 
from PyQt5 import QtWidgets 


class ComboWidget(QtWidgets.QWidget): 

    def __init__(self, parent=None): 
     super(ComboWidget, self).__init__(parent) 
     self.setGeometry(50, 50, 200, 200) 

     layout = QtWidgets.QVBoxLayout(self) 

     self.comboA = QtWidgets.QComboBox() 
     # The second addItem parameter is itemData, which we will retrieve later 
     self.comboA.addItem('A', ['1', '2', '3', '4']) 
     self.comboA.addItem('B', ['a', 'b', 'c', 'd', 'e']) 
     self.comboA.currentIndexChanged.connect(self.indexChanged) 
     layout.addWidget(self.comboA) 

     self.comboB = QtWidgets.QComboBox() 
     # We could have added the 1,2,3,4 items directly, but the following 
     # is a bit more generic in case the combobox starts with a different 
     # index for some reason: 
     self.indexChanged(self.comboA.currentIndex()) 
     layout.addWidget(self.comboB) 

     self.show() 

    def indexChanged(self, index): 
     self.comboB.clear() 
     data = self.comboA.itemData(index) 
     if data is not None: 
      self.comboB.addItems(data) 


def main(): 
    app = QtWidgets.QApplication(sys.argv) 
    w = ComboWidget() 
    sys.exit(app.exec_()) 

if __name__ == '__main__': 
    main() 

这样一来,你的代码是多一点面向未来的,因为这将允许您添加/修改/删除任何项目如果你想在某些时候这么做,很容易。

+2

我发现你的目标是寻找更通用的解决方案 - 但将用户可见的文本用作密钥是有问题的,因为如果您需要支持其他语言,它很容易破损。 Qt已经提供了一个API来直接关联项目和数据:[QComboBox.itemData](https://doc.qt.io/qt-5/qcombobox.html#itemData)。所以这可以用来存储值列表本身,或者,甚至更好的是动态生成它们的函数。 – ekhumoro

+0

@ekhumoro,嗨,你的意思是使用“QComboBox.setitemdata”来设置数据,并使用“QComboBox。的ItemData”为检索数据? – Kester

+0

@Kester。是的,他的想法,或者,更方便,通过*'userdata' *参数addItem'的'添加数据,并通过'currentData'检索。 – ekhumoro

我把它用3个组合框的工作(可以称它们的x,y和z)

  1. x包含A,B和用于选择哪些选项出现在其他组合框。选择一个显示的组合框y和选择B表示组合框ž

  2. y保存1,2,3,4

  3. Z含有A,B,C,d

我使用的QStackedLayout在第二个组合框的位置,加载了两个组合框(y和z),并根据在组合框x中选择哪个选项一次显示其中的一个。

方法comboOptionChanged处理这个。 只要选择组合框x中的不同选项,就会调用此方法。

import sys 
from PyQt5.QtWidgets import QWidget, QComboBox, QApplication, QFormLayout, QLabel,QStackedLayout 

class DynamicComboExample(QWidget): 
    def __init__(self): 
     super().__init__() 
     self.setupUI() 

    def setupUI(self): 
     self.setGeometry(300,300, 500, 300) 
     self.show() 

     combo_a = QComboBox(self) 
     combo_a.addItem('A') 
     combo_a.addItem('B') 

     # set slot for when option of combobox A is changed 
     combo_a.currentIndexChanged[int].connect(self.comboOptionChanged) 

     self.combo_b = QComboBox() 
     self.combo_b.addItem('1') 
     self.combo_b.addItem('2') 
     self.combo_b.addItem('3') 
     self.combo_b.addItem('4') 

     self.combo_c = QComboBox() 
     self.combo_c.addItem('a') 
     self.combo_c.addItem('b') 
     self.combo_c.addItem('c') 
     self.combo_c.addItem('d') 
     self.combo_c.addItem('e') 

     # use a stacked layout to view only one of two combo box at a time 
     self.combo_container_layout = QStackedLayout() 

     self.combo_container_layout.addWidget(self.combo_b) 
     self.combo_container_layout.addWidget(self.combo_c) 

     combo_container = QWidget() 
     combo_container.setLayout(self.combo_container_layout) 

     form_layout = QFormLayout() 

     form_layout.addRow(QLabel('A:\t'), combo_a) 

     # the stacked layout is placed in place of the (meant to be) second combobox 
     form_layout.addRow(QLabel('B:\t'), combo_container) 


     self.setLayout(form_layout) 


    def comboOptionChanged(self, idx): 
     ''' gets called when option for combobox A is changed''' 

     # check which combobox_a option is selected ad show the appropriate combobox in stacked layout 
     self.combo_container_layout.setCurrentIndex(0 if idx == 0 else 1) 


def main(): 
    app= QApplication(sys.argv) 
    w = DynamicComboExample() 
    exit(app.exec_()) 

if __name__ == '__main__': 
    main() 
+0

感谢您的帮助。是否有必要使用两个组合框来解决这个问题? – Kester

+0

是的,只有使用一个组合框才能获得相同结果的方法是删除所有当前选项,然后在用户每次选择第一个组合框中的不同选项时添加新选定组合框的所有选项。这是你应该避免的。 – Anonta

+0

为什么要让组合框具有动态数据有待避免?重新填充QComboBox的项目毕竟不是一个非常昂贵的操作,尤其是对于少量的项目 – FernAndr