gpt4 book ai didi

python - PyQt - 如何将多个信号连接到同一个小部件

转载 作者:行者123 更新时间:2023-12-01 05:56:27 25 4
gpt4 key购买 nike

[ ]All1           [ ]All2        

[ ]checkbox1A [ ]checkbox1B

[ ]checkbox2A [ ]checkbox2B

根据上面的图表,需要发生一些事情:

  1. “全部”复选框仅影响其所在列的开/关,并选中该列中的所有复选框。
  2. 所有复选框都是成对工作的,因此如果 checkbox1A 打开/关闭,checkbox1B 也需要打开/关闭
  3. 如果选中“全部”复选框,然后用户继续选中该列中的一个或多个复选框,则“全部”复选框应取消选中,但所有已选中的复选框应保持选中状态。

所以这实际上更像是一个链式 react 设置。如果复选框 All1 处于打开状态,则 checkbox1A 和 2A 将打开,并且由于它们处于打开状态,因此 checkbox1B 和 2B 也会打开,但复选框 All2 保持关闭状态。我尝试根据此逻辑连接信号,但只有配对逻辑才能 100% 工作。 “全部”复选框逻辑仅在 50% 的时间内有效,而且不准确,并且我无法在不关闭所有已选中的复选框的情况下关闭“全部”复选框。

真的真的需要帮助......T-T

示例代码:

cbPairKeys = cbPairs.keys()
for key in cbPairKeys:
cbOne = cbPairs[key][0][0]
cbTwo = cbPairs[key][1][0]
cbOne.stateChanged.connect(self.syncCB)
cbTwo.stateChanged.connect(self.syncCB)

def syncCB(self):
pairKeys = cbPairs.keys()
for keys in pairKeys:
cbOne = cbPairs[keys][0][0]
cbOneAllCB = cbPairs[keys][0][4]
cbTwo = cbPairs[keys][1][0]
cbTwoAllCB = cbPairs[keys][1][4]

if self.sender() == cbOne:
if cbOne.isChecked() or cbTwoAllCB.isChecked():
cbTwo.setChecked(True)
else:
cbTwo.setChecked(False)
else:
if cbTwo.isChecked() or cbOneAllCB.isChecked():
cbOne.setChecked(True)
else:
cbOne.setChecked(False)

编辑

感谢用户 Avaris 的帮助和耐心,我能够将代码简化为更简洁的代码,并且在第一个和第二个所需行为上 100% 地工作:

#Connect checkbox pairs     
cbPairKeys = cbPairs.keys()
for key in cbPairKeys:
cbOne = cbPairs[key][0][0]
cbTwo = cbPairs[key][1][0]
cbOne.toggled.connect(cbTwo.setChecked)
cbTwo.toggled.connect(cbOne.setChecked)

#Connect allCB and allRO signals
cbsKeys = allCBList.keys()
for keys in cbsKeys:
for checkbox in allCBList[keys]:
keys.toggled.connect(checkbox.setChecked)

当用户现在有选择地关闭模块化复选框时,仅需要关闭“全部”复选框的帮助

最佳答案

如果我理解你的数据结构,我就有一个解决方案。如果我错了,请纠正我:allCBList 是一个dict(令人困惑的名称!:))。它的键是 all* 复选框。值 allCBList[key] 是一个 列表,其中包含与该 all 复选框关联的复选框。对于您的示例结构,它将是这样的:

{ All1 : [checkbox1A, checkbox1B],
All2 : [checkbox2A, checkbox2B]}

那么你需要的是这样的:当一个复选框被切换并且它处于 checked 状态时,那么你需要选中 All* 复选框,如果所有其他复选框处于已选中状态。否则它将被取消选中。

for key, checkboxes in allCBList.iteritems():
for checkbox in checkboxes:
checkbox.toggled.connect(lambda checked, checkboxes=checkboxes, key=key: key.setChecked(checked and all(checkbox.isChecked() for checkbox in checkboxes))

我想,这个陈述需要一些解释:

lambda checked, checkboxes=checkboxes, key=key:

lambda 创建连接到信号的可调用函数。 toggled 传递复选框状态,并将其传递给 checked 变量。 checkboxes=checkboxeskey=key 部分将当前值传递给 lambda 的 checkboxeskey 参数。 (您需要这个,因为 lambda 中的闭包)

接下来是:

key.setChecked(...)

我们正在设置keychecked 状态,这是相应的All* 复选框。在里面:

checked and all(checkbox.isChecked() for checkbox in checkboxes)
如果里面的所有内容都为 True,则

allTrue,我们检查每个复选框的状态。如果所有的都被检查,这将返回True(即isChecked()返回True)。

checked and ... 部分用于短路all。如果当前复选框变为未选中,那么我们不需要检查其他复选框。 All*未选中

(PS:顺便说一句,您不需要获取 dict.keys() 来迭代键。您只需迭代dict,它就会迭代其。)

编辑:为了避免通过单击任何子复选框来切换 All* 复选框的链式 react ,有必要更改 All* 的信号code> 复选框为单击,而不是切换。因此,All* 复选框将在用户交互的情况下影响其下方的其他复选框。

最后,修改后的代码将是:

# Connect checkbox pairs
# you just use the values
# change 'itervalues' to 'values' if you are on Python 3.x
for cbPair in cbPairs.itervalues():
cbOne = cbPair[0][0]
cbTwo = cbPair[1][0]
cbOne.toggled.connect(cbTwo.setChecked)
cbTwo.toggled.connect(cbOne.setChecked)

# Connect allCB and allRO signals
# change 'iteritems' to 'items' if you are on Python 3.x
for key, checkboxes in allCBList.iteritems():
for checkbox in checkboxes:
key.clicked.connect(checkbox.setChecked)
checkbox.toggled.connect(lambda checked, checkboxes=checkboxes, key=key: key.setChecked(checked and all(checkbox.isChecked() for checkbox in checkboxes))

关于python - PyQt - 如何将多个信号连接到同一个小部件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12376253/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com