Pyqt - QMenu 动态填充和单击

发布于 2024-08-05 02:09:14 字数 543 浏览 2 评论 0原文

我需要能够知道我在动态生成的菜单系统中单击了哪个项目。我只想知道我点击了什么,即使它只是一个字符串表示形式。

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

I need to be able to know what item I've clicked in a dynamically generated menu system. I only want to know what I've clicked on, even if it's simply a string representation.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

度的依靠╰つ 2024-08-12 02:09:14

不要直接使用 onFilmSet 作为连接的接收者,而是使用 lambda 函数来传递其他参数:

receiver = lambda film=film: self.onFilmSet(self, film)
self.connect(menuItem_Film, SIGNAL('triggered()'), receiver)

Instead of using onFilmSet directly as the receiver of your connection, use a lambda function so you can pass additional parameters:

receiver = lambda film=film: self.onFilmSet(self, film)
self.connect(menuItem_Film, SIGNAL('triggered()'), receiver)
蘸点软妹酱 2024-08-12 02:09:14

我在这里找到了这个答案在 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

I found this answer here for dealing with this issue in PyQt5, python3. I don't like it, the bVal variable to be precise, as I don't fully understand it but it took a long time to find so I thought I'd share it here. The bVal picks up the boolean value from triggered and allows the taskType to be passed.

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
烟柳画桥 2024-08-12 02:09:14

看一下Qt 的属性系统。您可以动态添加包含字符串或任何您想要的内容的属性,它定义了操作。然后你可以使用槽中的sender()方法来获取调用该槽的QObject。然后,查询您设置的属性并相应地执行您想要的操作。

但是,这不是最好的方法。不建议使用 sender(),因为它违反了面向对象的模块化原则。

最好的方法是使用 QSignalMapper 类。此类将来自不同对象的信号映射到具有不同参数的同一槽。

我没有使用过 PyQt,因此我无法为您提供确切的语法或示例,但通过一些研究应该不难找到。

Take a look at the Qt's property system. You can dynamically add a property containing a string or anything you desire, which defines the action. Then you can use sender() method in the slot to obtain the QObject calling the slot. Then, query the property you set and do whatever you want accordingly.

But, this is not the best method to do this. Using sender() is not advised because it violates the object oriented principle of modularity.

The best method would be using QSignalMapper class. This class maps signals from different objects to the same slot with different arguments.

I haven't used PyQt therefore i cannot give you exact syntax or an example, but it shouldn't be hard to find with a little research.

太阳公公是暖光 2024-08-12 02:09:14

我试图找出类似的问题,在查看上面的代码后,这对我有用。认为将所有内容一起展示会很好。 =)

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

I was trying to figure out a similar issue and after looking at the code above this is what worked for me. Thought it would be good to show it all together. =)

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
寂寞陪衬 2024-08-12 02:09:14

只是一些附加信息,
我不知道为什么,但 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 )  )    

一切都很好。
使用新的连接语法,您只能获得循环的最后一个元素:(

Just some additional information,
I don't know why, but lambda function doesn't work with new pyqt syntax for connections :

Example of code not working :

    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 )  )

But if you subsitute the last line with the old style connection syntax :

self.connect(actionAssignTo, QtCore.SIGNAL('triggered()'),  lambda userID = user[1] :  self.assignAllTo( userID )  )    

Everything is fine.
With the new connection syntax, you only get the last element of the loop :(

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文