Modifying QDrag is no use. What about QMimeData, which is key to the Delayed Encoding hack? I set up the following modified MIME data class.
class MaimData(QMimeData): def __init__(self): super().__init__() def retrieveData(self,mt,ty): print('MT retrieveData') return super().retrieveData(mt,ty) def formats(self): print('MT formats') return super().formats()
The results were very interesting (on Mac OS X 10.9, this is).
starting drag with actions: Copy Move Link MT formats MT retrieveData MT retrieveData MT retrieveData MT retrieveData MT retrieveData drag enters at 0 20 kbd mods 0 buttons 1 offering actions: Copy Move Link MT formats target moved to <class '__main__.TargWidj'> drag moving at 1 20 drag moving at 3 19 drag moving at 4 19 drag moving at 5 19 dropping at 5 19 actions: Move -- setting copy action! MT formats MT retrieveData exec returns 1 default 2 target <class '__main__.TargWidj'> source <class '__main__.SorcWidj'>
There is an immediate call to formats() and then five (5!) successive calls to retrieveData(). These all take place the moment the drag begins, while the mouse has barely moved. This immediately shows why the Delayed Encoding hack fails on Mac OS: not only would the expensive data conversion not be delayed; it would be done multiple times!
The next call to formats happens when the dragEnterEvent() method of the target widget accesses event.mimeData().hasText(). Then both methods are called during drop event processing.
Well, this looks promising. What happens if the drag is dropped onto a different application?
starting drag with actions: Copy Move Link MT formats MT retrieveData MT retrieveData MT retrieveData MT retrieveData MT retrieveData exec returns 0 default 2 target <class 'NoneType'> source <class '__main__.SorcWidj'>
OK, what happens if it is dropped on the desktop?
starting drag with actions: Copy Move Link MT formats MT retrieveData MT retrieveData MT retrieveData MT retrieveData MT retrieveData exec returns 0 default 2 target <class 'NoneType'> source <class '__main__.SorcWidj'>
Oops. What about a drop that fails, releasing the mouse over an ineligible receiver?
starting drag with actions: Copy Move Link MT formats MT retrieveData MT retrieveData MT retrieveData MT retrieveData MT retrieveData exec returns 0 default 2 target <class 'NoneType'> source <class '__main__.SorcWidj'>
Depressing: the MIME data methods are just never called after the start of the drag, except when the drag enters a target in the same app.
It may be this behavior is peculiar to Mac OS and the code would behave differently on Windows or Linux. Doesn't matter; Mac OS is one of two main targets for my app, and anyway I want to keep it platform independent.
For the moment my desire to detect the drag of a tab off the edge of its parent window—and for that matter, the complementary desire to detect the drag of a QDialog onto a QTabBar—appears to be out of reach. But stay tuned, something may turn up.
No comments:
Post a Comment