Pergunta

Eu preciso ser capaz de saber o item I clicou em um sistema de menu gerado dinamicamente. Eu só quero saber o que eu clicado, mesmo que seja simplesmente uma representação de cadeia.

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
Foi útil?

Solução

Em vez de usar onFilmSet diretamente como o receptor de sua conexão, use uma função lambda para que possa passar parâmetros adicionais:

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

Outras dicas

Dê uma olhada em sistema de propriedade do Qt. Você pode adicionar dinamicamente uma propriedade que contém uma string ou qualquer coisa que você deseja, que define a ação. Então você pode usar o método remetente () na ranhura para obter o QObject chamando o slot. Em seguida, consulta a propriedade você definir e fazer o que quiser em conformidade.

Mas, este não é o melhor método para fazer isso. Usando remetente () não é aconselhável, porque viola o princípio de objeto orientado de modularidade.

O melhor método seria usar classe QSignalMapper. Esta classe mapeia sinais de diferentes objetos para o mesmo slot com argumentos diferentes.

Eu não usei PyQt, portanto, eu não posso dar-lhe sintaxe exata ou um exemplo, mas não deve ser difícil de encontrar com um pouco de pesquisa.

Eu estava tentando descobrir um problema semelhante e depois de olhar para o código acima isto é o que funcionou para mim. Pensei que seria bom para mostrar-lo todos juntos. =)

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

Apenas algumas informações adicionais, Eu não sei por que, mas a função lambda não funciona com nova sintaxe PyQt para conexões:

Exemplo de código não funciona:

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

Mas se você subsitute a última linha com a sintaxe antiga conexão estilo:

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

Está tudo bem. Com a nova sintaxe de conexão, você só obter o último elemento do loop: (

este responder aqui para lidar com esta questão em PyQt5, python3. Eu não gosto disso, a variável bVal para ser mais preciso, como eu não entendo totalmente, mas levou muito tempo para encontrar, então eu pensei que eu iria partilhá-la aqui. O bVal pega o valor booleano de acionado e permite que o TaskType a ser passado.

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
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top