Question

Je dois être en mesure de savoir quel élément j'ai cliqué dans un système de menu généré dynamiquement. Je veux seulement savoir ce que j'ai cliqué sur, même si elle est simplement une représentation de chaîne.

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
Était-ce utile?

La solution

Au lieu d'utiliser onFilmSet directement le récepteur de votre connexion, utilisez une fonction lambda afin que vous puissiez passer des paramètres supplémentaires:

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

Autres conseils

Jetez un coup d'oeil au système de propriété de Qt. Vous pouvez ajouter dynamiquement une propriété contenant une chaîne ou tout ce que vous désirez, qui définit l'action. Ensuite, vous pouvez utiliser la méthode sender () dans la fente pour obtenir le QObject appelant la fente. Ensuite, interrogez la propriété que vous définissez et faites ce que vous voulez en conséquence.

Mais, ce n'est pas la meilleure méthode pour le faire. En utilisant l'expéditeur () est déconseillée car elle viole le principe orienté objet de modularité.

La meilleure méthode serait en utilisant la classe QSignalMapper. Cette classe cartes signaux à partir d'objets différents à la même emplacement avec des arguments différents.

Je ne l'ai pas utilisé PyQt donc je ne peux pas vous donner la syntaxe exacte ou un exemple, mais il ne devrait pas être difficile de trouver un peu de recherche.

Je suis en train de trouver un problème similaire et après avoir regardé le code ci-dessus est ce qui a fonctionné pour moi. Je pensais que ce serait bon de montrer tous ensemble. =)

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

Juste quelques informations supplémentaires, Je ne sais pas pourquoi, mais la fonction lambda ne fonctionne pas avec la nouvelle syntaxe PyQt pour les connexions:

Exemple code ne fonctionne pas:

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

Mais si vous Substitut la dernière ligne avec l'ancienne connexion de style syntaxe:

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

Tout va bien. Avec la nouvelle syntaxe de connexion, vous obtenez seulement le dernier élément de la boucle: (

J'ai trouvé cette répondre ici pour traiter de cette question dans PyQt5, python3. Je ne l'aime pas, la variable bVal pour être précis, que je ne comprends pas bien, mais il a fallu beaucoup de temps pour trouver ce que je pensais que je partagerais ici. Le bVal prend la valeur booléenne de déclenchement et permet à l'TaskType à transmettre.

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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top