[Qt-interest] Drag and Drop when source is deleted

Bo Thorsen bo at fioniasoftware.dk
Fri May 20 15:09:35 CEST 2011


Den 20-05-2011 14:35, Martin Grossberger skrev:
>> Den 20-05-2011 11:48, Martin Grossberger skrev:
>>>> Den 20-05-2011 11:40, Martin Grossberger skrev:
>>>>>> Hi
>>>>>>
>>>>>> Am 20.05.2011 11:04, schrieb Martin Grossberger:
>>>>>>> However, the program still crashes before I can even check if the
>>>>>>> widget
>>>>>>> still exists on dropping.
>>>>>> Maybe it's not what you are dragin, but the drag object itself. Is it
>>>>>> created on the heap or is there a possibility that it gets
>>>>>> destroyed if
>>>>>> the corresponding widget gets deleted while you are dragging?
>>>>>>
>>>>>> Alex
>>>>>> _______________________________________________
>>>>>> Qt-interest mailing list
>>>>>> Qt-interest at qt.nokia.com
>>>>>> http://lists.qt.nokia.com/mailman/listinfo/qt-interest
>>>>> Hi,
>>>>>
>>>>> It is created on the heap. I've hacked together a minimalistic program
>>>>> to reproduce the issue, and it has the same issue.
>>>>> To reproduce the issue:
>>>>>
>>>>> 1. Compile the code attached
>>>>> 2. Start dragging the DragWidget and hold it for 5 seconds
>>>>> 3. After those 5 seconds the DragWidget gets deleted, if you drop
>>>>> now, the program will crash
>>>>
>>>> That's because you have created the drag object with the widget as
>>>> QObject parent. So when the widget is deleted, so is the drag object.
>>>>
>>>> Don't do that :)
>>>>
>>>> Bo Thorsen,
>>>> Fionia Software.
>>>>
>>> Can you send me a line of code how this should work?
>>> If I change the creation of the drag to:
>>> QDrag *drag = new QDrag(0);
>>> then no drag is actually happening.
>>
>> Sorry, that was the wrong direction. Apparently, you need to make sure
>> the widget is alive for as long as the drag is active. I didn't know
>> this. And it's IMO a Qt bug not to allow the drag source to be deleted.
>>
>> Bo Thorsen,
>> Fionia Software.
>>
> I was hoping there would be another solution, because I have found no
> way to tell if a drag&drop operation is occuring.
> If I understand the documentation correctly, the best approach would be
> to hide the widget instead of deleting it, and delete it once the
> drag&drop operation is done (in mouseMoveEvent? according to the docs
> QDrag::start or exec blocks the event loop).

One thing you can do is use the destroyed signal on all QObject 
subclasses plus a QPointer.

So where you start the drag, you do this:

class ... {

private:
   QPointer<QDrag*> mDrag;
}

startDrag() {
   // do the drag here
   mDrag.set(new QDrag);
   ...
}

wantToDelete() {
   if (mDrag.isNull()) {
     delete this;
   } else {
     connect(mDrag.data(), SIGNAL(destroyed()), SLOT(deleteLater()));
     hide();
   }
}

I hope you can figure it out based on this.

Bo Thorsen,
Fionia Software.

-- 

Expert Qt and C++ developer for hire
Contact me if you need expert Qt help
http://www.fioniasoftware.dk



More information about the Qt-interest-old mailing list