1
/****************************************************************************
3
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4
** All rights reserved.
5
** Contact: Nokia Corporation (qt-info@nokia.com)
7
** This file is part of the documentation of the Qt Toolkit.
9
** $QT_BEGIN_LICENSE:LGPL$
10
** No Commercial Usage
11
** This file contains pre-release code and may not be distributed.
12
** You may use this file in accordance with the terms and conditions
13
** contained in the Technology Preview License Agreement accompanying
16
** GNU Lesser General Public License Usage
17
** Alternatively, this file may be used under the terms of the GNU Lesser
18
** General Public License version 2.1 as published by the Free Software
19
** Foundation and appearing in the file LICENSE.LGPL included in the
20
** packaging of this file. Please review the following information to
21
** ensure the GNU Lesser General Public License version 2.1 requirements
22
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24
** In addition, as a special exception, Nokia gives you certain additional
25
** rights. These rights are described in the Nokia Qt LGPL Exception
26
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28
** If you have questions regarding the use of this file, please contact
29
** Nokia at qt-info@nokia.com.
40
****************************************************************************/
44
\title Drag And Drop Classes
46
\brief Classes dealing with drag and drop and mime type encoding and decoding.
52
\brief An overview of the drag and drop system provided by Qt.
54
\ingroup frameworks-technologies
56
Drag and drop provides a simple visual mechanism which users can use
57
to transfer information between and within applications. (In the
58
literature this is referred to as a "direct manipulation model".) Drag
59
and drop is similar in function to the clipboard's cut and paste
64
This document describes the basic drag and drop mechanism and
65
outlines the approach used to enable it in custom widgets. Drag
66
and drop operations are also supported by Qt's item views and by
67
the graphics view framework; more information is available in the
68
\l{Using Drag and Drop with Item Views} and \l{The Graphics View
71
\section1 Drag and Drop Classes
73
These classes deal with drag and drop and the necessary mime type
74
encoding and decoding.
76
\annotatedlist draganddrop
78
\section1 Configuration
80
The QApplication object provides some properties that are related
81
to drag and drop operations:
84
\i \l{QApplication::startDragTime} describes the amount of time in
85
milliseconds that the user must hold down a mouse button over an
86
object before a drag will begin.
87
\i \l{QApplication::startDragDistance} indicates how far the user has to
88
move the mouse while holding down a mouse button before the movement
89
will be interpreted as dragging. Use of high values for this quantity
90
prevents accidental dragging when the user only meant to click on an
94
These quantities provide sensible default values for you to use if you
95
provide drag and drop support in your widgets.
99
To start a drag, create a QDrag object, and call its
100
exec() function. In most applications, it is a good idea to begin a drag
101
and drop operation only after a mouse button has been pressed and the
102
cursor has been moved a certain distance. However, the simplest way to
103
enable dragging from a widget is to reimplement the widget's
104
\l{QWidget::mousePressEvent()}{mousePressEvent()} and start a drag
107
\snippet doc/src/snippets/dragging/mainwindow.cpp 0
109
\snippet doc/src/snippets/dragging/mainwindow.cpp 2
111
Although the user may take some time to complete the dragging operation,
112
as far as the application is concerned the exec() function is a blocking
113
function that returns with \l{Qt::DropActions}{one of several values}.
114
These indicate how the operation ended, and are described in more detail
117
Note that the exec() function does not block the main event loop.
119
For widgets that need to distinguish between mouse clicks and drags, it
120
is useful to reimplement the widget's
121
\l{QWidget::mousePressEvent()}{mousePressEvent()} function to record to
122
start position of the drag:
124
\snippet doc/src/snippets/draganddrop/dragwidget.cpp 6
126
Later, in \l{QWidget::mouseMoveEvent()}{mouseMoveEvent()}, we can determine
127
whether a drag should begin, and construct a drag object to handle the
130
\snippet doc/src/snippets/draganddrop/dragwidget.cpp 7
132
\snippet doc/src/snippets/draganddrop/dragwidget.cpp 8
134
This particular approach uses the \l QPoint::manhattanLength() function
135
to get a rough estimate of the distance between where the mouse click
136
occurred and the current cursor position. This function trades accuracy
137
for speed, and is usually suitable for this purpose.
141
To be able to receive media dropped on a widget, call
142
\l{QWidget::setAcceptDrops()}{setAcceptDrops(true)} for the widget,
143
and reimplement the \l{QWidget::dragEnterEvent()}{dragEnterEvent()} and
144
\l{QWidget::dropEvent()}{dropEvent()} event handler functions.
146
For example, the following code enables drop events in the constructor of
147
a QWidget subclass, making it possible to usefully implement drop event
150
\snippet doc/src/snippets/dropevents/window.cpp 0
152
\snippet doc/src/snippets/dropevents/window.cpp 1
153
\snippet doc/src/snippets/dropevents/window.cpp 2
155
The dragEnterEvent() function is typically used to inform Qt about the
156
types of data that the widget accepts.
157
You must reimplement this function if you want to receive either
158
QDragMoveEvent or QDropEvent in your reimplementations of
159
\l{QWidget::dragMoveEvent()}{dragMoveEvent()} and
160
\l{QWidget::dropEvent()}{dropEvent()}.
162
The following code shows how \l{QWidget::dragEnterEvent()}{dragEnterEvent()}
163
can be reimplemented to
164
tell the drag and drop system that we can only handle plain text:
166
\snippet doc/src/snippets/dropevents/window.cpp 3
168
The \l{QWidget::dropEvent()}{dropEvent()} is used to unpack dropped data
169
and handle it in way that is suitable for your application.
171
In the following code, the text supplied in the event is passed to a
172
QTextBrowser and a QComboBox is filled with the list of MIME types that
173
are used to describe the data:
175
\snippet doc/src/snippets/dropevents/window.cpp 4
177
In this case, we accept the proposed action without checking what it is.
178
In a real world application, it may be necessary to return from the
179
\l{QWidget::dropEvent()}{dropEvent()} function without accepting the
180
proposed action or handling
181
the data if the action is not relevant. For example, we may choose to
182
ignore Qt::LinkAction actions if we do not support
183
links to external sources in our application.
185
\section2 Overriding Proposed Actions
187
We may also ignore the proposed action, and perform some other action on
188
the data. To do this, we would call the event object's
189
\l{QDropEvent::setDropAction()}{setDropAction()} with the preferred
190
action from Qt::DropAction before calling \l{QEvent::}{accept()}.
191
This ensures that the replacement drop action is used instead of the
194
For more sophisticated applications, reimplementing
195
\l{QWidget::dragMoveEvent()}{dragMoveEvent()} and
196
\l{QWidget::dragLeaveEvent()}{dragLeaveEvent()} will let you make
197
certain parts of your widgets sensitive to drop events, and give you more
198
control over drag and drop in your application.
200
\section2 Subclassing Complex Widgets
202
Certain standard Qt widgets provide their own support for drag and drop.
203
When subclassing these widgets, it may be necessary to reimplement
204
\l{QWidget::dragMoveEvent()}{dragMoveEvent()} in addition to
205
\l{QWidget::dragEnterEvent()}{dragEnterEvent()} and
206
\l{QWidget::dropEvent()}{dropEvent()} to prevent the base class from
207
providing default drag and drop handling, and to handle any special
208
cases you are interested in.
210
\section1 Drag and Drop Actions
212
In the simplest case, the target of a drag and drop action receives a
213
copy of the data being dragged, and the source decides whether to
214
delete the original. This is described by the \c CopyAction action.
215
The target may also choose to handle other actions, specifically the
216
\c MoveAction and \c LinkAction actions. If the source calls
217
QDrag::exec(), and it returns \c MoveAction, the source is responsible
218
for deleting any original data if it chooses to do so. The QMimeData
219
and QDrag objects created by the source widget \e{should not be deleted}
220
- they will be destroyed by Qt. The target is responsible for taking
221
ownership of the data sent in the drag and drop operation; this is
222
usually done by keeping references to the data.
224
If the target understands the \c LinkAction action, it should
225
store its own reference to the original information; the source
226
does not need to perform any further processing on the data. The
227
most common use of drag and drop actions is when performing a
228
Move within the same widget; see the section on \l{Drop Actions}
229
for more information about this feature.
231
The other major use of drag actions is when using a reference type
232
such as text/uri-list, where the dragged data are actually references
235
\section1 Adding New Drag and Drop Types
237
Drag and drop is not limited to text and images. Any type of information
238
can be transferred in a drag and drop operation. To drag information
239
between applications, the applications must be able to indicate to each
240
other which data formats they can accept and which they can produce.
241
This is achieved using
242
\l{http://www.rfc-editor.org/rfc/rfc1341.txt}{MIME types}. The QDrag
243
object constructed by the source contains a list of MIME types that it
244
uses to represent the data (ordered from most appropriate to least
245
appropriate), and the drop target uses one of these to access the data.
246
For common data types, the convenience functions handle the MIME types
247
used transparently but, for custom data types, it is necessary to
248
state them explicitly.
250
To implement drag and drop actions for a type of information that is
251
not covered by the QDrag convenience functions, the first and most
252
important step is to look for existing formats that are appropriate:
253
The Internet Assigned Numbers Authority (\l{http://www.iana.org}{IANA})
255
\l{http://www.iana.org/assignments/media-types/}{hierarchical
256
list of MIME media types} at the Information Sciences Institute
257
(\l{http://www.isi.edu}{ISI}).
258
Using standard MIME types maximizes the interoperability of
259
your application with other software now and in the future.
261
To support an additional media type, simply set the data in the QMimeData
262
object with the \l{QMimeData::setData()}{setData()} function, supplying
263
the full MIME type and a QByteArray containing the data in the appropriate
264
format. The following code takes a pixmap from a label and stores it
265
as a Portable Network Graphics (PNG) file in a QMimeData object:
267
\snippet doc/src/snippets/separations/finalwidget.cpp 0
269
Of course, for this case we could have simply used
270
\l{QMimeData::setImageData()}{setImageData()} instead to supply image data
271
in a variety of formats:
273
\snippet doc/src/snippets/separations/finalwidget.cpp 1
275
The QByteArray approach is still useful in this case because it provides
276
greater control over the amount of data stored in the QMimeData object.
278
Note that custom datatypes used in item views must be declared as
279
\l{QMetaObject}{meta objects} and that stream operators for them
282
\section1 Drop Actions
284
In the clipboard model, the user can \e cut or \e copy the source
285
information, then later paste it. Similarly in the drag and drop
286
model, the user can drag a \e copy of the information or they can drag
287
the information itself to a new place (\e moving it). The
288
drag and drop model has an additional complication for the programmer:
289
The program doesn't know whether the user wants to cut or copy the
290
information until the operation is complete. This often makes no
291
difference when dragging information between applications, but within
292
an application it is important to check which drop action was used.
294
We can reimplement the mouseMoveEvent() for a widget, and start a drag
295
and drop operation with a combination of possible drop actions. For
296
example, we may want to ensure that dragging always moves objects in
299
\snippet doc/src/snippets/draganddrop/dragwidget.cpp 7
301
\snippet doc/src/snippets/draganddrop/dragwidget.cpp 8
303
The action returned by the exec() function may default to a
304
\c CopyAction if the information is dropped into another application
305
but, if it is dropped in another widget in the same application, we
306
may obtain a different drop action.
308
The proposed drop actions can be filtered in a widget's dragMoveEvent()
309
function. However, it is possible to accept all proposed actions in
310
the dragEnterEvent() and let the user decide which they want to accept
313
\snippet doc/src/snippets/draganddrop/dragwidget.cpp 0
315
When a drop occurs in the widget, the dropEvent() handler function is
316
called, and we can deal with each possible action in turn. First, we
317
deal with drag and drop operations within the same widget:
319
\snippet doc/src/snippets/draganddrop/dragwidget.cpp 1
321
In this case, we refuse to deal with move operations. Each type of drop
322
action that we accept is checked and dealt with accordingly:
324
\snippet doc/src/snippets/draganddrop/dragwidget.cpp 2
325
\snippet doc/src/snippets/draganddrop/dragwidget.cpp 3
326
\snippet doc/src/snippets/draganddrop/dragwidget.cpp 4
328
\snippet doc/src/snippets/draganddrop/dragwidget.cpp 5
330
Note that we checked for individual drop actions in the above code.
331
As mentioned above in the section on
332
\l{#Overriding Proposed Actions}{Overriding Proposed Actions}, it is
333
sometimes necessary to override the proposed drop action and choose a
334
different one from the selection of possible drop actions.
335
To do this, you need to check for the presence of each action in the value
336
supplied by the event's \l{QDropEvent::}{possibleActions()}, set the drop
337
action with \l{QDropEvent::}{setDropAction()}, and call
338
\l{QEvent::}{accept()}.
340
\section1 Drop Rectangles
342
The widget's dragMoveEvent() can be used to restrict drops to certain parts
343
of the widget by only accepting the proposed drop actions when the cursor
344
is within those areas. For example, the following code accepts any proposed
345
drop actions when the cursor is over a child widget (\c dropFrame):
347
\snippet doc/src/snippets/droprectangle/window.cpp 0
349
The dragMoveEvent() can also be used if you need to give visual
350
feedback during a drag and drop operation, to scroll the window, or
351
whatever is appropriate.
353
\section1 The Clipboard
355
Applications can also communicate with each other by putting data on
356
the clipboard. To access this, you need to obtain a QClipboard object
357
from the QApplication object:
359
\snippet examples/widgets/charactermap/mainwindow.cpp 3
361
The QMimeData class is used to represent data that is transferred to and
362
from the clipboard. To put data on the clipboard, you can use the
363
setText(), setImage(), and setPixmap() convenience functions for common
364
data types. These functions are similar to those found in the QMimeData
365
class, except that they also take an additional argument that controls
366
where the data is stored: If \l{QClipboard::Mode}{Clipboard} is
367
specified, the data is placed on the clipboard; if
368
\l{QClipboard::Mode}{Selection} is specified, the data is placed in the
369
mouse selection (on X11 only). By default, data is put on the clipboard.
371
For example, we can copy the contents of a QLineEdit to the clipboard
372
with the following code:
374
\snippet examples/widgets/charactermap/mainwindow.cpp 11
376
Data with different MIME types can also be put on the clipboard.
377
Construct a QMimeData object and set data with setData() function in
378
the way described in the previous section; this object can then be
379
put on the clipboard with the
380
\l{QClipboard::setMimeData()}{setMimeData()} function.
382
The QClipboard class can notify the application about changes to the
383
data it contains via its \l{QClipboard::dataChanged()}{dataChanged()}
384
signal. For example, we can monitor the clipboard by connecting this
385
signal to a slot in a widget:
387
\snippet doc/src/snippets/clipboard/clipwindow.cpp 0
389
The slot connected to this signal can read the data on the clipboard
390
using one of the MIME types that can be used to represent it:
392
\snippet doc/src/snippets/clipboard/clipwindow.cpp 1
394
\snippet doc/src/snippets/clipboard/clipwindow.cpp 2
396
The \l{QClipboard::selectionChanged()}{selectionChanged()} signal can
397
be used on X11 to monitor the mouse selection.
402
\o \l{draganddrop/draggableicons}{Draggable Icons}
403
\o \l{draganddrop/draggabletext}{Draggable Text}
404
\o \l{draganddrop/dropsite}{Drop Site}
405
\o \l{draganddrop/fridgemagnets}{Fridge Magnets}
406
\o \l{draganddrop/puzzle}{Drag and Drop Puzzle}
409
\section1 Interoperating with Other Applications
411
On X11, the public \l{http://www.newplanetsoftware.com/xdnd/}{XDND
412
protocol} is used, while on Windows Qt uses the OLE standard, and
413
Qt for Mac OS X uses the Carbon Drag Manager. On X11, XDND uses MIME,
414
so no translation is necessary. The Qt API is the same regardless of
415
the platform. On Windows, MIME-aware applications can communicate by
416
using clipboard format names that are MIME types. Already some
417
Windows applications use MIME naming conventions for their
418
clipboard formats. Internally, Qt uses QWindowsMime and
419
QMacPasteboardMime for translating proprietary clipboard formats
420
to and from MIME types.
422
On X11, Qt also supports drops via the Motif Drag & Drop Protocol. The
423
implementation incorporates some code that was originally written by
424
Daniel Dardailler, and adapted for Qt by Matt Koss <koss@napri.sk>
425
and Nokia. Here is the original copyright notice:
428
Copyright 1996 Daniel Dardailler.
430
Permission to use, copy, modify, distribute, and sell this software
431
for any purpose is hereby granted without fee, provided that the above
432
copyright notice appear in all copies and that both that copyright
433
notice and this permission notice appear in supporting documentation,
434
and that the name of Daniel Dardailler not be used in advertising or
435
publicity pertaining to distribution of the software without specific,
436
written prior permission. Daniel Dardailler makes no representations
437
about the suitability of this software for any purpose. It is
438
provided "as is" without express or implied warranty.
440
Modifications Copyright 1999 Matt Koss, under the same license as
443
\omit NOTE: The copyright notice is from qmotifdnd_x11.cpp. \endomit
445
Note: The Motif Drag \& Drop Protocol only allows receivers to
446
request data in response to a QDropEvent. If you attempt to
447
request data in response to e.g. a QDragMoveEvent, an empty
448
QByteArray is returned.