Python/PyQt/Qt QMenu QAction 语法

问题描述 投票:0回答:1

我在使用 Python 3、PyQt5 和 Qt5 的应用程序中遇到语法/理解问题。我不确定其中哪一个导致了问题。

我负责将在 Windows 下运行的 GUI 应用程序移植到 Linux 上,并使用更新版本的库。我无法访问在 Windows 下运行的原始版本。

在几个地方我看到:

menu = QMenu(self)
action = menu.addAction("Some string")
action.triggered[()].connect(self.handler)

我认为这曾经有效。我正在移植到 Python 3.5、PyQt 5.7 和 Qt 5.7。我有理由相信代码是为每个版本的早期版本编写的。

现在执行它会在

'there is no matching overloaded signal'
段上生成
action.triggered[()]
错误。

通过猜测并查看我在某处找到的几个示例,我将最后一行更改为:

action.triggered.connect(self.handler)

现在似乎可以工作了。

有人可以解释一下原始的

triggered[()]
语法的含义/作用是什么,以及明显的变化是在哪个“产品”中——如果能够阅读到它在哪里发生了变化,那就太好了?我的替换只是
triggered
正确/相同的行为吗?

python python-3.x pyqt5 signals-slots qaction
1个回答
4
投票

相关更改发生在 PyQt-5.3 中。简单地删除旧语法完全安全,因为这很容易在当前和未来的代码中产生微妙的错误。

问题在于某些信号(如

triggered
)将始终发送默认布尔值,除非您采取措施消除它。 Qt 像这样定义这些信号:

    triggered(bool checked = false)

PyQt 之前将其实现为两个重载:

    triggered(bool checked)
    triggered()

如果您想明确选择后一个重载,则必须使用以下稍微尴尬的语法:

    triggered[()].connect(slot)

但是现在这不再是一种选择,因为只实现了第一个重载。因此,为了获得完全相同相同的行为,有必要像这样包装处理程序:

    triggered.connect(lambda checked: slot())

或者像这样装饰它:

    @QtCore.pyqtSlot()
    def handleTriggered(self):
        pass

否则,很容易陷入一个小陷阱。想象一下你有一个这样定义的方法:

    def frobnicate(self, foobar=True):
        if foobar:
            # do something nice
        else:
            # empty my home directory without prompting

后来,您决定将其连接到一个按钮,如下所示:

    self.button.clicked.connect(self.frobnicate)

一切看起来都很好,直到您发现

clicked
信号的工作方式与
triggered
一样,并且默认情况下始终发送
False
...

当然,如果您绝对确定您将永远不会连接带有参数的插槽,例如

triggered
clicked
,您可以按照上面所示的简单方式将它们全部连接起来。但是,实际上,这只是一场等待发生的事故......

© www.soinside.com 2019 - 2024. All rights reserved.