【问题标题】:How to make a QComboBox group mutually exclusive?如何使 QComboBox 组互斥?
【发布时间】:2021-02-07 13:06:26
【问题描述】:

一旦在组合中选择了一个项目,它应该从其他项目中删除,除非它是“无用”。

我做了三个 QComboBox 选项,每个选项都包含相同的项目。

解释是这样的:

  • QCombobox Tug 1 共有 4 个项目('No Use'、'207HR'、'306DR'、'Jupiter')

  • QCombobox Tug 2 共有 4 个项目('No Use'、'207HR'、'306DR'、'Jupiter')

  • QCombobox Tug 3 共有 4 个项目('No Use'、'207HR'、'306DR'、'Jupiter')

那些Qcombobox的默认值为'No Use'。

如何从 QComboBox Tug 2 中删除 QComboBox Tug 1 的选定值?

重点是不能去掉“No Use”;只有“207HR”、“306DR”和“Jupiter”中的一项。

我制作的代码如下:

class Ship_Use_Tug_Input_Program(QWidget):
    def __init__(self, master):
        super().__init__()
        self.initUI()

    def initUI(self):
        tug1_cb = QComboBox(self)
        jeju_tug = ['No use','207HR (2,500HP)', '306DR (3,600HP)', 'Jupiter (3,600HP)']
        tug1_cb.addItems(jeju_tug)

        tug2_cb = QComboBox(self)
        tug2_cb.addItems(jeju_tug)

        tug3_cb = QComboBox(self)
        tug3_cb.addItems(jeju_tug)

        self.setGeometry(100,100,1000,500) 
        self.setWindowTitle('Ship_Use_Tug_Input_Program')
        self.show()
app = QApplication(sys.argv)
exc = Ship_Use_Tug_Input_Program(master=Ship_Use_Tug_Input_Program)
app.exec_()

解说图如下:

【问题讨论】:

  • 不要多次发布同一个问题,因为这很烦人
  • 对不起,我这样做是因为我想说明我的问题的重点。作为您的建议,我已经删除了上一个问题
  • 您已经在 SO 中发表了几篇文章,因此您应该已经知道规则:如果您想改进一个问题,那么只需编辑它。如果你不知道规则然后检查How to Ask并传递tour,这样你就不会继续造成烦恼,然后不要抱怨系统阻止了创建新帖子的能力

标签: python pyqt5 qcombobox mutual-exclusion


【解决方案1】:

组合框的view-widget 可用于隐藏行,item-data 可用于跟踪哪个组合框正在显示哪一行。连接到activated signal 的插槽可以在当前项目之一更改时更新项目。

以下是实现该功能的完整演示脚本。 ExclusiveComboGroup 类可以与任何组合框组一起使用。要使用它,只需创建一个实例,然后使用其 addCombo 方法添加所有组合框。

演示脚本

import sys
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *

class ExclusiveComboGroup(QObject):
    def __init__(self, parent=None):
        super().__init__(parent)
        self._combos = []
        self._role = Qt.UserRole + 500

    def addCombo(self, combo):
        combo.activated.connect(
            lambda: self.handleActivated(combo))
        self._combos.append(combo)

    def handleActivated(self, target):
        index = target.currentIndex()
        groupid = id(target)
        for combo in self._combos:
            if combo is target:
                continue
            previous = combo.findData(groupid, self._role)
            if previous >= 0:
                combo.view().setRowHidden(previous, False)
                combo.setItemData(previous, None, self._role)
            if index > 0:
                combo.setItemData(index, groupid, self._role)
                combo.view().setRowHidden(index, True)

class Window(QWidget):
    def __init__(self):
        super().__init__()
        self.group = QGroupBox('Selected Tug')
        layout = QVBoxLayout(self)
        layout.addWidget(self.group)
        layout = QFormLayout(self.group)
        layout.setVerticalSpacing(15)
        layout.setHorizontalSpacing(50)
        jeju_tug = [
            'No use',
            '207HR (2,500HP)',
            '306DR (3,600HP)',
            'Jupiter (3,600HP)',
            ]
        # create a combo-group
        self.tugs = ExclusiveComboGroup(self)
        for index in range(3):
            combo = QComboBox(self)
            combo.addItems(jeju_tug)
            layout.addRow(f'Tug {index + 1}', combo)
            # add the combo-box
            self.tugs.addCombo(combo)

if __name__ == "__main__":

    app = QApplication(sys.argv)
    window = Window()
    window.setWindowTitle('Demo')
    window.setGeometry(800, 200, 100, 50)
    window.show()
    sys.exit(app.exec_())

PS:这是在您自己的示例中使用它的方法:

def initUI(self):
    tug1_cb = QComboBox(self)
    jeju_tug = ['No use','207HR (2,500HP)', '306DR (3,600HP)', 'Jupiter (3,600HP)']
    tug1_cb.addItems(jeju_tug)

    tug2_cb = QComboBox(self)
    tug2_cb.addItems(jeju_tug)

    tug3_cb = QComboBox(self)
    tug3_cb.addItems(jeju_tug)
    
    # copy the ExclusiveComboGroup class into
    # your code and then add this section
    tugs = ExclusiveComboGroup(self)
    tugs.addCombo(tug1_cb)
    tugs.addCombo(tug2_cb)
    tugs.addCombo(tug3_cb)

【讨论】:

  • 感谢您的友好解决方案!不过先生,我还有一个问题。如何使用“.move”将“QGroupbox”、“Labels”和“Qcombobox”放置到我想要的位置?
  • @WoodyKim 我已经在回答的最后展示了如何做到这一点。 ExclusiveComboGroup 类复制到您的代码中,然后创建它的一个实例并添加您的组合框。您不需要演示脚本中的任何其他内容。 (PS:如果你觉得我的回答有用,请接受——即点击上面的勾号)。
  • 天啊。有用!!感谢您的天才解决方案。我为此绞尽脑汁将近 1 个月,但您立即解决了!我已经在你的答案上面打勾了!!谢谢先生!!!:))
  • 先生,我试图理解你在上面写的'class ExclusiveComboGroup(Qobject)'部分的代码,但在我短暂的编码经验中,我无法理解.....如果你解释代码和信号的原理去哪里去哪里它工作,这将更有利于你的声誉。谢谢楼主
  • @WoodyKim 每当用户在组合框中选择一个项目时,都会发出激活信号。它连接到handleActivated 方法,该方法更新其他组合框。每个组合框中的项目数据记录任何其他组合框的 id,该组合框将该项目作为其当前项目,并根据需要隐藏/显示该项目。
猜你喜欢
  • 2011-12-26
  • 2011-02-12
  • 2015-10-19
  • 2015-04-28
  • 1970-01-01
  • 1970-01-01
  • 2021-12-20
相关资源
最近更新 更多