[PyQt] adding context menu to graphics item

Christopher M. Nahler christopher.nahler at papermodels.at
Thu Jul 8 10:34:57 BST 2010


I need some help on how to add a context menu to a graphics item.

In the sample code below I have an action (editAction) on a menu 
(myMenu) that is only enabled if a item is selected.

Now I would like to have this menu show up as a context menu when I 
right click the rect item in the scene/view.

I think the way to do this is to do my own processing of the 
contextMenuEvent. But what is the best way to do that?

Store the menu in the scene so that I can access it from the 
graphicsItem? And then do a menu.exec in the contextMenuEvent handler?

Or are they better ways to do this? Is there some route with signalling?

Thanks in advance
Chris


from PyQt4.QtCore import *
from PyQt4.QtGui import *

class MyRect(QGraphicsRectItem):
     def __init__(self, parent=None, scene=None):
         super(MyRect, self).__init__(parent, scene)

     def contextMenuEvent(self, contextEvent):
         print("cme")

class MyView(QGraphicsView):
     def __init__(self, parent=None):
         super(MyView, self).__init__(parent)
         self.setMouseTracking(True)
         self.scale(1,1)

     def mouseMoveEvent(self, mouseEvent):
         self.emit(SIGNAL("updateCoords"), 
self.mapToScene(mouseEvent.pos()))
         super(MyView, self).mouseMoveEvent(mouseEvent)

class MyScene(QGraphicsScene):

     def __init__(self, parent=None):
         super(MyScene, self).__init__(parent)

         someRect = MyRect()
         someRect.setRect(0, 0, 160, 80)
         someRect.setBrush(QBrush(Qt.white, Qt.SolidPattern))
         someRect.setFlag(QGraphicsItem.ItemIsSelectable, True)
         someRect.setFlag(QGraphicsItem.ItemIsMovable, True)

         self.addItem(someRect)


class MainWindow(QMainWindow):

     def __init__(self, parent=None):
         # call parent init
         super(MainWindow, self).__init__(parent)
         self._iconState = False

         # setup scene object
         self.scene = MyScene()

         # setup view object
         self.view = MyView()

         self.myAction = createAction(self, "my Action",
                                       self.testslot,
                                       Qt.Key_T,
                                       "info.ico",
                                       self.tr(" my Action comment"))

         self.editAction = createAction(self, "EditAction",
                                       self.testslot,
                                       Qt.Key_E,
                                       "pencil.ico",
                                       self.tr(" my EditAction comment"))

         self.editAction.setEnabled(False)

         self.testToolBar = self.addToolBar("testToolBar")
         self.testToolBar.setObjectName("testToolBar")

         self.myMenu = self.menuBar().addMenu("&TestMenu")

         addActions(self, self.myMenu, (
                 self.editAction,
             ))

         addActions(self, self.testToolBar, (
                 self.myAction,
                 self.editAction,
             ))

         # connect scene to view
         self.view.setScene(self.scene)

         # create layout
         layout = QVBoxLayout()

         # add view to layout
         layout.addWidget(self.view)

         # set the margin of the object in the layout
         layout.setContentsMargins(0, 0, 0, 0)

         # create the central widget
         self.widget = QWidget()

         # lay it out
         self.widget.setLayout(layout)

         # set it to central
         self.setCentralWidget(self.widget)

         # setup connections
         self.scene.changed.connect(self.checkSelected)

     def checkSelected(self):
         if self.scene.selectedItems():
             self.editAction.setEnabled(True)
         else:
             self.editAction.setEnabled(False)

     def testslot(self):
         self._iconState =  not self._iconState
         if self._iconState:
             self.myAction.setIcon(QIcon("icons/help.ico"))
         else:
             self.myAction.setIcon(QIcon("icons/info.ico"))

def createAction(self, text, slot=None, shortcut=None, icon=None,
                  tip=None, checkable=False, signal="triggered()"):

     action = QAction(text, self)

     if icon is not None:
         action.setIcon(QIcon(("icons/{}").format(icon)))
     if shortcut is not None:
         action.setShortcut(shortcut)
     if tip is not None:
         action.setToolTip(tip)
         action.setStatusTip(tip)
     if slot is not None:
         self.connect(action, SIGNAL(signal), slot)
     if checkable:
         action.setCheckable(True)
     return action

def addActions(self, target, actions):
     for action in actions:
         if action is None:
             target.addSeparator()
         else:
             target.addAction(action)

if __name__ == "__main__":

     import sys

     # setup application object
     app = QApplication(sys.argv)

     # create (parent) main window
     mainWindow = MainWindow()
     mainWindow.setWindowTitle("gridScene")
     mainWindow.show()

     # run application object
     sys.exit(app.exec_())
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.riverbankcomputing.com/pipermail/pyqt/attachments/20100708/74eb761b/attachment-0001.html>


More information about the PyQt mailing list