Hide default drag rendering

  • I have a QTreeView where the user can select an item and drag'n'drop it into a QGraphicsScene. Everything works very nicely so far.
    There is just a minor cosmetic issue that I would like to resolve: As soon as the item is being dragged out of the tree, a blue-ish selection box is being rendered underneath the cursor so the user knows that he is dragging something. That is no issue so far. My problem is that as soon as the dragEnterEvent() of the scene is called I start to render a QGraphicsItem at the mouse position. However, the blue selection box is on top of my QGraphicsItem which hides it partially.

    Can somebody tell me how I can hide that default 'dragged item rendering' as soon as the cursor enters the scene?

    I made a very short video showing the issue: http://screencast.com/t/oei8kqJBj

    Any help is highly appreciated.

  • Moderators

    You can't change the preview while the drag is in progress, but you can change it before it starts with setPixmap. So one way you can approach this is set this to an image of a button and only insert the real graphics item when the drop event occurs.

  • Thank you for your answer.
    Two things:

    1\ I don't have an image. The item is a QGraphicsItem with a custom paint method.

    2\ Where would I call QDrag::setPixmal()? I never create a QDrag object myself so far. All did was implementing the required mimeData methods into my tree model and enabling the dragging support.

  • Moderators

    1. Since you've got a custom paint method anyway you might as well use it to create an image of the button. Just use a QPainter that paints onto a pixmap.

    2. Ok, that makes it a little bit more complicated, but not much. The view has a virtual startDrag method that you can re-implement to create your own drag. The built-in implementation is about 20 lines long. You can just copy what it does and adjust to use your own image. Should be simple enough.

  • @Chris-Kawa I tried copying the code from the default implementation and putting it into the virtual method of my custom view class: http://code.qt.io/cgit/qt/qtbase.git/tree/src/widgets/itemviews/qabstractitemview.cpp#n3588
    However, I can't get it compiling as many things are not accessible and all the d-pointer magic is not available. After all it already starts with the fact that selectedDraggableIndexes() is not an API call.

    Am I doing something wrong or is there a way around this?

  • Moderators

    I didn't mean a 1:1 copy. Just the basic idea of what it's doing. Basically it's just taking the selected indices, getting the mime data from the model for them and creating a QDrag with that data. You can reimplement the same stuff using public API. Plus, since you know your data you can simplify.

    For example selectedDraggableIndexes is just taking the selection from selection model and removing non-draggable items. That's all available in the public functions. Same goes for other things - instead of d->model you can use model(), instead of d->defaultDropAction you can use defaultDropAction() and so on.

  • Yes, of course...
    Sorry, it was a long day and I didn't pay enough attention.

    I now managed to implement a working version. I don't yet render the QGraphicsItem into a QPixmap but for the first version I am pretty happy with the fact that it just doesn't render the standard selection box thingy.

    My code:

    void WidgetsLibraryView::startDrag(Qt::DropActions supportedActions)
        // Partly copied from Qt 5.5.5 sources
        QModelIndexList indexes = selectedIndexes();
        if (indexes.count() > 0) {
            // Get a list of the supported MIMEs of the selected indexes
            QMimeData* data = model()->mimeData(indexes);
            if (!data) {
            // Create the drag object
            QDrag* drag = new QDrag(this);
            // Execute the drag
            drag->exec(supportedActions, Qt::CopyAction);

    Thank you for your help! Very appreciated.

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.