Qt World Summit: Submit your Presentation

Drag action change behavior between tree view widgets

  • Hello,

    I am coding an applications with C++ Qt 5.9.2 and have a problem understanding the drag icon behavior between tree view widgets or maybe it's a bug in qt.

    I subclass from QTreeView and QAbstractItemModel and overloarded the supportedDropActions() in my custom item model class, so I can set them manually and I am also setting the defaultDropAction for my tree view. I initialize the tree view/model like this (assume the model of the tree view is set already):


    First of all: What exactly does the Shift, Ctrl and Alt Key do while or before dragging? I couldn't find anything specific in the docs and by trying it seems that:

    • Shift = MoveAction
    • Ctrl = CopyAction
    • Alt = LinkAction (or switching between supported actions?)
      It also seems the Alt key switches the drag icon to CopyAction if the default is something else.

    I have following example application:

    TreeView1: (TV1)
    supportedDropActions: MoveAction | CopyAction
    defaultDropAction: CopyAction

    TreeView2: (TV2)
    supportedDropActions: MoveAction | CopyAction
    defaultDropAction: MoveAction

    TreeView3: (TV3)
    supportedDropActions: LinkAction | CopyAction
    defaultDropAction: LinkAction

    Scenario 1 (S1): Drag an item from TV1 to TV2
    Here I was expecting that the drag icon is changing from CopyAction (+) to MoveAction (->) when entering TV2, since the defaultDropAction is MoveAction, but it stays as CopyAction. Why is that? Is only the defaultDropAction from the dragged source considered for the drag icon when dragging into another widget?

    Scenario 2 (S2): Drag an item from TV2 to TV3
    I expected here the same as in S1, but since TV3 doesn't support MoveActions I expected to get a LinkAction as default. But let's ignore that for now. If I now hover over an item in TV3 and press Ctrl or Alt, nothing happens. Why it doesn't switch here to the supported actions of TV3?? At least CopyAction should work since TV2 supports that too.

    I didn't want to reimplement the dragEnterEvent and dragMoveEvent to manage the actions etc. manually (if that even helps), because then I have to code alot of things myself that QAbstractItemView already provides.

    Thanks in advance.

  • Lifetime Qt Champion

    Hi and welcome to devnet,

    The modifier changes from platform to platform for example, on macOS the CMD key replaces usually the Ctrl key.

    As for your other question a minimal compilable example would be nice to test the behaviour you have.

  • Hi and thx for the welcome.
    Ok i got that with the modifier behavior from platform to platform. Maybe i should have mentioned that my appl. is used in windows (7 - 10) only.
    I hoped it's a general problem and I don't need to post an example. Since my own test code contains my custom data models I have to make a general example first to show it here which takes some time. I'll post it when I'm done.

    Okey I don't have an example yet since I had no time to make one but I tried some things and my main issue is the following scenario: The drag source only supports MoveAction. I drag it into another widget which does not support MoveAction but CopyAction | LinkAction and it's default action is LinkAction.
    I was expecting the drag icon and action to be changed/updated according to the default drop action and supported drop actions of the target widget I am dragging into, which is not the case. The drag icon remains as the action from the drag source, in this case a MoveAction.

    So I tried to forcibly set it. I can overload the dropEvent handler in the target widget and set the drop action of the QDropEvent there as I need and pass it to the default event handler. To update the drag icon I can do the same with the dragEnterEvent and dragMoveEvent event. However, this is not enough since it also depends on the default drop action and supported drop actions which you can't set since the API doesn't provide that functionality. But the members are protected, so I made a custom class which inherits from QDropEvent, set the corresponding members there and passed the custom QDropEvent instead to the event handlers.

    And this is STILL not enough, since it also depends on the supported drag actions of the drag source, which I can separately set with overloading the supportedDragActions() method. But then I have the problem that if you drag something within the same widget, it switches the drag icon with the control modifiers, which may not be a supported drop action.

    Ok I managed to get it work. I was updating the default drop and drop action of the QEvent only when it's not the same widget. So I update it for the same widget too and it seems to work as I want.

Log in to reply