我试图减少我在上下文中使用的信号量。菜单包括切换程序操作模式的动作,因此插槽执行的操作非常简单。引用QMenu :: triggered,
上的文档通常,您将每个菜单操作的triggered()信号连接到其自己的自定义插槽,但有时您需要将多个操作连接到单个插槽,例如,当您有一组密切相关的操作时,例如“左对齐“,”中心“,”右对齐“。
但是,我无法弄清楚如何实现这一点,文档没有进一步详细说明
假设我在菜单actionOpMode1
中有actionOpMode2
和actionMenu
,以及一个广告符setOpMode
。我希望用一个参数来调用setOpMode
,该参数在某种程度上与触发了哪些动作有关。我尝试了这个主题的各种排列:
QObject.connect(self.actionMenu, SIGNAL('triggered(QAction)'), self.setOpMode)
但是我从来没有得到它来调用setOpMode,这表明actionMenu永远不会“感觉被触发”,可以这么说。
在this SO question中,建议可以使用lamdbas完成,但是这样:
QObject.connect(self.actionOpMode1, SIGNAL('triggered()'), lambda t: self.setOpMode(t))
给出"<lambda> () takes exactly 1 argument (0 given)"
。我不能说我真的明白这是怎么回事,所以从clicked()转到trigger()时我可能做错了。
怎么做?
答案 0 :(得分:4)
使用QObject.Sender是解决方案之一,尽管不是最干净的解决方案。
使用QSignalMapper将值与发出信号的对象完全关联。
答案 1 :(得分:2)
我使用这种方法:
from functools import partial
def bind(self, action, *params):
self.connect(action, QtCore.SIGNAL('triggered()'),
partial(action, *params, self.onMenuAction))
def onMenuAction(self, *args):
pass
bind(self.actionOpMode1, 'action1')
bind(self.actionOpMode2, 'action2')
答案 2 :(得分:1)
您可以使用QObject::sender()来确定发出信号的QAction。
所以你的插槽可能如下所示:
def triggered(self):
sender = QtCore.QObject.sender()
if sender == self.actionOpMode1:
# do something
elif sender == self.actionOpMode2:
# do something else
关于你在lambda中提到的另一个SO问题中发生了什么,它所做的是创建一个带有一个参数的lambda,该参数具有默认值,因此要将其应用于您的示例,您需要执行以下操作:
self.connect(self.actionOpMode1, QtCore.SIGNAL('triggered()'), lambda who="mode1": self.changeMode(who))
self.connect(self.actionOpMode2, QtCore.SIGNAL('triggered()'), lambda who="mode2": self.changeMode(who))
然后有一个像这样的成员函数:
def changeMode(self, who):
if who == "mode1":
# ...
elif who == "mode2":
# ...
就个人而言,第一种方法看起来更清晰,更易读。