Question

I'm trying to write a program that will interact with QGraphicsView. I want to gather mouse and keyboard events when the happen in the QGraphicsView. For example, if the user clicks on the QGraphicsView widget I will get the mouse position, something like that. I can hard code it rather easily, but I want to use QtDesigner because the UI will be changing frequently.

This is the code that I have for the gui.py. A simple widget with a QGraphicsView in it.

from PyQt4 import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    _fromUtf8 = lambda s: s

class Ui_graphicsViewWidget(object):
    def setupUi(self, graphicsViewWidget):
        graphicsViewWidget.setObjectName(_fromUtf8("graphicsViewWidget"))
        graphicsViewWidget.resize(400, 300)
        graphicsViewWidget.setMouseTracking(True)
        self.graphicsView = QtGui.QGraphicsView(graphicsViewWidget)
        self.graphicsView.setGeometry(QtCore.QRect(70, 40, 256, 192))
        self.graphicsView.setObjectName(_fromUtf8("graphicsView"))

        self.retranslateUi(graphicsViewWidget)
        QtCore.QMetaObject.connectSlotsByName(graphicsViewWidget)

    def retranslateUi(self, graphicsViewWidget):
        graphicsViewWidget.setWindowTitle(QtGui.QApplication.translate("graphicsViewWidget", "Form", None, QtGui.QApplication.UnicodeUTF8))

The code for the program:

#!/usr/bin/python -d

import sys
from PyQt4 import QtCore, QtGui
from gui import Ui_graphicsViewWidget

class MyForm(QtGui.QMainWindow):

    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.ui = Ui_graphicsViewWidget()
        self.ui.setupUi(self)
        QtCore.QObject.connect(self.ui.graphicsView, QtCore.SIGNAL("moved"), self.test)

    def mouseMoveEvent(self, event):
        print "Mouse Pointer is currently hovering at: ", event.pos()
        self.emit(QtCore.SIGNAL("moved"), event)

    def test(self, event):
        print('in test')

if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    myapp = MyForm()
    myapp.show()
    sys.exit(app.exec_())

When I run this code, it gives me the opposite of what I want. I get the mouse position everywhere except for inside the QGraphicsView.

I'm sure it's a problem with my QObject.connect. But every time I go back and read about signals and slots it makes sense but I can't get it.

Please help, I've been banging my head for the past few days now. I'm sorry if this as been asked before but I've been through all the threads on this topic and I can't get anywhere.

Thanks

Was it helpful?

Solution

The signal must come from the QGraphicsView object that was defined in the ui.

You can create a class derived from QGraphicsView like this

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

class MyView(QGraphicsView):
    moved = pyqtSignal(QMouseEvent)

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

    def mouseMoveEvent(self, event):
        # call the base method to be sure the events are forwarded to the scene
        super(MyView, self).mouseMoveEvent(event)

        print "Mouse Pointer is currently hovering at: ", event.pos()
        self.moved.emit(event)

Then, in the designer:

  • right-click on the QGraphicsView then Promote to
  • write the class name in the Promoted Class Name field (e.g. "MyView"),
  • write the file name where that class is in the Header file field but without the .py extension,
  • click on the Add button and then on the Promote button.

And you can regenerate your file gui.py with pyuic4.

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