无法将 QMenu 项中的 'checked' 状态和自定义参数传递给连接的插槽

Can't pass 'checked' state and custom parameter in QMenu items to connected slot

我创建了一个 QMenu 并在菜单中添加了一些可检查的 QAction 项目。所有这些项目都连接到同一个槽函数。

如果单击可勾选的 QAction,则会发出 triggered 信号并将勾选标记 is passed as an argument 的状态发送到已连接的槽函数。

在插槽函数中我想区分点击的项目。除了传递 checked 状态之外,我还尝试通过使用 lambda 将索引传递给槽函数来做到这一点。

我唯一无法实现的是将 checked 状态和我的索引都传递给槽函数。

请参阅下面的示例代码。示例中 slot 变量的不同变体显示了我到目前为止的尝试。

import sys
from PySide2 import QtCore
from PySide2.QtWidgets import (QMainWindow, QApplication, QAction)

class Window(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        # create menu
        self.dynamic_menu = self.menuBar().addMenu('tools')
        # add menu items
        labels = ['tool0', 'tool1', 'tool2']
        for index, label in enumerate(labels):
            # passes 'checked' correctly, but 'index' is always 2 (last loop value)
            # slot = lambda checked: self.run_menu_item(checked, index)
            #
            # Throws exception:
            #   TypeError: <lambda>() missing 1 required positional argument: 'checked'
            # slot = lambda checked, i=index: self.run_menu_item(checked, i)
            #
            # passes 'checked' always as False, but index is correct
            slot = lambda checked=False, i=index: self.run_menu_item(checked, i)

            action = QAction(label, self)
            action.triggered.connect(slot)
            action.setCheckable(True)
            self.dynamic_menu.addAction(action)
            
    @QtCore.Slot(bool, int)
    def run_menu_item(self, checked, index):
        print('checked:{} index:{}'.format(checked, index))


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = Window()
    window.setMinimumSize(400, 100)
    print('starting app...')
    window.show()
    sys.exit(app.exec_())

如何定义 slot 以便同时获得菜单项的 checked 状态以及作为槽函数参数的正确索引 run_menu_item?

既然triggered是一个过载信号,那么签名必须指出:action.triggered[bool].connect(slot).

class Window(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        # create menu
        self.dynamic_menu = self.menuBar().addMenu("tools")
        # add menu items
        labels = ["tool0", "tool1", "tool2"]
        for index, label in enumerate(labels):
            slot = lambda checked, i=index: self.run_menu_item(checked, i)
            action = QAction(label, self)
            action.triggered[bool].connect(slot)
            action.setCheckable(True)
            self.dynamic_menu.addAction(action)

    @QtCore.Slot(bool, int)
    def run_menu_item(self, checked, index):
        print("checked:{} index:{}".format(checked, index))