Reputation: 3
I'm trying to build off this example that I've came across from here: Right click contextMenu on QPushButton
How would I get this to work when I'm creating the button dynamically? I can't figure out a way to dynamically create the method on_context_menu
.
Here is the code that I have so far.
import sys
from PyQt4 import QtGui,QtCore
import sip
class LayoutTest(QtGui.QWidget):
def __init__(self):
super(LayoutTest, self).__init__()
self.setGeometry(300, 300, 400, 200)
VmasterLayout = QtGui.QVBoxLayout(self)
self.Hbox = QtGui.QHBoxLayout()
for i in range(1,4):
self.butVal = 'buttonMenu_%s' % i
self.button = QtGui.QPushButton(self.butVal)
self.button.clicked.connect(self.allCheckButton)
self.button.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.connect(self.button, QtCore.SIGNAL('customContextMenuRequested(const QPoint&)'), self.on_context_menu)
# create context menu
self.popMenu = QtGui.QMenu(self)
action = QtGui.QActionGroup(self, exclusive=True)
listVer = ['image_v001','image_v003','image_v012','image_v120','image_v140', 'image_v013']
for i, vDir in enumerate(sorted(listVer)):
x = action.addAction(QtGui.QAction( vDir, self, checkable = True))
x.triggered.connect(self.foo(x.text()))
self.popMenu.addAction(x)
self.popMenu.addSeparator()
self.Hbox.addWidget(self.button)
VmasterLayout.addLayout(self.Hbox)
def on_context_menu(self, point):
# show context menu
self.popMenu.exec_(self.button.mapToGlobal(point))
def foo(self, name):
def poo():
print 'Image version is: %s' % name
return poo
def allCheckButton(self):
point = QtGui.QCursor.pos()
print point
def run():
app = QtGui.QApplication(sys.argv)
ex = LayoutTest()
ex.show()
sys.exit(app.exec_())
if __name__ == "__main__":
run()
Upvotes: 0
Views: 1817
Reputation: 3661
I've rewrite this code: python pyqt4 contextMenu on pushButton.
First of all, you need to be able to identify different buttons if you want to create them dynamically, so I've created my own QPushButton
class - MyPushButton
.
After that I've moved on_context_menu
in that class.
And third important thing is that I've connected MainForm
class and MyPushButton
class with buttonXclickedSignal
signal , that gives MainForm
class information which button is clicked so you can handle button clicked signal in MainForm
and do whatever you want for different buttons.
Here is code (run it and try to click buttons and right click on buttons):
import sys
from PyQt4 import QtGui, QtCore
class MyPushButton(QtGui.QPushButton):
def __init__(self, popMenu,elementID, mainForm):
super(MyPushButton, self).__init__()
self.__elementID = elementID
self.__mainForm = mainForm
self.__popMenu = popMenu
self.connect(self, QtCore.SIGNAL('customContextMenuRequested(const QPoint&)'), self.on_context_menu)
self.connect(self, QtCore.SIGNAL('clicked()'), self, QtCore.SLOT("triggerOutput()"))
def on_context_menu(self, point):
# show context menu
self.__popMenu.exec_(self.mapToGlobal(point))
@QtCore.pyqtSlot()
def triggerOutput(self):
self.__mainForm.emit(QtCore.SIGNAL("buttonXclickedSignal(PyQt_PyObject)"), self.__elementID) # send signal to MainForm class
class MainForm(QtGui.QWidget):
def __init__(self, parent=None):
super(MainForm, self).__init__(parent)
self.setGeometry(300, 300, 400, 200)
VmasterLayout = QtGui.QVBoxLayout(self)
self.Hbox = QtGui.QHBoxLayout()
# Custom signal
self.connect(self, QtCore.SIGNAL("buttonXclickedSignal(PyQt_PyObject)"), self.buttonXclicked)
for i in range(1,4):
# create context menu as you like
popMenu = QtGui.QMenu(self)
popMenu.addAction(QtGui.QAction('button %s - test0'%(i), self))
popMenu.addAction(QtGui.QAction('button %s - test1'%(i), self))
popMenu.addSeparator()
popMenu.addAction(QtGui.QAction('button %s - test2'%(i), self))
# create button
self.button = MyPushButton(popMenu, i, self)
self.button.setText("test button %s" %(i))
self.button.resize(100, 30)
# set button context menu policy
self.button.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.Hbox.addWidget(self.button)
VmasterLayout.addLayout(self.Hbox)
def buttonXclicked(self, buttonID):
if buttonID == 1:
#do something , call some method ..
print "button with ID ", buttonID, " is clicked"
if buttonID == 2:
#do something , call some method ..
print "button with ID ", buttonID, " is clicked"
if buttonID == 3:
#do something , call some method ..
print "button with ID ", buttonID, " is clicked"
def main():
app = QtGui.QApplication(sys.argv)
form = MainForm()
form.show()
app.exec_()
if __name__ == '__main__':
main()
Upvotes: 1