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

时间:2017-08-22 14:22:21

标签: python pyqt pyqt5 qcombobox

例如,第一个包含选项A和选项B的组合框。 如果我在第一个组合框中选择选项A,则第二个组合框包含选项1,2,3,4,5。 如果我在第一个组合框中选择选项B,则第二个组合框包含选项a,b,c,d,e。

我怎么能在PyQt5中这样做?我搜索过Qcombobox类,有2个类 activated currentIndexChanged ,但不知道我需要使用哪个以及如何使用它在PyQt5中。

2 个答案:

答案 0 :(得分:2)

我就是这样做的:

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()

这样,您的代码就会更加面向未来,因为如果您希望在某些时候这样做,它可以很容易地添加/修改/删除任何下拉列表中的项目。

答案 1 :(得分:0)

我通过使用3个组合框(让我们称之为x,y和z)来实现它

  1. x包含A,B,用于选择其他组合框中显示的选项。选择A显示组合框y并选择B显示组合框z

  2. y包含1,2,3,4

  3. Z包含a,b,c,d

  4. 我使用QStackedLayout代替第二个组合框,用两个组合框(y和z)加载它,并根据在combobox 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()