QAction 触发信号未传递检查参数

QAction triggered signal is not passing checked parameter

我制作了一个菜单栏,其中 QAction 设置为可检查

self.display_features_action = QtGui.QAction("Show Features", parent)
self.display_features_action.setCheckable(True)
self.display_features_action.setChecked(True)

然后我连接到这个

class MyClass:
    def __init__(....)
         ....
         self.display_features_action.triggered.connect(self.my_slot)

    def my_slot(self, checked)
         ....

但是我得到一个运行时错误,即 my_slot 方法在只提供一个参数时接受参数。为什么检查的参数没有随信号一起发送?

我可以确认此行为。我也看到checked参数没有通过

QAction.triggereddocumentation 有一个默认的 (checked=False) 参数。也许这意味着有时信号在没有额外参数的情况下被调用,然后检查应该是假的。

另一方面,我做了一个小例子,发现从来没有一个额外的参数,虽然偶尔检查应该是 True(如果它被检查)并且 documentation 也说它应该。

所以我想最好的方法是删除那个选中的参数,如果你需要它调用 isChecked:

def my_slot(self, checked=False) # just in case there is an argument
   # just to be sure you really find out if it is checked, store the action and ask
   checked = self.action.isChecked() 

我的示例显示了特定行为(Python 3.4 上的 PySide 1.2.2):

from PySide import QtGui

def test(checked=False):
    print(checked, a.isChecked())

app = QtGui.QApplication([])

t = QtGui.QToolBar()
a = QtGui.QAction('Action', t)
a.setCheckable(True)
a.setChecked(True)
a.triggered.connect(test)
t.addAction(a)
t.show()

app.exec_()

交付

False False
False True

似乎在 PySide 和 PyQt 中处理具有默认参数(例如 triggeredclicked)的信号是不同的。前者不允许在接收槽中有任何位置参数,但后者会毫无怨言地愉快地丢弃未使用的参数。

在 PySide 和 PyQt 中,具有默认参数的信号实际上有两个重载:一个 "no-op" 版本什么都不发送(或者,在 PyQt 中,总是发送 False),一个 "active"版本,它发送当前选中的状态。

"no-op" 版本是默认的,因此要获得 "active" 版本,您必须显式 select 它,如下所示:

    action.triggered[bool].connect(slot)

至于插槽签名:在 PySide 中,最可靠的解决方案可能是这样的:

    def slot(self, checked=False):