[PyQt] setCursor does not seem to work as expected in graphicsScene/View

Christopher M. Nahler christopher.nahler at papermodels.at
Tue Aug 24 09:53:00 BST 2010


This is a reduced part of a project I am working on (Win7, Python 3.1, 
PyQt 4.7.3, Qt 4.6.2).

I can set different "modes" via keyPressEvent (F1, F2, F3) in the MyView 
class. There I set different cursors according to the mode in 
MyView.updateItems().

When I run the code and the mouse is outside of the test rectangles the 
switching of cursors works fine. As soon as I move the mouse over one of 
the rectangles, the cursors switching works fine in/over the rectangles 
but as soon as I move the mouse outside of the rectangles it does not 
switch anymore.

I expected the cursor switching to still work outside of the rectangles 
when the mouse is "over" the view are not covered by rectangles.

Is this expectation wrong? Did I do something wrong?

Thanks in advance
Chris


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

class MyRect(QGraphicsRectItem):

     def __init__(self, parent=None, scene=None):
         # init parent
         super().__init__(parent, scene)

         # set flags
         self.setFlag(QGraphicsItem.ItemIsSelectable, True)
         self.setFlag(QGraphicsItem.ItemIsMovable, True)
         self.setFlag(self.ItemSendsGeometryChanges, True)
         self.setAcceptHoverEvents(True)

     def paint(self, painter, option, widget):
         if self.isSelected():
             painter.setPen(QPen(Qt.black, 1, Qt.DotLine))
         else:
             painter.setPen(QPen(Qt.black, 1, Qt.SolidLine))

         painter.setBrush(QBrush(Qt.white, Qt.SolidPattern))
         painter.drawRect(self.rect())

class MyView(QGraphicsView):

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

     def setSelectMode(self):
         print("view setting select mode")
         self.scene().setViewMode(MyScene.SELECTMODE)

     def setEditMode(self):
         print("view setting edit mode")
         self.scene().setViewMode(MyScene.EDITMODE)
         if len(self.scene().selectedItems()) > 1:
             self.scene().clearSelection()

     def setDrawMode(self):
         print("view setting draw mode")
         self.scene().setViewMode(MyScene.DRAWMODE)
         self.scene().clearSelection()

     def updateItems(self):
         print("view updateItems")
         m = self.scene().viewMode()

         if m == MyScene.SELECTMODE:
             print("is select mode")
             self.setCursor(Qt.ArrowCursor)
             itemCursor = Qt.OpenHandCursor

         elif m == MyScene.EDITMODE:
             print("is edit mode")
             self.setCursor(Qt.ForbiddenCursor)
             itemCursor = Qt.ForbiddenCursor

         elif m == MyScene.DRAWMODE:
             print("is draw mode")
             self.setCursor(Qt.CrossCursor)
             itemCursor = Qt.CrossCursor

         items = self.scene().items()

         for item in items:
             item.setCursor(itemCursor)
             item.update()

     def drawBackground(self, painter, rect):
         # draw a rect in size of sceneRect

         painter.setPen(QPen(Qt.red, 0, Qt.NoPen))
         painter.setBrush(QBrush(Qt.lightGray, Qt.SolidPattern))
         painter.drawRect(self.scene().sceneRect())

     def mousePressEvent(self, mouseEvent):
         print("view mousePress")
         curPos = mouseEvent.pos()
         self.startPos = self.mapToScene(curPos)

         if self.scene().viewMode() == MyScene.DRAWMODE:
             self.scene().newItem = MyRect(scene=self.scene())
             self.scene().newItem.setRect(QRectF(self.startPos, 
QSizeF(0, 0)))
             self.scene().newItem.setSelected(True)

         else:
             super().mousePressEvent(mouseEvent)

     def mouseMoveEvent(self, mouseEvent):
         #print("view mouseMove")
         curPos = self.mapToScene(mouseEvent.pos())

         if self.scene().viewMode() == MyScene.DRAWMODE:
             if self.scene().newItem:
                 newRectF = QRectF(self.startPos, curPos)
                 if newRectF != self.scene().newItem.rect():
                     self.scene().newItem.setRect(newRectF.normalized())
         else:
             super().mouseMoveEvent(mouseEvent)

     def mouseReleaseEvent(self, mouseEvent):
         print("view mouseRelease")

         if self.scene().newItem:
             # delete item if zero height or width
             if (self.scene().newItem.rect().width() == 0
                 or self.scene().newItem.rect().height() == 0):
                 self.scene().removeItem(self.scene().newItem)
                 del self.scene().newItem

         self.startPos = None
         self.scene().newItem = None
         super().mouseReleaseEvent(mouseEvent)

     def keyPressEvent(self, keyEvent):
         if keyEvent.key() == Qt.Key_F1:
             self.setSelectMode()
             self.updateItems()

         elif keyEvent.key() == Qt.Key_F2:
             self.setEditMode()
             self.updateItems()

         elif keyEvent.key() == Qt.Key_F3:
             self.setDrawMode()
             self.updateItems()

         elif keyEvent.key() == Qt.Key_Delete:
             if self.scene().viewMode() == MyScene.SELECTMODE:
                 items = self.scene().selectedItems()
                 if len(items):
                     for item in items:
                         self.scene().removeItem(item)
                         del item

class MyScene(QGraphicsScene):

     SELECTMODE, EDITMODE, DRAWMODE = (0, 1, 2)
     validViewModes = [SELECTMODE, EDITMODE, DRAWMODE]

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

         self._viewMode = MyScene.SELECTMODE
         self.newItem = None

         self.setSceneRect(-300, -200, 600, 400)

         # add some item
         someRect = MyRect(scene=self)
         someRect.setRect(QRectF(0, 0, 160, 80))

         # add another item
         anotherRect = MyRect(scene=self)
         anotherRect.setRect(QRectF(-80, -40, 80, 160))

     def setViewMode(self, value):
         if value != self._viewMode:
             if value in MyScene.validViewModes:
                 self._viewMode = value
             else:
                 raise ValueError("invalid view mode")

     def viewMode(self):
         return self._viewMode

class MainWindow(QMainWindow):

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

         # setup scene object
         self.scene = MyScene()

         # setup view object
         self.view = MyView()

         # 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)

if __name__ == "__main__":

     import sys

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

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

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


More information about the PyQt mailing list