Python / PyQt / Qt QMenu QAction语法

时间:2017-06-05 14:39:41

标签: python python-3.x pyqt qt5 pyqt5

我在使用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正确/相同的行为吗?

1 个答案:

答案 0 :(得分:2)

相关的变化发生在PyQt-5.3中。简单地删除旧语法是完全安全,因为这可能很容易在当前和未来的代码中创建一个微妙的错误。

问题是某些信号如triggered将始终发送默认的布尔值,除非您采取措施消除它。 Qt定义了这样的信号:

    triggered(bool checked = false)

PyQt以前将此实现为两个重载:

    triggered(bool checked)
    triggered()

如果你想明确选择后一个重载,你必须使用以下稍微笨拙的sytax:

    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和{{1}等信号你可以通过上面简单的方式将它们全部连接起来。但是,真的,这只是一个等待发生的事故......