1/**************************************************************************** 2** 3** Copyright (C) 2016 The Qt Company Ltd. 4** Contact: https://www.qt.io/licensing/ 5** 6** This file is part of the documentation of the Qt Toolkit. 7** 8** $QT_BEGIN_LICENSE:FDL$ 9** Commercial License Usage 10** Licensees holding valid commercial Qt licenses may use this file in 11** accordance with the commercial license agreement provided with the 12** Software or, alternatively, in accordance with the terms contained in 13** a written agreement between you and The Qt Company. For licensing terms 14** and conditions see https://www.qt.io/terms-conditions. For further 15** information use the contact form at https://www.qt.io/contact-us. 16** 17** GNU Free Documentation License Usage 18** Alternatively, this file may be used under the terms of the GNU Free 19** Documentation License version 1.3 as published by the Free Software 20** Foundation and appearing in the file included in the packaging of 21** this file. Please review the following information to ensure 22** the GNU Free Documentation License version 1.3 requirements 23** will be met: https://www.gnu.org/licenses/fdl-1.3.html. 24** $QT_END_LICENSE$ 25** 26****************************************************************************/ 27 28/*! 29 \page dnd.html 30 \title Drag and Drop 31 \brief An overview of the drag and drop system provided by Qt. 32 33 \ingroup qt-gui-concepts 34 35 Drag and drop provides a simple visual mechanism which users can use 36 to transfer information between and within applications. Drag 37 and drop is similar in function to the clipboard's cut and paste 38 mechanism. 39 40 \tableofcontents 41 42 This document describes the basic drag and drop mechanism and 43 outlines the approach used to enable it in custom controls. Drag 44 and drop operations are also supported by many of Qt's controls, 45 such as the item views and graphics view framework, as well as 46 editing controls for Qt Widgets and Qt Quick. More information 47 about item views and graphics view is available in 48 \l{Using drag and drop with item views} and \l{Graphics View 49 Framework}. 50 51 \section1 Drag and Drop Classes 52 53 These classes deal with drag and drop and the necessary mime type 54 encoding and decoding. 55 56 \annotatedlist draganddrop 57 58 \section1 Configuration 59 60 The QStyleHints object provides some properties that are related 61 to drag and drop operations: 62 63 \list 64 \li \l{QStyleHints::startDragTime()} describes the amount of time in 65 milliseconds that the user must hold down a mouse button over an 66 object before a drag will begin. 67 \li \l{QStyleHints::startDragDistance()} indicates how far the user has to 68 move the mouse while holding down a mouse button before the movement 69 will be interpreted as dragging. 70 \li \l{QStyleHints::startDragVelocity()} indicates how fast (in pixels/second) 71 the user has to move the mouse to start a drag. A value of \c 0 means 72 that there is no such limit. 73 \endlist 74 75 These quantities provide sensible default values that are compliant with 76 the underlying windowing system for you to use if you 77 provide drag and drop support in your controls. 78 79 \section1 Drag and Drop in Qt Quick 80 81 The rest of the document focuses mainly on how to implement drag and drop 82 in C++. For using drag and drop inside a Qt Quick scene, please read the 83 documentation for the Qt Quick \l{Drag}, \l{DragEvent}, and \l{DropArea} items, 84 as well as the \l {Qt Quick Examples - Drag and Drop}{Qt Quick Drag and Drop} examples. 85 86 \section1 Dragging 87 88 To start a drag, create a QDrag object, and call its 89 exec() function. In most applications, it is a good idea to begin a drag 90 and drop operation only after a mouse button has been pressed and the 91 cursor has been moved a certain distance. However, the simplest way to 92 enable dragging from a widget is to reimplement the widget's 93 \l{QWidget::mousePressEvent()}{mousePressEvent()} and start a drag 94 and drop operation: 95 96 \snippet dragging/mainwindow.cpp 0 97 \dots 8 98 \snippet dragging/mainwindow.cpp 2 99 100 Although the user may take some time to complete the dragging operation, 101 as far as the application is concerned the exec() function is a blocking 102 function that returns with \l{Qt::DropActions}{one of several values}. 103 These indicate how the operation ended, and are described in more detail 104 below. 105 106 Note that the exec() function does not block the main event loop. 107 108 For widgets that need to distinguish between mouse clicks and drags, it 109 is useful to reimplement the widget's 110 \l{QWidget::mousePressEvent()}{mousePressEvent()} function to record to 111 start position of the drag: 112 113 \snippet draganddrop/dragwidget.cpp 6 114 115 Later, in \l{QWidget::mouseMoveEvent()}{mouseMoveEvent()}, we can determine 116 whether a drag should begin, and construct a drag object to handle the 117 operation: 118 119 \snippet draganddrop/dragwidget.cpp 7 120 \dots 121 \snippet draganddrop/dragwidget.cpp 8 122 123 This particular approach uses the \l QPoint::manhattanLength() function 124 to get a rough estimate of the distance between where the mouse click 125 occurred and the current cursor position. This function trades accuracy 126 for speed, and is usually suitable for this purpose. 127 128 \section1 Dropping 129 130 To be able to receive media dropped on a widget, call 131 \l{QWidget::setAcceptDrops()}{setAcceptDrops(true)} for the widget, 132 and reimplement the \l{QWidget::dragEnterEvent()}{dragEnterEvent()} and 133 \l{QWidget::dropEvent()}{dropEvent()} event handler functions. 134 135 For example, the following code enables drop events in the constructor of 136 a QWidget subclass, making it possible to usefully implement drop event 137 handlers: 138 139 \snippet dropevents/window.cpp 0 140 \dots 141 \snippet dropevents/window.cpp 1 142 \snippet dropevents/window.cpp 2 143 144 The dragEnterEvent() function is typically used to inform Qt about the 145 types of data that the widget accepts. 146 You must reimplement this function if you want to receive either 147 QDragMoveEvent or QDropEvent in your reimplementations of 148 \l{QWidget::dragMoveEvent()}{dragMoveEvent()} and 149 \l{QWidget::dropEvent()}{dropEvent()}. 150 151 The following code shows how \l{QWidget::dragEnterEvent()}{dragEnterEvent()} 152 can be reimplemented to 153 tell the drag and drop system that we can only handle plain text: 154 155 \snippet dropevents/window.cpp 3 156 157 The \l{QWidget::dropEvent()}{dropEvent()} is used to unpack dropped data 158 and handle it in way that is suitable for your application. 159 160 In the following code, the text supplied in the event is passed to a 161 QTextBrowser and a QComboBox is filled with the list of MIME types that 162 are used to describe the data: 163 164 \snippet dropevents/window.cpp 4 165 166 In this case, we accept the proposed action without checking what it is. 167 In a real world application, it may be necessary to return from the 168 \l{QWidget::dropEvent()}{dropEvent()} function without accepting the 169 proposed action or handling 170 the data if the action is not relevant. For example, we may choose to 171 ignore Qt::LinkAction actions if we do not support 172 links to external sources in our application. 173 174 \section2 Overriding Proposed Actions 175 176 We may also ignore the proposed action, and perform some other action on 177 the data. To do this, we would call the event object's 178 \l{QDropEvent::setDropAction()}{setDropAction()} with the preferred 179 action from Qt::DropAction before calling \l{QEvent::}{accept()}. 180 This ensures that the replacement drop action is used instead of the 181 proposed action. 182 183 For more sophisticated applications, reimplementing 184 \l{QWidget::dragMoveEvent()}{dragMoveEvent()} and 185 \l{QWidget::dragLeaveEvent()}{dragLeaveEvent()} will let you make 186 certain parts of your widgets sensitive to drop events, and give you more 187 control over drag and drop in your application. 188 189 \section2 Subclassing Complex Widgets 190 191 Certain standard Qt widgets provide their own support for drag and drop. 192 When subclassing these widgets, it may be necessary to reimplement 193 \l{QWidget::dragMoveEvent()}{dragMoveEvent()} in addition to 194 \l{QWidget::dragEnterEvent()}{dragEnterEvent()} and 195 \l{QWidget::dropEvent()}{dropEvent()} to prevent the base class from 196 providing default drag and drop handling, and to handle any special 197 cases you are interested in. 198 199 \section1 Drag and Drop Actions 200 201 In the simplest case, the target of a drag and drop action receives a 202 copy of the data being dragged, and the source decides whether to 203 delete the original. This is described by the \c CopyAction action. 204 The target may also choose to handle other actions, specifically the 205 \c MoveAction and \c LinkAction actions. If the source calls 206 QDrag::exec(), and it returns \c MoveAction, the source is responsible 207 for deleting any original data if it chooses to do so. The QMimeData 208 and QDrag objects created by the source widget \e{should not be deleted} 209 - they will be destroyed by Qt. The target is responsible for taking 210 ownership of the data sent in the drag and drop operation; this is 211 usually done by keeping references to the data. 212 213 If the target understands the \c LinkAction action, it should 214 store its own reference to the original information; the source 215 does not need to perform any further processing on the data. The 216 most common use of drag and drop actions is when performing a 217 Move within the same widget; see the section on \l{Drop Actions} 218 for more information about this feature. 219 220 The other major use of drag actions is when using a reference type 221 such as text/uri-list, where the dragged data are actually references 222 to files or objects. 223 224 \section1 Adding New Drag and Drop Types 225 226 Drag and drop is not limited to text and images. Any type of information 227 can be transferred in a drag and drop operation. To drag information 228 between applications, the applications must be able to indicate to each 229 other which data formats they can accept and which they can produce. 230 This is achieved using 231 \l{http://www.rfc-editor.org/rfc/rfc1341.txt}{MIME types}. The QDrag 232 object constructed by the source contains a list of MIME types that it 233 uses to represent the data (ordered from most appropriate to least 234 appropriate), and the drop target uses one of these to access the data. 235 For common data types, the convenience functions handle the MIME types 236 used transparently but, for custom data types, it is necessary to 237 state them explicitly. 238 239 To implement drag and drop actions for a type of information that is 240 not covered by the QDrag convenience functions, the first and most 241 important step is to look for existing formats that are appropriate: 242 The Internet Assigned Numbers Authority (\l{http://www.iana.org}{IANA}) 243 provides a 244 \l{http://www.iana.org/assignments/media-types/}{hierarchical 245 list of MIME media types} at the Information Sciences Institute 246 (\l{http://www.isi.edu}{ISI}). 247 Using standard MIME types maximizes the interoperability of 248 your application with other software now and in the future. 249 250 To support an additional media type, simply set the data in the QMimeData 251 object with the \l{QMimeData::setData()}{setData()} function, supplying 252 the full MIME type and a QByteArray containing the data in the appropriate 253 format. The following code takes a pixmap from a label and stores it 254 as a Portable Network Graphics (PNG) file in a QMimeData object: 255 256 \snippet separations/finalwidget.cpp 0 257 258 Of course, for this case we could have simply used 259 \l{QMimeData::setImageData()}{setImageData()} instead to supply image data 260 in a variety of formats: 261 262 \snippet separations/finalwidget.cpp 1 263 264 The QByteArray approach is still useful in this case because it provides 265 greater control over the amount of data stored in the QMimeData object. 266 267 Note that custom datatypes used in item views must be declared as 268 \l{QMetaObject}{meta objects} and that stream operators for them 269 must be implemented. 270 271 \section1 Drop Actions 272 273 In the clipboard model, the user can \e cut or \e copy the source 274 information, then later paste it. Similarly in the drag and drop 275 model, the user can drag a \e copy of the information or they can drag 276 the information itself to a new place (\e moving it). The 277 drag and drop model has an additional complication for the programmer: 278 The program doesn't know whether the user wants to cut or copy the 279 information until the operation is complete. This often makes no 280 difference when dragging information between applications, but within 281 an application it is important to check which drop action was used. 282 283 We can reimplement the mouseMoveEvent() for a widget, and start a drag 284 and drop operation with a combination of possible drop actions. For 285 example, we may want to ensure that dragging always moves objects in 286 the widget: 287 288 \snippet draganddrop/dragwidget.cpp 7 289 \dots 290 \snippet draganddrop/dragwidget.cpp 8 291 292 The action returned by the exec() function may default to a 293 \c CopyAction if the information is dropped into another application 294 but, if it is dropped in another widget in the same application, we 295 may obtain a different drop action. 296 297 The proposed drop actions can be filtered in a widget's dragMoveEvent() 298 function. However, it is possible to accept all proposed actions in 299 the dragEnterEvent() and let the user decide which they want to accept 300 later: 301 302 \snippet draganddrop/dragwidget.cpp 0 303 304 When a drop occurs in the widget, the dropEvent() handler function is 305 called, and we can deal with each possible action in turn. First, we 306 deal with drag and drop operations within the same widget: 307 308 \snippet draganddrop/dragwidget.cpp 1 309 310 In this case, we refuse to deal with move operations. Each type of drop 311 action that we accept is checked and dealt with accordingly: 312 313 \snippet draganddrop/dragwidget.cpp 2 314 \snippet draganddrop/dragwidget.cpp 3 315 \snippet draganddrop/dragwidget.cpp 4 316 \dots 317 \snippet draganddrop/dragwidget.cpp 5 318 319 Note that we checked for individual drop actions in the above code. 320 As mentioned above in the section on 321 \l{#Overriding Proposed Actions}{Overriding Proposed Actions}, it is 322 sometimes necessary to override the proposed drop action and choose a 323 different one from the selection of possible drop actions. 324 To do this, you need to check for the presence of each action in the value 325 supplied by the event's \l{QDropEvent::}{possibleActions()}, set the drop 326 action with \l{QDropEvent::}{setDropAction()}, and call 327 \l{QEvent::}{accept()}. 328 329 \section1 Drop Rectangles 330 331 The widget's dragMoveEvent() can be used to restrict drops to certain parts 332 of the widget by only accepting the proposed drop actions when the cursor 333 is within those areas. For example, the following code accepts any proposed 334 drop actions when the cursor is over a child widget (\c dropFrame): 335 336 \snippet droprectangle/window.cpp 0 337 338 The dragMoveEvent() can also be used if you need to give visual 339 feedback during a drag and drop operation, to scroll the window, or 340 whatever is appropriate. 341 342 \section1 The Clipboard 343 344 Applications can also communicate with each other by putting data on 345 the clipboard. To access this, you need to obtain a QClipboard object 346 from the QApplication object. 347 348 The QMimeData class is used to represent data that is transferred to and 349 from the clipboard. To put data on the clipboard, you can use the 350 setText(), setImage(), and setPixmap() convenience functions for common 351 data types. These functions are similar to those found in the QMimeData 352 class, except that they also take an additional argument that controls 353 where the data is stored: If \l{QClipboard::Mode}{Clipboard} is 354 specified, the data is placed on the clipboard; if 355 \l{QClipboard::Mode}{Selection} is specified, the data is placed in the 356 mouse selection (on X11 only). By default, data is put on the clipboard. 357 358 For example, we can copy the contents of a QLineEdit to the clipboard 359 with the following code: 360 361 \snippet ../widgets/widgets/charactermap/mainwindow.cpp 11 362 363 Data with different MIME types can also be put on the clipboard. 364 Construct a QMimeData object and set data with setData() function in 365 the way described in the previous section; this object can then be 366 put on the clipboard with the 367 \l{QClipboard::setMimeData()}{setMimeData()} function. 368 369 The QClipboard class can notify the application about changes to the 370 data it contains via its \l{QClipboard::dataChanged()}{dataChanged()} 371 signal. For example, we can monitor the clipboard by connecting this 372 signal to a slot in a widget: 373 374 \snippet clipboard/clipwindow.cpp 0 375 376 The slot connected to this signal can read the data on the clipboard 377 using one of the MIME types that can be used to represent it: 378 379 \snippet clipboard/clipwindow.cpp 1 380 \dots 381 \snippet clipboard/clipwindow.cpp 2 382 383 The \l{QClipboard::selectionChanged()}{selectionChanged()} signal can 384 be used on X11 to monitor the mouse selection. 385 386 \section1 Examples 387 388 \list 389 \li \l{draganddrop/draggableicons}{Draggable Icons} 390 \li \l{draganddrop/draggabletext}{Draggable Text} 391 \li \l{draganddrop/dropsite}{Drop Site} 392 \li \l{draganddrop/fridgemagnets}{Fridge Magnets} 393 \li \l{draganddrop/puzzle}{Drag and Drop Puzzle} 394 \endlist 395 396 \section1 Interoperating with Other Applications 397 398 On X11, the public \l{http://www.newplanetsoftware.com/xdnd/}{XDND 399 protocol} is used, while on Windows Qt uses the OLE standard, and 400 Qt for \macos uses the Cocoa Drag Manager. On X11, XDND uses MIME, 401 so no translation is necessary. The Qt API is the same regardless of 402 the platform. On Windows, MIME-aware applications can communicate by 403 using clipboard format names that are MIME types. Already some 404 Windows applications use MIME naming conventions for their 405 clipboard formats. 406 407 Custom classes for translating proprietary clipboard formats can be 408 registered by reimplementing QWinMime on Windows or 409 QMacPasteboardMime on \macos. 410 411*/ 412