[PyQt] Various problems with QGraphicsView

Matt Newell 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.setTransformationAnchor(QtGui.QGraphicsView.NoAnchor)
>         self.setSceneRect(QtCore.QRectF(-1e100, -1e100, 1e100, 1e100))
>      - Instead of using self.translate(x, y), I use:
>          m = self.matrix()
>          m.translate(x, y)
>          self.setMatrix(m)
>  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
> task.
>
>  - 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:
>    self.resetMatrix()
>    center = self.mapToScene(self.width()/2., self.height()/2.)
>    m = QtGui.QMatrix()
>    m.translate(center.x(), center.y())
>    self.setMatrix(m)
>  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 :)
> Thanks!
> Luke

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 
bug.  

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 
reported?

Matt




More information about the PyQt mailing list