Testing Drag & Drop
-
I'm looking for a way to test the D&D behavior of one of my custom widgets. Some functionality could be tested by posting
QDragEnterEvent
+QDropEvent
to the target widget, when thesource()
of the event is not used.One of the custom widgets now uses the
source()
of the event and at this point I'm a bit lost.Looking into the implementation of
QDropEvent::source()
, I see, that it is not "set" but the source is taken from the package-private typeQDragManager
, which I cannot access. So posting the event directly is just not possible as it was for the other use-cases.So I tried to post
QMouseEvent
withQt::MouseButtonPress
, severalQt::MouseMove
andQt::MouseButtonRelease
event types. TheQt::MouseButtonPress
event actually triggersQDrag::exec()
(from within the custom widget), but the other events don't cause the drag to finish with a drop event - even if posted from a different thread.Oh, do I have to mention, that at this point I may not change the original code of the custom widgets, only the tests...
I would love to see useful suggestions.
Environment: Win10, Qt-5.15.2
-
@kehr_I said in Testing Drag & Drop:
So I tried to post QMouseEvent with Qt::MouseButtonPress, several Qt::MouseMove and Qt::MouseButtonRelease event types. The Qt::MouseButtonPress event actually triggers QDrag::exec() (from within the custom widget), but the other events don't cause the drag to finish with a drop event - even if posted from a different thread.
Does it create a
QDrag
object? Does yourcustomWidget
have the accept-drag/drop-events-flag set? -
Yes, it creates a
QDrag
object. Actually, when I use the custom widgets in the final application, they are working fine. Whenever there is a user controlling the mouse, all works as expected.My question relates to automated (unit-) testing, where I do not have user interaction, but can only simulate it.
As mentioned before, I tried to simulate user interaction with several strategies already. But for the case, where the target widget relies on
QDragEvent::source()
, well, this doesn't work. -
You might want to explore the test library, especially QTest::mousePress(), QTest::mouseMove(), QTest::mouseRelease() for simulating drag and drop in unit tests. It has been designed to do exactly what you are looking for.
-
Excellent suggestion to use QTest.
If I hadn't tried that already...
Sorry, I didn't want to sound sarcastic.
I tried QTest initially and found out, that there are many use-cases, where it just didn't work, in particular when using multiple threads.
QTest works fine if you "only" want to simulate mouse-clicks and key-clicks from the single one thread. But it is pretty useless when it comes to context menus or - which is the topic here - Drag&Drop.
Looking at the QTest implementation, we can see, that it posts events to the specified widget usingQApplication::notify(QWidget*, QEvent*)
. As mentioned already, this is working fine in the limited application of clicking a button or selecting an item in aQListView
. But it won't work for context menus (there you have to post theQContextMenuEvent
manually - and most probably operate the context menu from a different thread, sinceQMenu::exec()
is blocking in the test-thread). But - hey, no problem, that's working.For D&D on the other hand, it looks as if it is going much deeper than the Qt framework (at least on the platform which is required here). I could not make the drag stop other than with manual mouse interactions.
QTest::mouseRelease
did not work nor did posting aQMouseEvent
(withQt::MouseButtonReleased
).Any other suggestions?
-
I didn't intend this question to be a joke or blaming session. I invested quite some time already in trying to make testing Drag&Drop work.
Does anyone have an idea how to (automatically; also in CI) post the necessary events to make the drag-engine recognize them? Nothing I tried inside the Qt-framework worked so far, because the drag-engine circumvents the Qt-framework completely. At least on Windows; could be different on Unixoid systems, but I don't have the liberty to use that system.
Just a thought: is there a platform-plugin available for testing on Windows? Currently the default one is loaded.