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 _______________________________________________ PyQt mailing list [email protected] http://www.riverbankcomputing.com/mailman/listinfo/pyqt
