Pyqt - 动态填充并点击的QMenu

6 投票
5 回答
7672 浏览
提问于 2025-04-15 14:32

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

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

5 个回答

1

看看Qt的属性系统。你可以动态地添加一个属性,这个属性可以是字符串或者你想要的任何东西,用来定义某个动作。然后你可以在槽函数中使用sender()方法来获取调用这个槽的QObject对象。接着,你可以查询你设置的属性,并根据这个属性做你想做的事情。

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

更好的方法是使用QSignalMapper类。这个类可以把来自不同对象的信号映射到同一个槽函数,但可以传递不同的参数。

我没有使用过PyQt,所以不能给你确切的语法或例子,但稍微查一下应该不难找到。

2

我在这里找到了一些关于如何在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
11

与其直接使用 onFilmSet 来接收你的连接,不如使用一个 lambda 函数,这样你就可以传递额外的参数了:

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

撰写回答