Search code examples
pythonqtpysideqcomboboxqmenu

How to send index to slot with a QMenu


I am trying to get QComboBox-like behavior using a QPushButton that brings up a QMenu. Namely, when an action is selected, I want to connect to a slot, and for the slot to print out the index of the selected item. Relevant class definition:

from PySide import QtGui, QtCore

class PushIt(QtGui.QWidget):
    def __init__(self):
        QtGui.QWidget.__init__(self)  
        menBut=self.makeQMenuButton()
        self.show()        

    def makeQMenuButton(self):
        button=QtGui.QPushButton("Men...you!", self)           
        pushMenu=QtGui.QMenu(button)
        #Set up each element of menu
        menBut1=pushMenu.addAction("Select me!")
        menBut2=pushMenu.addAction("Don't select me!")
        #What to do when each one is activated
        menBut1.activated[int].connect(self.menButSlot)
        menBut2.activated[int].connect(self.menButSlot) 
        button.setMenu(pushMenu)       
        return button

    @QtCore.Slot(int)
    def menButSlot(self, menDat):
        print "Menu button ", menDat

It sort of works. When I push button 1, for instance, it returns:

Menu button -3

Which is close to what I would get using a combobox, except the counting is seeming to start with -3 instead of 0. I assumed it would start with 0, so I think I am not accessing an index at all, but am toying with powers I do not understand.

I am using PySide within iPython/Anaconda in Windows 7.


Solution

  • According to comment by Pavel Strakhov, the QMenu.activated signal is deprecated. He suggested the use of QSignalMapper to send an index to a slot. This worked great, as follows:

    class PushIt(QtGui.QWidget):
        def __init__(self):
            QtGui.QWidget.__init__(self)  
            menBut=self.makeQMenuButton()
            self.show()        
    
        def makeQMenuButton(self):
            button=QtGui.QPushButton("Men...you!", self)           
            #Set up qmenu and its items
            pushMenu=QtGui.QMenu(button)
            menBut1=pushMenu.addAction("Select me!")
            menBut2=pushMenu.addAction("Don't select me!")
            button.setMenu(pushMenu)   
    
            #set up mapping to create your own indexing scheme
            menuMapping=QtCore.QSignalMapper(self)
            menuMapping.setMapping(menBut1, 0)
            menuMapping.setMapping(menBut2, 1)
    
            menBut1.triggered.connect(menuMapping.map)
            menBut2.triggered.connect(menuMapping.map)
            menuMapping.mapped[int].connect(self.menButSlot) 
    
            return button
    
        @QtCore.Slot(int)
        def menButSlot(self, menDat):
            print "Home-grown triggered index:", menDat
    

    This works exactly as I was hoping (though I am still curious about the strange negative values I was receiving for activated).