I am trying to resend this since sending source code as an attachment did not seem to work properly when sending to this list.<br><br>I have been struggling for a while with strange and/or inconsistent
mouse event and drag/drop behaviour in QGraphicsItem where Windows
differ from Linux and OSX. I hope someone who have understood the mouse
event system could enlighten me?
<br>
<br>The attached test-case shows a simple QGraphicsView with a QGraphicsScene.
<br>
<br>When running it and pressing the left mouse button over one of the green
circles I get the following output in Windows 7 (PyQt 4.6):
<br>1 Scene: mousePressEvent
<br>2 Item: mousePressEvent
<br>when releasing the left mouse button I get the following output:
<br>3 View: mouseReleaseEvent
<br>4 Scene: mouseReleaseEvent
<br>5 Item: mouseReleaseEvent
<br>
<br>The output is the same in Ubuntu 9.10 beta. (PyQt 4.6-1).
<br>
<br>Now, if the method mousePressEvent in the Item class is changed by
uncommenting the "super" call (row 89) the output is changed:
<br>1 Scene: mousePressEvent
<br>2 Item: mousePressEvent
<br>3 View: mouseReleaseEvent
<br>4 Scene: mouseReleaseEvent
<br>
<br>I get the same output in both Windows 7 and Ubuntu 9.10.
<br>Question 1: Why is not the mouseReleaseEvent reaching the Item in this case?
<br>
<br>Next case:
<br>Also uncomment rows 91-97 in mousePressEvent of the Item class.
<br>When clicking left mouse button in the same way as previously and
holding it down I get the following output in Windows 7:
<br>1 Scene: mousePressEvent
<br>2 Item: mousePressEvent
<br>and when releasing the mouse button no additional output is received.
<br>
<br>In Ubuntu 9.10, however, I get the following output:
<br>1 Scene: mousePressEvent
<br>2 Item: mousePressEvent
<br>3 Item: dragEnterEvent
<br>4 Item: dragMoveEvent
<br>and when releasing the mouse button:
<br>5 Item: dropEvent
<br>QGraphicsItem::ungrabMouse: not a mouse grabber
<br>
<br>Windows does not get the drag events until the mouse is actually moved.
<br>Question 2: How should the inconsistency in drag events be handled?
<br>
<br>In the Qt-documentation about QGraphicsItem is saying that:
<br>" The mouse press event decides which item should become the mouse
grabber (see QGraphicsScene::<div id=":p2" class="ii gt">mouseGrabberItem
<qgraphicsscene.html#mouseGrabberItem>()). If you do not reimplement
this function, the press event will propagate to any topmost item
beneath this item, and no other mouse events will be delivered to this
item."
<br>
<br>I am not entirely sure how I should relate to this in this case... Any
best practices?
<br>
<br>Thanks,
<br><font color="#888888">Stefan Larsson<br><br>Source:<br><br><span style="font-family: courier new,monospace;">import sys</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">import time</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">from PyQt4.QtCore import *</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">from PyQt4.QtGui import *</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">count = 0</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">def status(message):</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> global count</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> count += 1</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> print count, message</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">class View(QGraphicsView):</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> def __init__(self):</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> super(View, self).__init__()</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> self.setAcceptDrops(True)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> self.setRenderHints(QPainter.Antialiasing)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> self.setBackgroundBrush(Qt.darkGreen)</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> scene = Scene(self)</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> self.setScene(scene)</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> item1 = Item()</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> item2 = Item()</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> item1.setPos(100,200)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> item2.setPos(300,200)</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> scene.addItem(item1)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> scene.addItem(item2)</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> def mouseReleaseEvent(self, event):</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> status("View: mouseReleaseEvent")</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> super(View, self).mouseReleaseEvent(event)</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">class Scene(QGraphicsScene):</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> def __init__(self, parent):</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> super(Scene, self).__init__(parent)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> self.setSceneRect(0, 0, 400, 400)</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> def mousePressEvent(self, event):</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> status("Scene: mousePressEvent")</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> super(Scene, self).mousePressEvent(event)</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> def mouseReleaseEvent(self, event):</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> status("Scene: mouseReleaseEvent")</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> super(Scene, self).mouseReleaseEvent(event)</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">class Item(QGraphicsItem):</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> def __init__(self):</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> super(Item, self).__init__()</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> #self.setAcceptHoverEvents(True)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> self.setAcceptDrops(True)</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> self.hovering = False</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> def boundingRect(self):</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> return QRectF(-42.0, -42.0, 84.0, 84.0)</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> def paint(self, painter, option, widget):</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> if self.hovering:</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> color = Qt.yellow</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> else:</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> color = Qt.green</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> r = QRectF(-40.0, -40.0, 80.0, 80.0)</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> path = QPainterPath()</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> path.addEllipse(r)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> painter.fillPath(path, QBrush(color))</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> painter.setPen(QPen(QBrush(Qt.black), 2.0))</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> painter.drawEllipse(r)</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> def hoverEnterEvent(self, event):</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> status("Item: hoverEnterEvent")</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> self.hovering = True</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> super(Item, self).hoverEnterEvent(event)</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> def hoverLeaveEvent(self, event):</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> status("Item: hoverLeaveEvent")</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> self.hovering = False</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> super(Item, self).hoverLeaveEvent(event)</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> def mousePressEvent(self, event):</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> status("Item: mousePressEvent")</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> event.accept()</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> super(Item, self).mousePressEvent(event)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> </span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> drag = QDrag(event.widget())</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> mime_data = QMimeData()</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> encoded_data = QByteArray()</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> encoded_data.append('test')</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> mime_data.setData('text/plain', encoded_data)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> drag.setMimeData(mime_data)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> drag.exec_(Qt.CopyAction)</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> def mouseReleaseEvent(self, event):</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> status("Item: mouseReleaseEvent")</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> super(Item, self).mouseReleaseEvent(event)</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> def dropEvent(self, event):</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> status("Item: dropEvent")</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> super(Item, self).dropEvent(event)</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> def dragEnterEvent(self, event):</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> status("Item: dragEnterEvent")</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> super(Item, self).dragEnterEvent(event)</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> def dragLeaveEvent(self, event):</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> status("Item: dragLeaveEvent")</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> super(Item, self).dragLeaveEvent(event)</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> def dragMoveEvent(self, event):</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> status("Item: dragMoveEvent")</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> super(Item, self).dragMoveEvent(event)</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> def mouseMoveEvent(self, event):</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> status("Item: mouseMoveEvent")</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> super(Item, self).mouseMoveEvent(event)</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">if __name__ == '__main__':</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> app = QApplication(sys.argv)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> view = View()</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> view.show()</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> sys.exit(app.exec_())</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"></font></div><br>