Pyqt - QMenu动态填充并点击
我需要能够知道我在动态生成的菜单系统中点击了哪些项目。我只想知道我点击了什么,即使它只是一个字符串表示。Pyqt - QMenu动态填充并点击
def populateShotInfoMenus(self):
self.menuFilms = QMenu()
films = self.getList()
for film in films:
menuItem_Film = self.menuFilms.addAction(film)
self.connect(menuItem_Film, SIGNAL('triggered()'), self.onFilmSet)
self.menuFilms.addAction(menuItem_Film)
def onFilmRightClick(self, value):
self.menuFilms.exec_(self.group1_inputFilm.mapToGlobal(value))
def onFilmSet(self, value):
print 'Menu Clicked ', value
而不是直接使用onFilmSet
作为连接的接收器,使用lambda功能,这样你就可以通过额外的参数:
receiver = lambda film=film: self.onFilmSet(self, film)
self.connect(menuItem_Film, SIGNAL('triggered()'), receiver)
看看在Qt的属性系统。你可以动态地添加一个包含字符串或任何你想要的东西的属性,它定义了这个动作。然后,您可以在插槽中使用sender()方法来获取调用该插槽的QObject。然后,查询您设置的属性并相应地执行任何您想要的操作。
但是,这不是最好的方法来做到这一点。不建议使用sender(),因为它违反了面向对象的模块化原则。
最好的方法是使用QSignalMapper类。该类将来自不同对象的信号映射到具有不同参数的相同插槽。
我没有使用过PyQt,因此我不能给你确切的语法或示例,但是应该不难找到一点研究。
我同意这看起来像使用信号映射器的地方。 – 2009-09-23 16:38:36
我想弄清楚一个类似的问题,看了上面的代码后,这是什么对我有用。认为将它们放在一起很好。 =)
self.taskMenu = QtGui.QMenu("Task")
self.tasks = self.getTasks() #FETCHES A LIST OF LIST
self.menuTasks = QtGui.QMenu()
for item in self.tasks:
menuItem_Task = self.taskMenu.addAction(item[1])
receiver = lambda taskType=item[0]: self.setTask(taskType)
self.connect(menuItem_Task, QtCore.SIGNAL('triggered()'), receiver)
self.taskMenu.addAction(menuItem_Task)
def setTask(self,taskType):
print taskType
只是一些额外的信息, 我不知道为什么,但lambda函数不会用新PyQt的语法连接工作:
的代码示例不工作:
self.contextTreeMenuAssignTo = QtGui.QMenu(self)
actionAssign = contextMenu.addMenu(self.contextTreeMenuAssignTo)
actionAssign.setText("Assign to : ")
for user in self.whoCanBeAssignated() :
actionAssignTo = QtGui.QAction(user[0] ,self)
self.contextTreeMenuAssignTo.addAction(actionAssignTo)
actionAssignTo.triggered.connect( lambda userID = user[1] : self.assignAllTo(userID) )
但是如果你用替补多旧式连接语法中的最后一行:
self.connect(actionAssignTo, QtCore.SIGNAL('triggered()'), lambda userID = user[1] : self.assignAllTo(userID) )
一切都很好。 随着新的连接语法,你只能得到循环:(
对我来说(Qt4)它也适用于新的连接语法,请参阅我的评论到这个答案:http://stackoverflow.com/a/1102089/3224008 – Leistungsabfall 2016-05-02 11:51:58
我发现this答案这里处理这一问题PyQt5的最后一个元素,python3。我不喜欢它的BVAL变量是精确,因为我不完全理解它,但它花了很长时间找到,所以我想我会在这里分享。该BVAL从触发拿起布尔值,并允许任务类型传递。
self.taskMenu = QtGui.QMenu("Task")
self.tasks = self.getTasks() #FETCHES A LIST OF LIST
self.menuTasks = QtGui.QMenu()
for item in self.tasks:
menuItem_Task = self.taskMenu.addAction(item[1])
receiver = lambda: bVal, taskType=item: self.setTask(bVal, taskType)
menuItem_Task.triggered.connect(receiver)
self.taskMenu.addAction(menuItem_Task)
def setTask(self, ignore_bVal, taskType):
print taskType
你不需要'bVal'到'setTask',所以你可以摆脱那个丑陋'ignore_bVal'。唯一的要求是你在'lambda'中插入一个初始参数,这样'taskType'参数不会被布尔值覆盖。稍微更健壮(更普遍)的解决方案是用'* args'替换'bVal' - 然后忽略*信号发送的所有可能的*值,并且不改变关键字参数。 – ekhumoro 2016-01-28 19:48:50
感谢这个答案,我能够解决Python3和PyQt5的类似问题。这个想法也可以在这里看到:https:// github。COM /穆阿迈尔/ mkchromecast /提交/ 719fde94e271f97a2047e84b56d7603a5d8cde09 – muammar 2017-01-11 03:53:59
我正在寻找什么,ahhh sweet lambda! – crackerbunny 2009-09-23 22:11:39