Вопрос

Мне нужно иметь возможность знать, на какой элемент я нажал в динамически генерируемой системе меню.Я только хочу знать, на что я нажал, даже если это просто строковое представление.

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 непосредственно в качестве получателя вашего соединения используйте лямбда-функцию, чтобы вы могли передавать дополнительные параметры:

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

Другие советы

Взгляните на систему свойств Qt.Вы можете динамически добавлять свойство, содержащее строку или что угодно по вашему желанию, которое определяет действие.Затем вы можете использовать метод sender() в слоте, чтобы получить QObject, вызывающий слот.Затем запросите заданное вами свойство и делайте соответственно все, что хотите.

Но это не лучший способ сделать это.Использовать sender() не рекомендуется, поскольку это нарушает объектно-ориентированный принцип модульности.

Лучшим методом было бы использование класса QSignalMapper.Этот класс отображает сигналы от разных объектов в один и тот же слот с разными аргументами.

Я не использовал PyQt, поэтому не могу привести вам точный синтаксис или пример, но его не должно быть трудно найти при небольшом исследовании.

Я пытался разобраться с аналогичной проблемой, и после просмотра приведенного выше кода это то, что сработало у меня.Подумал, что было бы неплохо показать все это вместе.=)

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

Просто немного дополнительной информации, Я не знаю почему, но лямбда-функция не работает с новым синтаксисом 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 )  )    

Все в порядке.С новым синтаксисом подключения вы получаете только последний элемент цикла :(

Я нашел это ответьте здесь за решение этой проблемы в PyQt5, python3.Мне это не нравится, точнее, переменная BVal, поскольку я не до конца понимаю ее, но на поиск ушло много времени, поэтому я решил поделиться ею здесь.BVal выбирает логическое значение из triggered и разрешает передачу TaskType .

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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top