Results 1 to 3 of 3

Thread: DragDrop problem : QDrag::start doesn't return without mousemove.

  1. #1
    Join Date
    Aug 2006
    Posts
    2
    Qt products
    Qt4
    Platforms
    MacOS X Windows

    Default DragDrop problem : QDrag::start doesn't return without mousemove.

    Hi

    I'm using Drag'n'Drgop with Qt. The drag is started in MouseMove event in one widget. It end in same or other widget. When I release the mouse the DropEvent is called. But sometimes, the QDrag::start doesn't return, when mouse is not moved. Drop is done, Drag does not end.

    This seem to happen, when the mouse moved by 1 pix during releasing the mousebutton.
    I'm using a code very similar to the example code from the tutorial.

    Could anyone help me out here ?

    kind regards

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: DragDrop problem : QDrag::start doesn't return without mousemove.

    Can we see the code?

  3. #3
    Join Date
    Aug 2006
    Posts
    2
    Qt products
    Qt4
    Platforms
    MacOS X Windows

    Default Re: DragDrop problem : QDrag::start doesn't return without mousemove.

    Here is the code, filled up with some stuff, which isn't needed, but I didn't want to remove stuff, which could be the problem.

    Qt Code:
    1. //! This is called, when a Drag'n'Drop is commin into this Widget
    2. //!
    3. void CsfDlg_Overview::dragEnterEvent(QDragEnterEvent *qEvent)
    4. {
    5. if(!this->mAllowedDropInto)
    6. qEvent->ignore();
    7. else if (qEvent->mimeData()->hasFormat(kMime_ThumbOverview.c_str())
    8. || qEvent->mimeData()->hasFormat(sfMime_SystemDragDrop.c_str()))
    9. {
    10. if ((qEvent->source() == this))
    11. {
    12. qEvent->setDropAction(Qt::MoveAction);
    13. qEvent->accept();
    14. }
    15. else
    16. {
    17. qEvent->acceptProposedAction();
    18. }
    19. }
    20. else
    21. qEvent->ignore();
    22. }
    23.  
    24. //! ..when the Drag'n'Drop is moved in this widget
    25. //!
    26. void CsfDlg_Overview::dragMoveEvent(QDragMoveEvent *qEvent)
    27. {
    28. if(!this->mAllowedDropInto)
    29. qEvent->ignore();
    30. else
    31. emit update();
    32. }
    33.  
    34. //! Called, when any drag and drop action was ended in this widget
    35. //!
    36. void CsfDlg_Overview::dropEvent(QDropEvent *qEvent)
    37. {
    38. emit update();
    39.  
    40. if (!qEvent->mimeData()->hasFormat(kMime_ThumbOverview.c_str())
    41. && !qEvent->mimeData()->hasFormat(sfMime_SystemDragDrop.c_str()))
    42. return;
    43. if(!this->mAllowedDropInto)
    44. return;
    45. if ((qEvent->dropAction() == Qt::MoveAction) || (qEvent->dropAction() == Qt::CopyAction))
    46. qEvent->acceptProposedAction();
    47. else
    48. return;
    49.  
    50. CsfThumbnailOverview *thumb(0), thumbTemp;
    51. if(qEvent->mimeData()->hasFormat(kMime_ThumbOverview.c_str()))
    52. {
    53. // This seem to be a drag drop event from another thumbnail window
    54. // The thumbnails are complete in the datastream and need to be read
    55.  
    56. QByteArray itemData(qEvent->mimeData()->data(kMime_ThumbOverview.c_str()));
    57. QDataStream dataStream(&itemData, QIODevice::ReadOnly);
    58. int quant(0);
    59. CsfPoint basePoint, topleftP, curP, hotSpot;
    60.  
    61. dataStream >> basePoint;
    62. dataStream >> hotSpot;
    63. dataStream >> quant;
    64. if(!this->mReposition)
    65. topleftP = CsfPoint(qEvent->pos())-hotSpot;
    66. while(quant > 0)
    67. {
    68. dataStream >> thumbTemp;
    69.  
    70. if(!this->mReposition)
    71. {
    72. curP = thumbTemp.getPosition();
    73. curP -= basePoint;
    74. curP += topleftP;
    75. curP += this->mScrollPos;
    76. thumbTemp.setPosition(curP);
    77. }
    78.  
    79. if((this->getThumbnailFromName(thumbTemp.getImageFile()) == NULL) || (qEvent->source() == this))
    80. {
    81. thumb = this->addThumbnailToList();
    82. *thumb = thumbTemp;
    83. if(!thumb->isThumbnailLowsized())
    84. thumb->setImageFile(thumb->getImageFile(), true);
    85. }
    86. --quant;
    87. }
    88. this->slotChangeSizeAbs(this->mThumbSize);
    89.  
    90. if ((qEvent->source() == this))
    91. {
    92. qEvent->setDropAction(Qt::MoveAction);
    93. qEvent->accept();
    94. }
    95. else
    96. qEvent->acceptProposedAction();
    97. }
    98. else if(qEvent->mimeData()->hasFormat(sfMime_SystemDragDrop.c_str()))
    99. {
    100. // This event comes from the desktop an includes just the names of the
    101. // files given.
    102.  
    103. CsfString strg, ext;
    104. QByteArray itemData(qEvent->mimeData()->data(sfMime_SystemDragDrop.c_str()));
    105. std::vector<CsfStringA> filterListIn;
    106.  
    107. filterListIn = sIMAGEFILELIST.getImageExtensionList();
    108. QList<QUrl> urls = qEvent->mimeData()->urls();
    109. foreach(QUrl url, urls)
    110. {
    111. strg = url.toLocalFile();
    112. if(strg.left(1) == "/")
    113. strg = strg.right(strg.getLength() - 1);
    114. // Sort file out, when the extension is not known
    115. bool allowed(false);
    116. for(std::vector<CsfStringA>::const_iterator iter = filterListIn.begin(); iter != filterListIn.end(); ++iter)
    117. {
    118. ext = strg.right((*iter).getLength());
    119. ext.makeLower();
    120. if(ext == (*iter))
    121. {
    122. allowed = true;
    123. break;
    124. }
    125. }
    126. if(!allowed) continue;
    127. if(this->getThumbnailFromName(strg) == NULL)
    128. {
    129. thumb = this->addThumbnailToList();
    130. thumb->setImageFile(strg);
    131. if(!this->mReposition)
    132. thumb->setPosition(CsfPoint(qEvent->pos())+this->mScrollPos);
    133. }
    134. }
    135.  
    136. this->slotChangeSizeAbs(this->mThumbSize);
    137.  
    138. if ((qEvent->source() == this))
    139. {
    140. qEvent->setDropAction(Qt::MoveAction);
    141. qEvent->accept();
    142. }
    143. else
    144. {
    145. qEvent->setDropAction(Qt::CopyAction);
    146. qEvent->accept();
    147. }
    148. }
    149. }
    150.  
    151. //********************************************************************************
    152. // Events commin from using the mouse
    153. //********************************************************************************
    154.  
    155. //! mouseMoveEvent is called everytime, when the mouse cursor is moved over the window
    156. //! This method starts the drag/drop if needed and emit an update, when mouse is still clicked.
    157. //! - Not called after drag/drop started.
    158. void CsfDlg_Overview::mouseMoveEvent(QMouseEvent* qEvent)
    159. {
    160. QPoint pt(qEvent->pos());
    161. std::list<CsfThumbnailOverview*> activeThumb;;
    162.  
    163. this->mMouseCurrent = CsfPoint(pt);
    164.  
    165. while((this->mMouseState &= sfMouseState_Dragging) &&
    166. (this->mMouseStart.distance(this->mMouseCurrent) > 15.0)) // distance (pixel) when starting the drag/ drop
    167. {
    168. // We need to drag / drop the current thumbnail.
    169. QDrag *drag = new QDrag(this);
    170. QByteArray itemData;
    171. QDataStream dataStream(&itemData, QIODevice::WriteOnly);
    172. QMimeData *mimeData = new QMimeData;
    173. iterator iter, end;
    174. CsfRect rect, thumbRect;
    175. CsfPoint point2, point;
    176.  
    177. end = this->mThumbList.end();
    178. for(iter = this->mThumbList.begin(); iter != end; ++iter)
    179. {
    180. if(iter->getState() == sfMouseState_Dragging)
    181. {
    182. activeThumb.clear();
    183. break;
    184. }
    185. if(iter->isThumbnailActive())
    186. {
    187. activeThumb.push_back(&(*iter));
    188. iter->setState(sfMouseState_Dragging);
    189. if(rect.empty())
    190. rect = iter->getRect();
    191. else
    192. rect.setUnion(rect, iter->getRect());
    193. }
    194. }
    195.  
    196. if(activeThumb.size() == 0)
    197. break;
    198.  
    199. // Painting all thumbnails, wich will be used for drag/drop in an drag/drop image.
    200. QPixmap pixmap(rect.width(), rect.height());
    201. pixmap.fill(QColor(0, 0, 0, 0));
    202. point = this->mMouseStart - (rect.getTopLeft() - this->mScrollPos);
    203. point2 = rect.getTopLeft();
    204. for(std::list<CsfThumbnailOverview*>::iterator iter2 = activeThumb.begin(); iter2 != activeThumb.end(); ++iter2)
    205. {
    206. QPainter painter(&pixmap);
    207. CsfPoint whereTo((*iter2)->getRect().getTopLeft() - point2);
    208.  
    209. painter.drawPixmap(QPoint(whereTo), (*iter2)->getPreRendered());
    210. }
    211.  
    212. { // The thumbnails need an alpha.
    213. QPainter painter(&pixmap);
    214.  
    215. painter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
    216. painter.setPen(QColor(255, 255, 255, 120));
    217. painter.setBrush(QColor(255, 255, 255, 120));
    218. painter.drawRect(0, 0, pixmap.width(), pixmap.height());
    219. }
    220.  
    221. // Now we savin the thumbnail in the drag / drop.
    222. dataStream << point2; // Absolute position, where thumbs were located.
    223. dataStream << point; // Hotspot of the drag.
    224. dataStream << static_cast<int>(activeThumb.size()); // How many thumbnails
    225. for(std::list<CsfThumbnailOverview*>::iterator iter2 = activeThumb.begin(); iter2 != activeThumb.end(); ++iter2)
    226. {
    227. dataStream << *(*iter2);
    228. }
    229. mimeData->setData(kMime_ThumbOverview.c_str(), itemData);
    230.  
    231. drag->setMimeData(mimeData);
    232. drag->setPixmap(pixmap);
    233. drag->setHotSpot(point);
    234.  
    235. Qt::DropAction result = drag->start(Qt::CopyAction | (this->mAllowedDropInto ? Qt::MoveAction : Qt::IgnoreAction));
    236.  
    237. this->mMouseState &= sfMouseState_Nothing;
    238.  
    239. if(result == Qt::MoveAction && this->mAllowedDropInto)
    240. {
    241. for(std::list<CsfThumbnailOverview*>::iterator iter2 = activeThumb.begin(); iter2 != activeThumb.end(); ++iter2)
    242. {
    243. end = this->mThumbList.end();
    244. for(iter = this->mThumbList.begin(); iter != end; ++iter)
    245. {
    246. if(&(*iter) == (*iter2))
    247. {
    248. this->mThumbList.erase(iter);
    249. break;
    250. }
    251. }
    252. }
    253. this->slotChangeSizeAbs(this->mThumbSize);
    254. }
    255.  
    256. end = this->mThumbList.end();
    257. for(iter = this->mThumbList.begin(); iter != end; ++iter)
    258. iter->setState(sfMouseState_Nothing);
    259.  
    260. emit update();
    261. }
    262. if((this->mMouseState & sfMouseState_Clicked))
    263. {
    264. emit update();
    265. }
    266. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by jacek; 8th August 2006 at 18:09. Reason: splitted too long line

Similar Threads

  1. Version 4.1.3 and QTreeView
    By greencastor in forum Qt Programming
    Replies: 2
    Last Post: 13th June 2006, 10:37
  2. Problem with custom widget
    By jnana in forum Qt Programming
    Replies: 3
    Last Post: 15th March 2006, 11:55

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.