Question

Hi I am trying to get contextmenu actions to work for a qgraphicsitem, in broad strokes I want to be able to right-click on any qgraphicsitem in my scene get presented with a context menu and get a run one of 3 functions depending on which item has been selected/clicked on. To get to this I have created a node class which sub-classes qgraphicsitem and my code is as follows

class Node(QtGui.QGraphicsItem):
Type = QtGui.QGraphicsItem.UserType + 1

def __init__(self, Parent=None):
    super(Node, self).__init__()

    self.newPos = QtCore.QPointF()

    self.setFlag(QtGui.QGraphicsItem.ItemIsMovable)
    self.setFlag(QtGui.QGraphicsItem.ItemIsSelectable)
    self.setFlag(QtGui.QGraphicsItem.ItemSendsGeometryChanges)
    self.setCacheMode(QtGui.QGraphicsItem.DeviceCoordinateCache)
    self.setZValue(1)


def notifyaction1(self):
    print "action1"

def contextMenuEvent(self, contextEvent):
    object_cntext_Menu = QtGui.QMenu()
    object_cntext_Menu.addAction("action1")
    object_cntext_Menu.addAction("action2", object_cntext_Menu, QtCore.SLOT(self.notifyaction1()))
    object_cntext_Menu.addAction("action3")
    position=QtGui.QCursor.pos() 
    object_cntext_Menu.exec_(position)

So far this code displays the context menu in the right place, but how can I tell which item was clicked, so i can run the appropriate action related function. Currently just right clicking triggers the notifyaction1 function with the error

Object::connect: Parentheses expected, slot QMenu::

I am using pyqt4/python on windows. Thank you

Was it helpful?

Solution

The argument to QtCore.SLOT should be a string matching the signature of the slot, whereas you are trying to pass in the return value of notifyaction1 (which is None). Also, since notifyaction1 isn't a Qt slot, you would need to decorate it accordingly so that it could be used as one:

    @QtCore.pyqtSlot()
    def notifyaction1(self):
        print "action1"
    ...

    object_cntext_Menu.addAction("action2", self, QtCore.SLOT("notifyaction1()"))

However, I wouldn't recommend this approach, as it is over-complicated. The signature of QMenu.addAction works differently in PyQt, in that it can accept any python callable:

    object_cntext_Menu.addAction("action2", self.notifyaction1)

And in fact, wherever you see Qt functions with argument pairs like this:

    const QObject * receiver, const char * member

you can generally use a single python callable argument instead.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top