【问题标题】:How to define lambda functions to override several slots in Qt? [duplicate]如何定义 lambda 函数以覆盖 Qt 中的多个插槽? [复制]
【发布时间】:2022-01-22 14:07:48
【问题描述】:

我尝试使用 lambda 函数来调用一个方法,该方法从不提供任何参数的插槽中获取参数(QtWidgets.QGroupBox.clicked() 只是触发而不发出任何内容)。

我为几种灯光类型自动构造了几个 QtWidgets.QGroupBox。每个人都应该在 3D 环境中打开/关闭一种照明。这种切换是由对 lightType 的 groupBox 的检查来驱动的,因此这个插槽应该传递它的类型和状态。

这是一个简化的代码:

for lightType in A_CERTAIN_LIST:
    lightTypeBox = QtWidgets.QGroupBox(lightType, self.lightingDock)
    for param in a A_CERTAIN_DIC.keys():
        if param IS_THE_BOOL_PARAM:
            slotLambda = lambda: self.updateLighting(lightType, param, lightTypeBox.isChecked())
            lightTypeBox.clicked.connect(slotLambda)
...

创建的 lightTypeBox 也被添加到一个 dic 中以保留每个的 ref,并在最后添加到它出现的 dockPanel 中。

我确实希望每个 lightTypeBox 都连接自己的 lambda 函数,将适当的参数(lightType、param、bool)传递给我的类 MainWindow(QtWidgets.QMainWindow) 中定义的函数 self.updateLighting:

    @Slot(str, str, bool)
    @Slot(str, str, int)
    @Slot(str, str, float)
    def updateLighting(self, lighting, param, val):
        self.canvas.mainRenderer.setLighting(lighting, param, val)

这有几个@Slot(...) 签名,因为我希望将它与其他 lambdas 一起使用(对于 QspinBox、QDoubleSpinBox 等,仍然要返回它们的设置,对于哪个灯光,对于哪个参数,什么值...)。

但我目前所拥有的是我所有选中/取消选中的组框确实使用定义的最后一个 slotLambda,就好像只定义了一个 lambda 函数,即使在第二个 for 中定义。

我应该做些什么不同的事情?我确实尝试将 lambdas 放在一个列表中,在一个 dic 中,希望将它们分开,而不是在每个参数传递时重写。不知道有没有说清楚...

不管怎样,你看到什么了吗?

【问题讨论】:

    标签: python python-3.x lambda pyqt5 slot


    【解决方案1】:

    好的,

    我明白了:

    我刚刚定义了传递给 lambda 的输入属性:

    slotLambda = lambda lightType=lightType, param=param, lightTypeBox=lightTypeBox: self.updateLighting(lightType, param, lightTypeBox.isChecked())

    所以每个 lambda 都有自己的参数 :-)。

    【讨论】:

    • 虽然这可能有效,但它的可读性很差,并且使调试变得非常困难。我强烈建议您使用自定义信号创建一个专门的 QGroupBox 类,并使用 lightType 和 param 参数创建每个实例,然后连接 clicked 信号(但我强烈建议您使用 @987654322 @ 信号,因为复选框也可以使用键盘切换)到使用所需参数发出自定义信号的函数。此外,clickedtoggled 的第一个参数都是检查状态,因此您的代码在 lightType 参数上方是错误的。
    • 感谢您的反馈。是的,我必须在所有其他参数之前添加 state=lightTypeBox.isChecked() 。我知道这很丑。目前,我所有的 Qt 代码都很丑陋。我尝试让一些功能发挥作用,但很快就会进入重构期,一切都会变得更有条理。
    • 不,使用state=state=lightTypeBox.isChecked() 作为第一个参数也是错误的:关键字参数的默认值总是在定义 lambda 时建立(并评估),所以如果你使用它是错误的,如果你不这样做是没有意义的。正确的语法应该是:lambda checked, lightType=lightType, param=param: self.updateLighting(lightType, param, checked).
    • 再次感谢您回复我。最后我使用了自己的@Slot(PROPER_ARGS_LIST_HERE) 的子类方式,因为它更易于阅读和维护。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-12
    • 2022-01-18
    • 1970-01-01
    • 2018-12-06
    相关资源
    最近更新 更多