Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. When is the signal QDrag::targetChanged emitted?
Forum Updated to NodeBB v4.3 + New Features

When is the signal QDrag::targetChanged emitted?

Scheduled Pinned Locked Moved Solved General and Desktop
5 Posts 3 Posters 2.3k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    dcortesi
    wrote on last edited by A Former User
    #1

    I asked about when QDrag::targetChanged was emitted, and also I asked why, following a drop, the result of QDrag::exec() is 0 (Qt.IgnoreAction) and the target() method returned null (Python None).

    After simplifying my test case I found the following:

    QDrag::targetChanged is emitted, but only when the drag enters an accepting Qt Widget in the same Qt app, that is, a Widget which

    • has setAcceptDrops(True)
    • implements dragEnterEvent()
    • AND calls event->acceptProposedAction on the enter event to accept the drop

    Under these conditions the signal is emitted with a "target" argument of the accepting widget. Once the drag has entered the boundary of an accepting Widget, if you continue to drag out of that Widget, targetChanged is also emitted as the drag leaves, passing a "target" of a null QObject (Python None).

    To summarize, it appears that QDrag::targetChanged is emitted exactly and only when an accepting widget in the same app executes its dragEnterEvent() or its dragLeaveEvent(). Note if the accepting widget is in a different Qt app, it will execute its dragEnterEvent and dropEvent but targetChanged will not be issued.

    This means that you cannot use this signal to detect when a drag has crossed your window boundary over to the desktop or to a different application -- even if that application or desktop will accept the drop, even if it is a Qt app! For example I have tested a successful drop onto the Mac OS desktop (the dropped mime data appears as a Mac "clipping" file) or onto another app like an editor, the data is dropped correctly, but targetChanged is not issued -- presumably because these non-Qt targets do not execute dragEnterEvent?

    I have also found that if the dragEnterEvent() code does not accept the proposed action, neither the dragMoveEvent() nor the dragLeaveEvent() will ever be called! This means that you cannot use dragEnterEvent to change the appearance of a widget to indicate it refuses the drop, expecting to clear the visual indication on dragLeaveEvent. For example, you cannot make your widget turn red when an unwanted drop enters it, because if you do, it will remain red forever because your dragLeaveEvent will not be executed.

    If a drop is successful on a Qt Widget (that is, its dropEvent() method is executed) then the value of QDrag::target() will be that widget after QDrag::exec() completes. However, if the drop is rejected, or if the recipient is a different app, target() returns a null pointer or Python None. Thus you cannot use QDrag::target() to find out for certain whether a drop succeeded. It might have succeeded off-app, or it might not.

    In all cases of drops, successful and rejected, to Qt widgets or to foreign widgets, the returned value of QDrag::exec() has always been 0 (Qt.IgnoreAction) in my tests. So far I cannot find out when, if ever, QDrag::exec() returns some action value other than 0.

    1 Reply Last reply
    0
    • D Offline
      D Offline
      dcortesi
      wrote on last edited by
      #2

      Oh and in case anyone wants to try my test case, here it is: http://pastebin.com/LUMYyWCZ

      You can start two copies, e.g.

      @$ python draggin.py &
      $ python draggin.py &
      @

      and drag from one to the other.

      1 Reply Last reply
      0
      • D Offline
        D Offline
        dcortesi
        wrote on last edited by
        #3

        I have now put EVERYTHING that I have learned about drag and drop in a series of blog posts that can be read here: http://thispageintentionally.blogspot.com/2014/01/ts-drag-and-drop-architecture-for.html

        mrjjM 1 Reply Last reply
        1
        • L Offline
          L Offline
          lexected
          wrote on last edited by
          #4

          My findings regarding the targetChanged signal for anyone who wanders in here:

          • (a) If drag cursor dragEnterEvent()s a Widget and it acceptProposedAction()s, targetChanged(Widget) is emitted.

          • (b) If the Widget ignore()s the dragEnterEvent, targetChanged(nullptr) is emitted and it is not emitted anymore unless (a) happens again.

          My strong but unverified belief: if drag cursor leaves the Window that acceptProposedAction()s in dragEnterEvent, targetChanged(nullptr) is emitted.

          1 Reply Last reply
          1
          • D dcortesi

            I have now put EVERYTHING that I have learned about drag and drop in a series of blog posts that can be read here: http://thispageintentionally.blogspot.com/2014/01/ts-drag-and-drop-architecture-for.html

            mrjjM Offline
            mrjjM Offline
            mrjj
            Lifetime Qt Champion
            wrote on last edited by
            #5

            @dcortesi
            cool. thx for sharing.

            1 Reply Last reply
            0

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved