Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qdrag.cpp
Go to the documentation of this file.
1
// Copyright (C) 2016 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
// Qt-Security score:significant reason:default
4
5
#
include
<
qdrag
.
h
>
6
#
include
"private/qguiapplication_p.h"
7
#
include
"qpa/qplatformintegration.h"
8
#
include
"qpa/qplatformdrag.h"
9
#
include
<
qpixmap
.
h
>
10
#
include
<
qpoint
.
h
>
11
#
include
"qdnd_p.h"
12
13
#
include
<
QtCore
/
qpointer
.
h
>
14
15
QT_BEGIN_NAMESPACE
16
17
/*!
18
\class QDrag
19
\inmodule QtGui
20
\ingroup draganddrop
21
\brief The QDrag class provides support for MIME-based drag and drop data
22
transfer.
23
24
Drag and drop is an intuitive way for users to copy or move data around in an
25
application, and is used in many desktop environments as a mechanism for copying
26
data between applications. Drag and drop support in Qt is centered around the
27
QDrag class that handles most of the details of a drag and drop operation.
28
29
The data to be transferred by the drag and drop operation is contained in a
30
QMimeData object. This is specified with the setMimeData() function in the
31
following way:
32
33
\snippet dragging/mainwindow.cpp 1
34
35
Note that setMimeData() assigns ownership of the QMimeData object to the
36
QDrag object. The QDrag must be constructed on the heap with a parent QObject
37
to ensure that Qt can clean up after the drag and drop operation has been
38
completed.
39
40
A pixmap can be used to represent the data while the drag is in
41
progress, and will move with the cursor to the drop target. This
42
pixmap typically shows an icon that represents the MIME type of
43
the data being transferred, but any pixmap can be set with
44
setPixmap(). The cursor's hot spot can be given a position
45
relative to the top-left corner of the pixmap with the
46
setHotSpot() function. The following code positions the pixmap so
47
that the cursor's hot spot points to the center of its bottom
48
edge:
49
50
\snippet separations/finalwidget.cpp 2
51
52
\note On X11, the pixmap may not be able to keep up with the mouse
53
movements if the hot spot causes the pixmap to be displayed
54
directly under the cursor.
55
56
The source and target widgets can be found with source() and target().
57
These functions are often used to determine whether drag and drop operations
58
started and finished at the same widget, so that special behavior can be
59
implemented.
60
61
QDrag only deals with the drag and drop operation itself. It is up to the
62
developer to decide when a drag operation begins, and how a QDrag object should
63
be constructed and used. For a given widget, it is often necessary to
64
reimplement \l{QWidget::mousePressEvent()}{mousePressEvent()} to determine
65
whether the user has pressed a mouse button, and reimplement
66
\l{QWidget::mouseMoveEvent()}{mouseMoveEvent()} to check whether a QDrag is
67
required.
68
69
\sa {Drag and Drop}, QClipboard, QMimeData, {Draggable Icons Example},
70
{Draggable Text Example}, {Drop Site Example}
71
*/
72
73
/*!
74
Constructs a new drag object for the widget specified by \a dragSource.
75
*/
76
QDrag::QDrag(QObject *dragSource)
77
: QObject(*
new
QDragPrivate, dragSource)
78
{
79
Q_D(QDrag);
80
d->source = dragSource;
81
d->target =
nullptr
;
82
d->data =
nullptr
;
83
d->hotspot = QPoint(-10, -10);
84
d->executed_action = Qt::IgnoreAction;
85
d->supported_actions = Qt::IgnoreAction;
86
d->default_action = Qt::IgnoreAction;
87
}
88
89
/*!
90
Destroys the drag object.
91
*/
92
QDrag::~QDrag()
93
{
94
Q_D(QDrag);
95
96
// As a QObject child of the dragSource, QDrag can be destroyed while
97
// exec() is still blocked in the platform's nested event loop.
98
// End the drag while still in existence, to avoid use-after-free later on.
99
if
(QDragManager::m_instance && QDragManager::m_instance->object() ==
this
)
100
cancel();
101
delete
d->data;
102
}
103
104
/*!
105
Sets the data to be sent to the given MIME \a data. Ownership of the data is
106
transferred to the QDrag object.
107
*/
108
void
QDrag::setMimeData(QMimeData *data)
109
{
110
Q_D(QDrag);
111
if
(d->data == data)
112
return
;
113
if
(d->data !=
nullptr
)
114
delete
d->data;
115
d->data = data;
116
}
117
118
/*!
119
Returns the MIME data that is encapsulated by the drag object.
120
*/
121
QMimeData *QDrag::mimeData()
const
122
{
123
Q_D(
const
QDrag);
124
return
d->data;
125
}
126
127
/*!
128
Sets \a pixmap as the pixmap used to represent the data in a drag
129
and drop operation. You can only set a pixmap before the drag is
130
started.
131
*/
132
void
QDrag::setPixmap(
const
QPixmap &pixmap)
133
{
134
Q_D(QDrag);
135
d->pixmap = pixmap;
136
}
137
138
/*!
139
Returns the pixmap used to represent the data in a drag and drop operation.
140
*/
141
QPixmap QDrag::pixmap()
const
142
{
143
Q_D(
const
QDrag);
144
return
d->pixmap;
145
}
146
147
/*!
148
Sets the position of the hot spot relative to the top-left corner of the
149
pixmap used to the point specified by \a hotspot.
150
151
\b{Note:} on X11, the pixmap may not be able to keep up with the mouse
152
movements if the hot spot causes the pixmap to be displayed
153
directly under the cursor.
154
*/
155
void
QDrag::setHotSpot(
const
QPoint& hotspot)
156
{
157
Q_D(QDrag);
158
d->hotspot = hotspot;
159
}
160
161
/*!
162
Returns the position of the hot spot relative to the top-left corner of the
163
cursor.
164
*/
165
QPoint QDrag::hotSpot()
const
166
{
167
Q_D(
const
QDrag);
168
return
d->hotspot;
169
}
170
171
/*!
172
Returns the source of the drag object. This is the widget where the drag
173
and drop operation originated.
174
*/
175
QObject *QDrag::source()
const
176
{
177
Q_D(
const
QDrag);
178
return
d->source;
179
}
180
181
/*!
182
Returns the target of the drag and drop operation. This is the widget where
183
the drag object was dropped.
184
*/
185
QObject *QDrag::target()
const
186
{
187
Q_D(
const
QDrag);
188
return
d->target;
189
}
190
191
/*!
192
\since 4.3
193
194
Starts the drag and drop operation and returns a value indicating the requested
195
drop action when it is completed. The drop actions that the user can choose
196
from are specified in \a supportedActions. The default proposed action will be selected
197
among the allowed actions in the following order: Move, Copy and Link.
198
199
\b{Note:} On Linux and \macos, the drag and drop operation
200
can take some time, but this function does not block the event
201
loop. Other events are still delivered to the application while
202
the operation is performed. On Windows, the Qt event loop is
203
blocked during the operation.
204
205
\sa cancel()
206
*/
207
208
Qt::DropAction QDrag::exec(Qt::DropActions supportedActions)
209
{
210
return
exec(supportedActions, Qt::IgnoreAction);
211
}
212
213
/*!
214
\since 4.3
215
216
Starts the drag and drop operation and returns a value indicating the requested
217
drop action when it is completed. The drop actions that the user can choose
218
from are specified in \a supportedActions.
219
220
The \a defaultDropAction determines which action will be proposed when the user performs a
221
drag without using modifier keys.
222
223
\b{Note:} On Linux and \macos, the drag and drop operation
224
can take some time, but this function does not block the event
225
loop. Other events are still delivered to the application while
226
the operation is performed. On Windows, the Qt event loop is
227
blocked during the operation. However, QDrag::exec() on
228
Windows causes processEvents() to be called frequently to keep the GUI responsive.
229
If any loops or operations are called while a drag operation is active, it will block the drag operation.
230
*/
231
232
Qt::DropAction QDrag::exec(Qt::DropActions supportedActions, Qt::DropAction defaultDropAction)
233
{
234
Q_D(QDrag);
235
if
(!d->data) {
236
qWarning(
"QDrag: No mimedata set before starting the drag"
);
237
return
d->executed_action;
238
}
239
Qt::DropAction transformedDefaultDropAction = Qt::IgnoreAction;
240
241
if
(defaultDropAction == Qt::IgnoreAction) {
242
if
(supportedActions & Qt::MoveAction) {
243
transformedDefaultDropAction = Qt::MoveAction;
244
}
else
if
(supportedActions & Qt::CopyAction) {
245
transformedDefaultDropAction = Qt::CopyAction;
246
}
else
if
(supportedActions & Qt::LinkAction) {
247
transformedDefaultDropAction = Qt::LinkAction;
248
}
249
}
else
{
250
transformedDefaultDropAction = defaultDropAction;
251
}
252
d->supported_actions = supportedActions;
253
d->default_action = transformedDefaultDropAction;
254
QPointer<QDrag> self =
this
;
255
auto
executed_action = QDragManager::self()->drag(self.data());
256
if
(self.isNull())
257
return
Qt::IgnoreAction;
258
d->executed_action = executed_action;
259
return
d->executed_action;
260
}
261
262
/*!
263
Sets the drag \a cursor for the \a action. This allows you
264
to override the default native cursors. To revert to using the
265
native cursor for \a action pass in a null QPixmap as \a cursor.
266
267
Note: setting the drag cursor for IgnoreAction may not work on
268
all platforms. X11 and macOS has been tested to work. Windows
269
does not support it.
270
*/
271
void
QDrag::setDragCursor(
const
QPixmap &cursor, Qt::DropAction action)
272
{
273
Q_D(QDrag);
274
if
(cursor.isNull())
275
d->customCursors.remove(action);
276
else
277
d->customCursors[action] = cursor;
278
}
279
280
/*!
281
Returns the drag cursor for the \a action.
282
283
\since 5.0
284
*/
285
286
QPixmap QDrag::dragCursor(Qt::DropAction action)
const
287
{
288
typedef
QMap<Qt::DropAction, QPixmap>::const_iterator Iterator;
289
290
Q_D(
const
QDrag);
291
const
Iterator it = d->customCursors.constFind(action);
292
if
(it != d->customCursors.constEnd())
293
return
it.value();
294
295
Qt::CursorShape shape = Qt::ForbiddenCursor;
296
switch
(action) {
297
case
Qt::MoveAction:
298
shape = Qt::DragMoveCursor;
299
break
;
300
case
Qt::CopyAction:
301
shape = Qt::DragCopyCursor;
302
break
;
303
case
Qt::LinkAction:
304
shape = Qt::DragLinkCursor;
305
break
;
306
default
:
307
shape = Qt::ForbiddenCursor;
308
}
309
return
QGuiApplicationPrivate::instance()->getPixmapCursor(shape);
310
}
311
312
/*!
313
Returns the set of possible drop actions for this drag operation.
314
315
\sa exec(), defaultAction()
316
*/
317
Qt::DropActions QDrag::supportedActions()
const
318
{
319
Q_D(
const
QDrag);
320
return
d->supported_actions;
321
}
322
323
324
/*!
325
Returns the default proposed drop action for this drag operation.
326
327
\sa exec(), supportedActions()
328
*/
329
Qt::DropAction QDrag::defaultAction()
const
330
{
331
Q_D(
const
QDrag);
332
return
d->default_action;
333
}
334
335
/*!
336
Cancels a drag operation initiated by Qt.
337
338
\note This is currently implemented on Windows and X11.
339
340
\since 5.7
341
\sa exec()
342
*/
343
void
QDrag::cancel()
344
{
345
if
(QPlatformDrag *platformDrag = QGuiApplicationPrivate::platformIntegration()->drag())
346
platformDrag->cancelDrag();
347
}
348
349
/*!
350
\fn void QDrag::actionChanged(Qt::DropAction action)
351
352
This signal is emitted when the \a action associated with the
353
drag changes.
354
355
\sa targetChanged()
356
*/
357
358
/*!
359
\fn void QDrag::targetChanged(QObject *newTarget)
360
361
This signal is emitted when the target of the drag and drop
362
operation changes, with \a newTarget the new target.
363
364
\sa target(), actionChanged()
365
*/
366
367
QT_END_NAMESPACE
368
369
#
include
"moc_qdrag.cpp"
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qsequentialanimationgroup.cpp:47
qtbase
src
gui
kernel
qdrag.cpp
Generated on
for Qt by
1.18.0