Qt QGraphicsView unit testing - how to keep the mouse in a "pressed" state?
Asked Answered
B

1

6

I have a fairly complex QGraphicsView/Scene setup where by I have items with complex interactions.

As such I want to unit test this to avoid creating bugs in already existing functionality. For one test I wish to:

  1. Press the mouse down on an item in the scene
  2. Move the mouse to the right
  3. Release the mouse

This will allow me to check that the item was selected, was moved by the correct amount, and was deselected.

However I find that after sending mouseMove events the mouse state becomes "released", here is my code:

QTest.mousePress(gv.viewport(), Qt.LeftButton, Qt.NoModifier, QPoint(80,80), 100)
QTest.mouseMove(gv.viewport(), QPoint(80,80), 200)
QTest.mouseMove(gv.viewport(), QPoint(90,80), 300)
QTest.mouseMove(gv.viewport(), QPoint(100,80), 400)
QTest.mouseRelease(gv.viewport(), Qt.LeftButton, Qt.NoModifier, QPoint(80,80), 900)

Where gv is a QGraphicsView.

The problem seems to be that the mouseMove events are seen as hoverMoveEvents by the QGraphicsItem - it should be seen as a mouseMoveEvent!

According to the docs:

http://qt-project.org/doc/qt-4.8/qgraphicsitem.html#setAcceptHoverEvents

So it would seem that these simulated events do not set the "mouse grabber item"?

Related:

How to unit test qt graphics view widgets/items

Edit:

TLDR; Why are my fake mouse events not setting the current mouse grabber item? This causes QGraphicsItems to get mouseHover events instead of mouseMove events.

Baggywrinkle answered 30/4, 2013 at 12:20 Comment(1)
qt.gitorious.org/qt/qt/blobs/… might yeild my answer.. further investigation requiredBaggywrinkle
B
6

Finally managed to get something that actually works:

w = gv.viewport()

# this actually gets the click to the view
#QTest.mouseMove(w, QPoint(80,80))
event = QMouseEvent(QEvent.MouseMove, QPoint(80,80), w.mapToGlobal(QPoint(80,80)), Qt.LeftButton, Qt.LeftButton, Qt.NoModifier);
#event.setSpontaneous(True)
QApplication.postEvent(w, event);
QTest.qWait(250)

#QTest.mouseMove(w, QPoint(80,80))
event = QMouseEvent(QEvent.MouseButtonPress, QPoint(80,80), w.mapToGlobal(QPoint(80,80)), Qt.LeftButton, Qt.LeftButton, Qt.NoModifier);
QApplication.postEvent(w, event);
QTest.qWait(250)

count = 0
while count < 20:

    #QTest.mouseMove(w, QPoint(80+count,80+count))
    event = QMouseEvent(QEvent.MouseMove, QPoint(80+count,80+count), w.mapToGlobal(QPoint(80+count,80+count)), Qt.LeftButton, Qt.LeftButton, Qt.NoModifier);
    QApplication.postEvent(w, event);
    t = w.mapToGlobal(QPoint(80+count,80+count))
    #QCursor.setPos(t)
    QTest.qWait(20)
    count = count + 1

event = QMouseEvent(QEvent.MouseButtonRelease, QPoint(100,100), w.mapToGlobal(QPoint(100,100)), Qt.LeftButton, Qt.LeftButton, Qt.NoModifier);
QApplication.postEvent(w, event);

Why these fabricated events work and the QTest ones don't I have no idea..

It appears that QTest will physically move the mouse, where as this code acts as if the mouse had moved but hasn't. Confusing I know!

Baggywrinkle answered 6/5, 2013 at 18:1 Comment(1)
I am glad I came across this. I was beating my head for days now... The key is the widget = QtGui.QGraphicsView.viewport() and then passing the widget to the QTest.mouseClick(widget). I haven't tried the mouseMove.Sutlej

© 2022 - 2024 — McMap. All rights reserved.