Search code examples
pythonpython-2.7pyqtpyqt4qgraphicsview

AttributeError: 'NoneType' object has no attribute 'scenePos'


Here is my sample code,i want to print the my coordinates of x,y positions by using the mouse press event,i got this error can any one please help me and i want to display the my graphics view in middle of the scrollArea.

Given bellow is my code:

from pyface.qt import QtGui, QtCore
import sys

class MyView(QtGui.QGraphicsView):
    def __init__(self):
        QtGui.QGraphicsView.__init__(self)
        self.row = 2
        self.cols = 4
        self.scene = QtGui.QGraphicsScene(0,0,500,500)
        self.List = []

        for i in range(self.row):
            for j in range(self.cols):
                item = self.scene.addRect(QtCore.QRectF(0,0,30,30))
                item.setPos(30+j*30,500-i*30-60)
                print item.scenePos()
                self.List.append(item)
        self.setScene(self.scene)
    def mousePressEvent(self,event):
        super(MyView,self).mousePressEvent(event)
        p = QtCore.QPointF(event.pos())
        print "positonnnnnnnnnnnnnnnn", p
        item = self.scene.itemAt(p)
        print "@@@@@@@@@@@@@@@@@@@@@@@@@2"
        print item.scenePos()
class Settings(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(Settings, self).__init__(parent)
        spacer = QtGui.QWidget(self)
        spacer.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
        QtGui.QToolTip.setFont(QtGui.QFont('SansSerif', 10))
        self.vbox = QtGui.QVBoxLayout()
        self.save = QtGui.QPushButton("save")
        self.open= QtGui.QPushButton("open")
        self.folder= QtGui.QPushButton("Folder")
        self.folder.clicked.connect(self.showSettings)
        self.vbox.addWidget(self.save)
        self.vbox.addWidget(self.open)
        self.vbox.addWidget(self.folder)
        self.grid = QtGui.QGridLayout()
        self.grid.addLayout(self.vbox,0,0)
        self.scrollArea = QtGui.QScrollArea()
        self.scrollArea.setBackgroundRole(QtGui.QPalette.Light)
        self.scrollArea.setWidgetResizable(True)
        self.grid.addWidget(self.scrollArea,0,1)
        self.setCentralWidget(QtGui.QWidget(self))
        self.centralWidget().setLayout(self.grid)
        self.setGeometry(200,100,300,300)
        self.show()
    def showSettings(self):
        self.newwidget = QtGui.QWidget()
        self.glayout = QtGui.QGridLayout(self.newwidget)
        self.MyView =  MyView()
        self.glayout.addWidget(self.MyView,0,1)
        self.scrollArea.setWidget(self.newwidget)
def main():
    app = QtGui.QApplication(sys.argv)
    ex = Settings()
    sys.exit(app.exec_())
if __name__ == '__main__':
    main()

Solution

  • The coordinates of the items are different to the coordinates of the window, in the case of event.pos() returns the position of the mouse with respect to the viewport of the QGraphicsView so you will have to convert it to coordinates of the scene with mapToScene(), by other side when using itemAt() could return None since in certain areas of the scene there are no items so it is advisable to verify

    def mousePressEvent(self, event):
        super(MyView,self).mousePressEvent(event)
        p = self.mapToScene(event.pos())
        item = self.scene.itemAt(p)
        if item is not None:
            print(item.scenePos())
    

    To understand the different coordinate systems that handle the QGraphicsView, QGraphicsScene and the QGraphicsItems, I recommend reading Graphics View Framework.