我们有一个PyQt5应用程序,在Mac OS上从Python2 / PyQt4过渡到Python3 / PyQt5时,存在一个非常具体的问题,其中某些动态填充的菜单无法正常运行。
一个菜单都没有显示,但是我很确定this question的答案将解决该特定问题。另一个看上去很相关,但并不完全相同:将一类动态生成的动作添加到菜单中,但不会触发信号。
维护我们应用程序的Mac版本的贡献者已经提炼出以下MWE,它们完全模仿了菜单的创建方式:
from PyQt5.QtCore import (Qt)
from PyQt5.QtWidgets import (QAction, QApplication, QMainWindow, QMenu)
qApp = QApplication([])
win = QMainWindow()
menu = QMenu()
menu.setTitle('Menu')
menu.triggered.connect(lambda: print('menu.triggered'))
win.menuBar().addMenu(menu)
win.show()
action1 = QAction(win)
action1.setText('Action 1')
action1.triggered.connect(lambda: print('action1.triggered'))
menu.addAction(action1)
action2 = QAction(win)
action2.setText('Action 2')
#menu.addAction(action2)
menu.aboutToShow.connect(lambda: menu.addAction(action2))
menu.aboutToHide.connect(lambda: menu.removeAction(action2), Qt.QueuedConnection)
qApp.exec_()
某些动作传统上是通过menu.addAction()
添加的,而其他动作则是通过与populate()
连接的menu.aboutToShow
函数动态添加的。这些操作没有与之相连的插槽,但是menu.triggered
插槽的实现可以识别单击的操作并相应地进行分配。
在各种Linux系统上,所有这些操作都可以正常运行,但在Mac OS上则不能。
在Mac上运行MWE,单击“动作1”正确地先打印“ action1.triggered”,然后“ menu.triggered”。单击“动作2”,应该打印“ menu.triggered”,但不会。但是,当menu.addAction
行未注释并且后面的两个aboutTo...
注释了时,菜单项将按预期工作。
另一个问题(在顶部链接)是指Mac OS上的QMenu
,要求在将菜单添加到父级时要执行一个活动操作,否则将被认为是空的并被丢弃。我认为这与当前问题有所不同,但是 creation 与 show 时间的关系在这里也可能起作用。但是我不知道我们如何说服QMenu在创建时不知道将在菜单生命周期中添加到菜单中的动作的数量(更不用说实际的事情了)。