In the code sample below I have found a problem with changing cursors.

Basically I have a MyScene with two MyRect items shown with a MyView.

In the view I change "modes" by pressing F1 - F3. To visually represent the modes I want to change the cursor of the view (background) and the items.

If I do not move the mouse cursor over items the cursor of the view changes fine. As soon as I move the cursors over the items, the item cursors change ok but the view cursor does not change or changes wrong.

Is this a bug or am I doing something wrong here?

Qt Code:
  1. from PyQt4.QtCore import *
  2. from PyQt4.QtGui import *
  3.  
  4. class MyRect(QGraphicsRectItem):
  5.  
  6. def __init__(self, parent=None, scene=None):
  7. # init parent
  8. super().__init__(parent, scene)
  9.  
  10. # set flags
  11. self.setFlag(QGraphicsItem.ItemIsSelectable, True)
  12. self.setFlag(QGraphicsItem.ItemIsMovable, True)
  13. self.setFlag(self.ItemSendsGeometryChanges, True)
  14. self.setAcceptHoverEvents(True)
  15.  
  16. def paint(self, painter, option, widget):
  17. if self.isSelected():
  18. painter.setPen(QPen(Qt.black, 1, Qt.DotLine))
  19. else:
  20. painter.setPen(QPen(Qt.black, 1, Qt.SolidLine))
  21.  
  22. painter.setBrush(QBrush(Qt.white, Qt.SolidPattern))
  23. painter.drawRect(self.rect())
  24.  
  25. class MyView(QGraphicsView):
  26.  
  27. def __init__(self, parent=None):
  28. super().__init__(parent)
  29. self.setMouseTracking(True)
  30. self.scale(1,1)
  31. self.startPos = None
  32.  
  33. def setSelectMode(self):
  34. print("view setting select mode")
  35. self.scene().setViewMode(MyScene.SELECTMODE)
  36.  
  37. def setEditMode(self):
  38. print("view setting edit mode")
  39. self.scene().setViewMode(MyScene.EDITMODE)
  40. if len(self.scene().selectedItems()) > 1:
  41. self.scene().clearSelection()
  42.  
  43. def setDrawMode(self):
  44. print("view setting draw mode")
  45. self.scene().setViewMode(MyScene.DRAWMODE)
  46. self.scene().clearSelection()
  47.  
  48. def updateItems(self):
  49. print("view updateItems")
  50. m = self.scene().viewMode()
  51.  
  52. if m == MyScene.SELECTMODE:
  53. print("is select mode")
  54. self.setCursor(Qt.ArrowCursor)
  55. print(self.cursor().shape())
  56. #self.update()
  57. itemCursor = Qt.OpenHandCursor
  58.  
  59. elif m == MyScene.EDITMODE:
  60. print("is edit mode")
  61. self.setCursor(Qt.ForbiddenCursor)
  62. print(self.cursor().shape())
  63. #self.update()
  64. itemCursor = Qt.PointingHandCursor
  65.  
  66. elif m == MyScene.DRAWMODE:
  67. print("is draw mode")
  68. self.setCursor(Qt.CrossCursor)
  69. print(self.cursor().shape())
  70. #self.update()
  71. itemCursor = Qt.WaitCursor
  72.  
  73. items = self.scene().items()
  74.  
  75. for item in items:
  76. item.setCursor(itemCursor)
  77. #item.update()
  78.  
  79. def drawBackground(self, painter, rect):
  80. # draw a rect in size of sceneRect
  81.  
  82. painter.setPen(QPen(Qt.red, 0, Qt.NoPen))
  83. painter.setBrush(QBrush(Qt.lightGray, Qt.SolidPattern))
  84. painter.drawRect(self.scene().sceneRect())
  85.  
  86. def mousePressEvent(self, mouseEvent):
  87. print("view mousePress")
  88. curPos = mouseEvent.pos()
  89. self.startPos = self.mapToScene(curPos)
  90.  
  91. if self.scene().viewMode() == MyScene.DRAWMODE:
  92. self.scene().newItem = MyRect(scene=self.scene())
  93. self.scene().newItem.setRect(QRectF(self.startPos, QSizeF(0, 0)))
  94. self.scene().newItem.setSelected(True)
  95.  
  96. else:
  97. super().mousePressEvent(mouseEvent)
  98.  
  99. def mouseMoveEvent(self, mouseEvent):
  100. #print("view mouseMove")
  101. curPos = self.mapToScene(mouseEvent.pos())
  102.  
  103. if self.scene().viewMode() == MyScene.DRAWMODE:
  104. if self.scene().newItem:
  105. newRectF = QRectF(self.startPos, curPos)
  106. if newRectF != self.scene().newItem.rect():
  107. self.scene().newItem.setRect(newRectF.normalized())
  108.  
  109. else:
  110. super().mouseMoveEvent(mouseEvent)
  111.  
  112. def mouseReleaseEvent(self, mouseEvent):
  113. print("view mouseRelease")
  114.  
  115. if self.scene().newItem:
  116. # delete item if zero height or width
  117. if (self.scene().newItem.rect().width() == 0
  118. or self.scene().newItem.rect().height() == 0):
  119. self.scene().removeItem(self.scene().newItem)
  120. del self.scene().newItem
  121.  
  122. self.startPos = None
  123. self.scene().newItem = None
  124. super().mouseReleaseEvent(mouseEvent)
  125.  
  126. def keyPressEvent(self, keyEvent):
  127. if keyEvent.key() == Qt.Key_F1:
  128. self.setSelectMode()
  129. self.updateItems()
  130.  
  131. elif keyEvent.key() == Qt.Key_F2:
  132. self.setEditMode()
  133. self.updateItems()
  134.  
  135. elif keyEvent.key() == Qt.Key_F3:
  136. self.setDrawMode()
  137. self.updateItems()
  138.  
  139. elif keyEvent.key() == Qt.Key_Delete:
  140. if self.scene().viewMode() == MyScene.SELECTMODE:
  141. items = self.scene().selectedItems()
  142. if len(items):
  143. for item in items:
  144. self.scene().removeItem(item)
  145. del item
  146.  
  147. class MyScene(QGraphicsScene):
  148.  
  149. SELECTMODE, EDITMODE, DRAWMODE = (0, 1, 2)
  150. validViewModes = [SELECTMODE, EDITMODE, DRAWMODE]
  151.  
  152. def __init__(self, parent=None):
  153. super().__init__(parent)
  154.  
  155. self._viewMode = MyScene.SELECTMODE
  156. self.newItem = None
  157.  
  158. self.setSceneRect(-300, -200, 600, 400)
  159.  
  160. # add some item
  161. someRect = MyRect(scene=self)
  162. someRect.setRect(QRectF(0, 0, 160, 80))
  163.  
  164. # add another item
  165. anotherRect = MyRect(scene=self)
  166. anotherRect.setRect(QRectF(-80, -40, 80, 160))
  167.  
  168. # add own item
  169. #myItem = MyItem(scene=self)
  170.  
  171. def setViewMode(self, value):
  172. if value != self._viewMode:
  173. if value in MyScene.validViewModes:
  174. self._viewMode = value
  175. else:
  176. raise ValueError("invalid view mode")
  177.  
  178. def viewMode(self):
  179. return self._viewMode
  180.  
  181. class MainWindow(QMainWindow):
  182.  
  183. def __init__(self, parent=None):
  184. # call parent init
  185. super().__init__(parent)
  186.  
  187. # setup scene object
  188. self.scene = MyScene()
  189.  
  190. # setup view object
  191. self.view = MyView()
  192.  
  193. # connect scene to view
  194. self.view.setScene(self.scene)
  195.  
  196. # create layout
  197. layout = QVBoxLayout()
  198.  
  199. # add view to layout
  200. layout.addWidget(self.view)
  201.  
  202. # set the margin of the object in the layout
  203. layout.setContentsMargins(0, 0, 0, 0)
  204.  
  205. # create the central widget
  206. self.widget = QWidget()
  207.  
  208. # lay it out
  209. self.widget.setLayout(layout)
  210.  
  211. # set it to central
  212. self.setCentralWidget(self.widget)
  213.  
  214. if __name__ == "__main__":
  215.  
  216. import sys
  217.  
  218. # setup application object
  219. app = QApplication(sys.argv)
  220.  
  221. # create (parent) main window
  222. mainWindow = MainWindow()
  223. mainWindow.setWindowTitle("testScene")
  224. mainWindow.show()
  225.  
  226. # run application object
  227. sys.exit(app.exec_())
To copy to clipboard, switch view to plain text mode