我在使用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
正确/相同的行为吗?
答案 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}等信号你可以通过上面简单的方式将它们全部连接起来。但是,真的,这只是一个等待发生的事故......