source: trunk/doc/src/frameworks-technologies/dnd.qdoc@ 568

Last change on this file since 568 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

  • Property svn:eol-style set to native
File size: 20.1 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the documentation of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
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.
23**
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.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42/*!
43 \group draganddrop
44 \title Drag And Drop Classes
45
46 \brief Classes dealing with drag and drop and mime type encoding and decoding.
47*/
48
49/*!
50 \page dnd.html
51 \title Drag and Drop
52 \brief An overview of the drag and drop system provided by Qt.
53
54 \ingroup frameworks-technologies
55
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
60 mechanism.
61
62 \tableofcontents
63
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
69 Framework} documents.
70
71 \section1 Drag and Drop Classes
72
73 These classes deal with drag and drop and the necessary mime type
74 encoding and decoding.
75
76 \annotatedlist draganddrop
77
78 \section1 Configuration
79
80 The QApplication object provides some properties that are related
81 to drag and drop operations:
82
83 \list
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
91 object.
92 \endlist
93
94 These quantities provide sensible default values for you to use if you
95 provide drag and drop support in your widgets.
96
97 \section1 Dragging
98
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
105 and drop operation:
106
107 \snippet doc/src/snippets/dragging/mainwindow.cpp 0
108 \dots 8
109 \snippet doc/src/snippets/dragging/mainwindow.cpp 2
110
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
115 below.
116
117 Note that the exec() function does not block the main event loop.
118
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:
123
124 \snippet doc/src/snippets/draganddrop/dragwidget.cpp 6
125
126 Later, in \l{QWidget::mouseMoveEvent()}{mouseMoveEvent()}, we can determine
127 whether a drag should begin, and construct a drag object to handle the
128 operation:
129
130 \snippet doc/src/snippets/draganddrop/dragwidget.cpp 7
131 \dots
132 \snippet doc/src/snippets/draganddrop/dragwidget.cpp 8
133
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.
138
139 \section1 Dropping
140
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.
145
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
148 handlers:
149
150 \snippet doc/src/snippets/dropevents/window.cpp 0
151 \dots
152 \snippet doc/src/snippets/dropevents/window.cpp 1
153 \snippet doc/src/snippets/dropevents/window.cpp 2
154
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()}.
161
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:
165
166 \snippet doc/src/snippets/dropevents/window.cpp 3
167
168 The \l{QWidget::dropEvent()}{dropEvent()} is used to unpack dropped data
169 and handle it in way that is suitable for your application.
170
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:
174
175 \snippet doc/src/snippets/dropevents/window.cpp 4
176
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.
184
185 \section2 Overriding Proposed Actions
186
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
192 proposed action.
193
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.
199
200 \section2 Subclassing Complex Widgets
201
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.
209
210 \section1 Drag and Drop Actions
211
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.
223
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.
230
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
233 to files or objects.
234
235 \section1 Adding New Drag and Drop Types
236
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.
249
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})
254 provides a
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.
260
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:
266
267 \snippet doc/src/snippets/separations/finalwidget.cpp 0
268
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:
272
273 \snippet doc/src/snippets/separations/finalwidget.cpp 1
274
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.
277
278 Note that custom datatypes used in item views must be declared as
279 \l{QMetaObject}{meta objects} and that stream operators for them
280 must be implemented.
281
282 \section1 Drop Actions
283
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.
293
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
297 the widget:
298
299 \snippet doc/src/snippets/draganddrop/dragwidget.cpp 7
300 \dots
301 \snippet doc/src/snippets/draganddrop/dragwidget.cpp 8
302
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.
307
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
311 later:
312
313 \snippet doc/src/snippets/draganddrop/dragwidget.cpp 0
314
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:
318
319 \snippet doc/src/snippets/draganddrop/dragwidget.cpp 1
320
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:
323
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
327 \dots
328 \snippet doc/src/snippets/draganddrop/dragwidget.cpp 5
329
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()}.
339
340 \section1 Drop Rectangles
341
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):
346
347 \snippet doc/src/snippets/droprectangle/window.cpp 0
348
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.
352
353 \section1 The Clipboard
354
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:
358
359 \snippet examples/widgets/charactermap/mainwindow.cpp 3
360
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.
370
371 For example, we can copy the contents of a QLineEdit to the clipboard
372 with the following code:
373
374 \snippet examples/widgets/charactermap/mainwindow.cpp 11
375
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.
381
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:
386
387 \snippet doc/src/snippets/clipboard/clipwindow.cpp 0
388
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:
391
392 \snippet doc/src/snippets/clipboard/clipwindow.cpp 1
393 \dots
394 \snippet doc/src/snippets/clipboard/clipwindow.cpp 2
395
396 The \l{QClipboard::selectionChanged()}{selectionChanged()} signal can
397 be used on X11 to monitor the mouse selection.
398
399 \section1 Examples
400
401 \list
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}
407 \endlist
408
409 \section1 Interoperating with Other Applications
410
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.
421
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 <[email protected]>
425 and Nokia. Here is the original copyright notice:
426
427 \legalese
428 Copyright 1996 Daniel Dardailler.
429 Copyright 1999 Matt Koss
430
431 Permission to use, copy, modify, distribute, and sell this software
432 for any purpose is hereby granted without fee, provided that the above
433 copyright notice appear in all copies and that both that copyright
434 notice and this permission notice appear in supporting documentation,
435 and that the name of Daniel Dardailler not be used in advertising or
436 publicity pertaining to distribution of the software without specific,
437 written prior permission. Daniel Dardailler makes no representations
438 about the suitability of this software for any purpose. It is
439 provided "as is" without express or implied warranty.
440 \endlegalese
441 \omit NOTE: The original version of this copyright notice can be found
442 in qmotifdnd_x11.cpp. \endomit
443
444 \note The Motif Drag \& Drop Protocol only allows receivers to
445 request data in response to a QDropEvent. If you attempt to
446 request data in response to e.g. a QDragMoveEvent, an empty
447 QByteArray is returned.
448*/
Note: See TracBrowser for help on using the repository browser.