无法将 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))
我创建了一个 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))