Der neue Drag-and-Drop-Mechanismus funktioniert nicht wie erwartet in Qt-Quick (Qt 5.3)

8

Ich habe versucht, Drag & Drop in Qt 5.3 mit den neuen QML-Typen Drag , DragEvent und DropArea zu implementieren. Dies ist das Originalbeispiel aus der Dokumentation des QML Drag type mit einigen kleinen Änderungen:

%Vor%

Erwartetes Verhalten : Das kleine blaue Rechteck (Ziehziel) kann mit der Maus gezogen werden. Wenn Sie über das größere grüne Rechteck in der Mitte des Fensters gezogen werden, wird dieses Rechteck beim Verlassen rot und wieder grün. Außerdem sind die Signale dragStarted , eingegeben , beendet , gelöscht und dragFinished sind in der Zeit emittiert und die entsprechenden Signalhandler ihre Nachrichten ausdrucken.

Erfahrenes Verhalten :

Hängt von Drag.dragType ab (siehe oben die kommentierte Zeile):

  1. Drag.dragType ist NICHT gesetzt (Standard ist Drag.Internal ):

    Drag and Drop funktioniert wie beschrieben, aber nur die Signale eingegeben und exited werden ausgegeben. Die anderen Signale ( dragStarted , dragFinished und drop ) werden unterdrückt. Es gibt also keine Möglichkeit, auf den Abfall von DropArea zu reagieren.

  2. Drag.dragType wird auf Drag.Automatic :

    gesetzt

    Alle Signale werden jetzt ausgegeben, aber das blaue Rechteck (Ziehziel) bewegt sich nicht mit der Maus. Stattdessen ändert der Mauszeiger seine Form, um mögliche Drop-Ziele zu visualisieren. Nachdem die Maus losgelassen wurde, springt das blaue Rechteck zur letzten Mausposition.

Keine dieser beiden Varianten ist erfreulich. Wie kann ich alle Signale erhalten und immer noch in der Lage sein, das Ziehziel zu ziehen? Leider ist die Dokumentation alles andere als klar über Drag-and-Drop in QML, insbesondere über die ominöse Drag.dragType .

    
isnot2bad 02.07.2014, 13:23
quelle

2 Antworten

16

Wenn Sie offene das QQuickDrag Quellcode und Blick auf den Unterschieden zwischen start() , das durch Drag.Internal verwendet wird, und startDrag() , die durch Drag.Automatic verwendet wird, der Unterschied ist ziemlich offensichtlich. start() setzt ein Ereignis ändern Hörer auf , die dann verwendet es, um aktualisieren des angefügten Objekts. startDrag() dieses nicht tun .

Warum funktioniert das so? Ich habe keine Ahnung! Die QtQuick 2-Drag & Drop-Dokumentation kann hier sicherlich verbessert werden.

Es gibt eine ziemlich einfache Problemumgehung: nimm das Beste aus beiden Welten. Verwenden Sie Drag.Automatic , aber setzen Sie Drag.active und start() nicht manuell, sondern setzen Sie drop() . Es wird nicht berufen Drag.onDragStarted() und Drag.onDragFinished() , aber Sie im Wesentlichen diejenigen kostenlos ohnehin durch das Hören für eine Änderung in dem MouseArea 's drag.active erhalten.

Hier ist das Konzept in Aktion:

%Vor%

Mir ist klar, dass es keine vollständig zufriedenstellende Lösung ist, aber es entspricht Ihrem erwarteten Verhalten.

Diese Lösung bietet:

  • Benachrichtigungen für alle gewünschten Ereignisse: Ziehen gestartet, Ziehen beendet, Drag-Bereich betreten, Drag-Bereich verlassen und im Drag-Bereich abgelegt.
  • Die Drag-Animation wird automatisch von QtQuick gehandhabt. Das Quadrat friert nicht ein wie beim Ausführen des Beispielcodes mit Drag.Automatic .

Was es nicht bietet:

  • Eine Erklärung, warum QtQuicks Drag-and-Drop-Funktionalität so funktioniert oder ob es sogar das beabsichtigte Verhalten der Entwickler ist. Die aktuelle Dokumentation scheint mehrdeutig.
MrEricSir 14.07.2014, 05:06
quelle
3

Ich bin gerade selbst dazu gekommen (mit Qt 5.2, aber dort existiert das gleiche Problem). Ich habe ein "Slider-Feld" auf der X-Achse und wollte nur wissen, wann das Ziehen beendet war ... anstatt auf jede Positionsänderung auf dem Weg zu reagieren. Mein Workaround beinhaltete das Hacken der Zustände / Übergänge mit einem ScriptAction , um die Logik bereitzustellen. Dies ist die vereinfachte Version zum Nachahmen einer Antwort auf das Signal "onDragFinished". Obwohl es nicht alle Ihre Drag / Drop-Signale abdeckt, kann es Sie in die richtige Richtung weisen.

%Vor%

ps - Ich weiß, dass ein solcher "Workaround" nicht für die Bountyparameter geeignet ist, aber ich war ziemlich enttäuscht, nur Ihre Frage (keine Lösungen) zu finden, als ich nach Hilfe zu diesem Problem suchte. Hoffentlich wird jeder andere, der diesen Weg stolpert, das nützlich finden. Leider habe ich keine Ahnung, was mit QML Drag.dragType entweder geht.

    
Derek 08.07.2014 06:06
quelle

Tags und Links