Python/PyQt/Qt qmen QAction语法

Python/PyQt/Qt qmen QAction语法,python,python-3.x,pyqt,qt5,pyqt5,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) 我想这以前是有用的。我正在移植到Py

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

我负责将一个在Windows下工作的GUI应用程序移植到Linux,并使用较新版本的库。我没有访问Windows下运行的原始文件的权限

我在几个地方看到:

menu = QMenu(self)
action = menu.addAction("Some string")
action.triggered[()].connect(self.handler)
我想这以前是有用的。我正在移植到Python3.5、Pyqt5.7和Qt5.7。我有理由相信这段代码是为这些代码的早期版本编写的

现在执行它会在
操作上生成一个
“没有匹配的重载信号”
错误。已触发[()]

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

action.triggered.connect(self.handler)
现在它似乎起作用了


有人能解释一下原始的
触发[()]
语法是什么意思/起作用的,以及明显的变化是在哪个“产品”中——如果能读到这些变化的地方,那该多好啊?用
替代我是否触发了
正确/相同的行为?

相关的更改发生在PyQt-5.3中。仅仅删除旧语法是不完全安全的,因为这很容易在当前和将来的代码中产生一个微妙的bug

问题在于,某些信号(如
触发的
)将始终发送默认布尔值,除非您采取措施消除它。Qt对这些信号的定义如下:

    triggered(bool checked = false)
    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)
PyQt以前将其实现为两个重载:

    triggered(bool checked)
    triggered()
如果要显式选择后一个重载,则必须使用以下略显笨拙的sytax:

    triggered[()].connect(slot)
但现在这不再是一个选项,因为只实现了第一个重载。因此,要获得完全相同的行为,必须像这样包装处理程序:

    triggered(bool checked = false)
    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)
或者像这样装饰它:

    triggered(bool checked = false)
    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)
否则,很容易落入一个小陷阱。假设您有一个定义如下的方法:

    triggered(bool checked = false)
    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)
稍后,您决定将其连接到一个按钮,如下所示:

    triggered(bool checked = false)
    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)
这一切似乎都很好,直到您发现单击的
信号与触发的
信号一样工作,并且默认情况下总是发送
False


当然,如果您绝对确定您永远不会连接带有参数的插槽,例如
触发的
单击的
,那么您可以用上面所示的简单方式连接它们。但是,真的,这只是一个等待发生的意外…

这就是我所希望的答案!请您澄清一下触发[()]
的(语法)含义是什么?我是Python新手。那是“一个
()
”数组吗。参数类型的元组用于选择所需的特定重载。
()
是空元组,意思是:选择不带参数的重载。@JonBrave。我可能应该补充一点,信号是实现。从概念上讲,它们更像是一个
dict
(映射),而不是一个数组——尽管在某种程度上,python的duck类型允许以几乎相同的方式处理它们。有没有PyQt-5.3的文档链接来列举这种行为变化?我可以通过寻找其他潜力@乔恩布拉夫。试试看:在厨房里。