[PyQt] Various problems with QGraphicsView
newellm at blur.com
Tue Jun 3 18:05:10 BST 2008
On Tuesday 03 June 2008 09:50:50 Luke Campagnola wrote:
> Hello again,
> I am trying to implement a subclass of QGraphicsView that allows the
> user to pan its contents by dragging with the middle mouse button and
> scale by dragging with the right button. for various reasons, I do not
> wish to use the built-in pan and zoom features in QGraphicsView. I
> have read several posts online from people trying to accomplish
> similar tasks but haven't really seen any satisfactory answers, and
> I've been banging my head against this problem for a long while now.
> Here is my basic approach: subclass QGraphicsView, reimplement all
> mouse event functions so that I can catch the ones I recognize,
> translate/scale the graphicsview, and pass on the remaining events.
> Here are the problems I have run into:
> - If I catch ALL mouse events and never pass any on to the
> QGraphicsView handlers, everything works fine. If, however, I do pass
> some (but not all) events to the superclass, then I start to get some
> very erratic behavior--maybe 1 out of every 100 mouse events has the
> incorrect position, sometimes more. I've attached a program that
> demonstrates this--you can drag with the right mouse button with no
> trouble until the left mouse button (which is passed on to the
> superclass) is clicked. After clicking the left mouse button, dragging
> with the right mouse button should work most of the time but
> occasionally the scene will jump erratically.
> - If, on the other hand, I pass ALL events to the superclass, then
> every once in a while the mouseMoveEvent will start getting called
> repeatedly in the absence of any events, usually tying up the CPU in
> the process.
> - self.translate() does not work (seemingly under any
> circumstances?). This has been discussed a few times before, and seems
> to be caused by the graphicsView wanting to automatically center the
> scene contents after translating them. My workaround looks like this
> (working example attached):
> - in GraphicsView.__init__(), I have:
> self.setSceneRect(QtCore.QRectF(-1e100, -1e100, 1e100, 1e100))
> - Instead of using self.translate(x, y), I use:
> m = self.matrix()
> m.translate(x, y)
> I don't know exactly all of these together produce a workable
> solution, but it seems like a lot of work to accomplish such a simple
> - It is difficult to get full control of the viewport, presumably
> because QAbstractScrollArea (or possibly QGraphicsView?) likes to move
> the scene around without telling me (particularly when resizing the
> window). My workaround to this has been to reset any unexpected
> transformations like this:
> center = self.mapToScene(self.width()/2., self.height()/2.)
> m = QtGui.QMatrix()
> m.translate(center.x(), center.y())
> I have left this out of the attached example, and as a result I know
> no reliable way of knowing where exactly my graphics are drawn within
> the widget.
> - It appears that the event object that gets passed to the
> mouseEvent functions is being reused. This caused an unexpected (but
> easily fixed) problem for me: In order to allow scene panning/scaling,
> I need to record the event.pos() for every mouse event so that I can
> compare the previous event position to the current event position.
> Since the event object is reused, however, I find that the position I
> stored as the "previous position" has already been updated to the
> current position. For example:
> ## Does not work
> self.lastMousePosition = event.pos()
> ## Workaround
> self.lastMousePosition = QPoint(event.pos().x(), event.pos().y())
> In summary, my questions:
> 0. Why might I be having so much difficulty handling mouse events?
> 1. Is there a better / recommended way to accomplish the type of user
> interaction I'm after?
> 2. Is there some unambiguous way to set the transformation matrix used
> by QGraphicsView that will not be interfered with?
> 3. Is there a simple way to make translate() work?
> I'd love to hear any workable solutions other people have found.. I've
> been tempted to just go back to using QPainter, but the features in
> QGraphicsView are just too good to pass up :)
I was investigating the bug wrt mouse events, specifically that buttons()
returns incorrect values after the first click-release sequence. I haven't
pinpointed the problem yet, but I think this may be a Qt bug and not a PyQt
The QMouseEvent object is not actually reused, but is created on the stack at
such a low level in the call stack that it occupies the same address.
When I get a chance I will look into this further.
BTW, have you checked the trolltech bug tracker to see if this issue has been
More information about the PyQt