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
qshortcut.cpp
Go to the documentation of this file.
1
// Copyright (C) 2019 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
"qshortcut.h"
6
#
include
"qshortcut_p.h"
7
8
#
include
<
qevent
.
h
>
9
#
include
<
qguiapplication
.
h
>
10
#
include
<
qwindow
.
h
>
11
#
include
<
private
/
qguiapplication_p
.
h
>
12
#
include
<
qpa
/
qplatformmenu
.
h
>
13
14
QT_BEGIN_NAMESPACE
15
16
#
define
QAPP_CHECK
(
functionName
)
17
if
(
Q_UNLIKELY
(
!
qApp
)
)
{
18
qWarning
(
"QShortcut: Initialize QGuiApplication before calling '"
functionName
"'."
)
;
19
return
;
20
}
21
22
/*!
23
\class QShortcut
24
\brief The QShortcut class is used to create keyboard shortcuts.
25
26
\ingroup events
27
\inmodule QtGui
28
29
The QShortcut class provides a way of connecting keyboard
30
shortcuts to Qt's \l{signals and slots} mechanism, so that
31
objects can be informed when a shortcut is executed. The shortcut
32
can be set up to contain all the key presses necessary to
33
describe a keyboard shortcut, including the states of modifier
34
keys such as \uicontrol Shift, \uicontrol Ctrl, and \uicontrol Alt.
35
36
\target mnemonic
37
38
In widget applications, certain widgets can use '&' in front of a character.
39
This will automatically create a mnemonic (a shortcut) for that character,
40
e.g. "E&xit" will create the shortcut \uicontrol Alt+X (use '&&'
41
to display an actual ampersand). The widget might consume and perform
42
an action on a given shortcut. On X11 the ampersand will not be
43
shown and the character will be underlined. On Windows, shortcuts
44
are normally not displayed until the user presses the \uicontrol Alt
45
key, but this is a setting the user can change. On Mac, shortcuts
46
are disabled by default. Call \l qt_set_sequence_auto_mnemonic() to
47
enable them. However, because mnemonic shortcuts do not fit in
48
with Aqua's guidelines, Qt will not show the shortcut character
49
underlined.
50
51
For applications that use menus, it may be more convenient to
52
use the convenience functions provided in the QMenu class to
53
assign keyboard shortcuts to menu items as they are created.
54
Alternatively, shortcuts may be associated with other types of
55
actions in the QAction class.
56
57
The simplest way to create a shortcut for a particular widget is
58
to construct the shortcut with a key sequence. For example:
59
60
\snippet code/src_gui_kernel_qshortcut.cpp 0
61
62
When the user types the \l{QKeySequence}{key sequence}
63
for a given shortcut, the shortcut's activated() signal is
64
emitted. (In the case of ambiguity, the activatedAmbiguously()
65
signal is emitted.) A shortcut is "listened for" by Qt's event
66
loop when the shortcut's parent widget is receiving events.
67
68
A shortcut's key sequence can be set with setKey() and retrieved
69
with key(). A shortcut can be enabled or disabled with
70
setEnabled(), and can have "What's This?" help text set with
71
setWhatsThis().
72
73
\sa QShortcutEvent, QKeySequence, QAction
74
*/
75
76
/*!
77
\fn void QShortcut::activated()
78
79
This signal is emitted when the user types the shortcut's key
80
sequence.
81
82
\sa activatedAmbiguously()
83
*/
84
85
/*!
86
\fn void QShortcut::activatedAmbiguously()
87
88
When a key sequence is being typed at the keyboard, it is said to
89
be ambiguous as long as it matches the start of more than one
90
shortcut.
91
92
When a shortcut's key sequence is completed,
93
activatedAmbiguously() is emitted if the key sequence is still
94
ambiguous (i.e., it is the start of one or more other shortcuts).
95
The activated() signal is not emitted in this case.
96
97
\sa activated()
98
*/
99
100
bool
QShortcutPrivate::simpleContextMatcher(QObject *object, Qt::ShortcutContext context)
101
{
102
auto
guiShortcut = qobject_cast<QShortcut *>(object);
103
if
(QGuiApplication::applicationState() != Qt::ApplicationActive || guiShortcut ==
nullptr
)
104
return
false
;
105
if
(context == Qt::ApplicationShortcut)
106
return
true
;
107
auto
focusWindow = QGuiApplication::focusWindow();
108
if
(!focusWindow)
109
return
false
;
110
auto
window = qobject_cast<
const
QWindow *>(guiShortcut->parent());
111
if
(!window)
112
return
false
;
113
if
(focusWindow == window && focusWindow->isTopLevel())
114
return
context == Qt::WindowShortcut || context == Qt::WidgetWithChildrenShortcut;
115
return
focusWindow->isAncestorOf(window, QWindow::ExcludeTransients);
116
}
117
118
QShortcutMap::ContextMatcher QShortcutPrivate::contextMatcher()
const
119
{
120
return
simpleContextMatcher;
121
}
122
123
void
QShortcutPrivate::redoGrab(QShortcutMap &map)
124
{
125
Q_Q(QShortcut);
126
if
(Q_UNLIKELY(!parent)) {
127
qWarning(
"QShortcut: No window parent defined"
);
128
return
;
129
}
130
131
for
(
int
id : std::as_const(sc_ids))
132
map.removeShortcut(id, q);
133
134
sc_ids.clear();
135
if
(sc_sequences.isEmpty())
136
return
;
137
sc_ids.reserve(sc_sequences.size());
138
for
(
const
auto
&keySequence : std::as_const(sc_sequences)) {
139
if
(keySequence.isEmpty())
140
continue
;
141
int
id = map.addShortcut(q, keySequence, sc_context, contextMatcher());
142
sc_ids.append(id);
143
if
(!sc_enabled)
144
map.setShortcutEnabled(
false
, id, q);
145
if
(!sc_autorepeat)
146
map.setShortcutAutoRepeat(
false
, id, q);
147
}
148
}
149
150
QShortcutPrivate *QGuiApplicationPrivate::createShortcutPrivate()
const
151
{
152
return
new
QShortcutPrivate;
153
}
154
155
/*!
156
Constructs a QShortcut object for the \a parent, which should be a
157
QWindow or a QWidget.
158
159
Since no shortcut key sequence is specified, the shortcut will not emit any
160
signals.
161
162
\sa setKey()
163
*/
164
QShortcut::QShortcut(QObject *parent)
165
: QObject(*QGuiApplicationPrivate::instance()->createShortcutPrivate(), parent)
166
{
167
Q_ASSERT(parent !=
nullptr
);
168
}
169
170
/*!
171
Constructs a QShortcut object for the \a parent, which should be a
172
QWindow or a QWidget.
173
174
The shortcut operates on its parent, listening for \l{QShortcutEvent}s that
175
match the \a key sequence. Depending on the ambiguity of the event, the
176
shortcut will call the \a member function, or the \a ambiguousMember function,
177
if the key press was in the shortcut's \a context.
178
*/
179
QShortcut::QShortcut(
const
QKeySequence &key, QObject *parent,
180
const
char
*member,
const
char
*ambiguousMember,
181
Qt::ShortcutContext context)
182
: QShortcut(parent)
183
{
184
Q_D(QShortcut);
185
d->sc_context = context;
186
if
(!key.isEmpty()) {
187
d->sc_sequences = { key };
188
d->redoGrab(QGuiApplicationPrivate::instance()->shortcutMap);
189
}
190
if
(member)
191
connect(
this
, SIGNAL(activated()), parent, member);
192
if
(ambiguousMember)
193
connect(
this
, SIGNAL(activatedAmbiguously()), parent, ambiguousMember);
194
}
195
196
/*!
197
\since 6.0
198
Constructs a QShortcut object for the \a parent, which should be a
199
QWindow or a QWidget.
200
201
The shortcut operates on its parent, listening for \l{QShortcutEvent}s that
202
match the \a standardKey. Depending on the ambiguity of the event, the
203
shortcut will call the \a member function, or the \a ambiguousMember function,
204
if the key press was in the shortcut's \a context.
205
*/
206
QShortcut::QShortcut(QKeySequence::StandardKey standardKey, QObject *parent,
207
const
char
*member,
const
char
*ambiguousMember,
208
Qt::ShortcutContext context)
209
: QShortcut(parent)
210
{
211
Q_D(QShortcut);
212
d->sc_context = context;
213
d->sc_sequences = QKeySequence::keyBindings(standardKey);
214
d->redoGrab(QGuiApplicationPrivate::instance()->shortcutMap);
215
if
(member)
216
connect(
this
, SIGNAL(activated()), parent, member);
217
if
(ambiguousMember)
218
connect(
this
, SIGNAL(activatedAmbiguously()), parent, ambiguousMember);
219
}
220
221
222
/*!
223
\fn template<typename Functor> QShortcut::QShortcut(const QKeySequence &key, QObject *parent, Functor functor, Qt::ShortcutContext shortcutContext = Qt::WindowShortcut)
224
\since 5.15
225
\overload
226
227
This is a QShortcut convenience constructor which connects the shortcut's
228
\l{QShortcut::activated()}{activated()} signal to the \a functor.
229
*/
230
/*!
231
\fn template<typename Functor> QShortcut::QShortcut(const QKeySequence &key, QObject *parent, const QObject *context, Functor functor, Qt::ShortcutContext shortcutContext = Qt::WindowShortcut)
232
\since 5.15
233
\overload
234
235
This is a QShortcut convenience constructor which connects the shortcut's
236
\l{QShortcut::activated()}{activated()} signal to the \a functor.
237
238
The \a functor can be a pointer to a member function of the \a context object.
239
240
If the \a context object is destroyed, the \a functor will not be called.
241
*/
242
/*!
243
\fn template<typename Functor, typename FunctorAmbiguous> QShortcut::QShortcut(const QKeySequence &key, QObject *parent, const QObject *context, Functor functor, FunctorAmbiguous functorAmbiguous, Qt::ShortcutContext shortcutContext = Qt::WindowShortcut)
244
\since 5.15
245
\overload
246
247
This is a QShortcut convenience constructor which connects the shortcut's
248
\l{QShortcut::activated()}{activated()} signal to the \a functor and
249
\l{QShortcut::activatedAmbiguously()}{activatedAmbiguously()}
250
signal to the \a functorAmbiguous.
251
252
The \a functor and \a functorAmbiguous can be a pointer to a member
253
function of the \a context object.
254
255
If the \a context object is destroyed, the \a functor and
256
\a functorAmbiguous will not be called.
257
*/
258
/*!
259
\fn template<typename Functor, typename FunctorAmbiguous> QShortcut::QShortcut(const QKeySequence &key, QObject *parent, const QObject *context1, Functor functor, const QObject *context2, FunctorAmbiguous functorAmbiguous, Qt::ShortcutContext shortcutContext = Qt::WindowShortcut)
260
\since 5.15
261
\overload
262
263
This is a QShortcut convenience constructor which connects the shortcut's
264
\l{QShortcut::activated()}{activated()} signal to the \a functor and
265
\l{QShortcut::activatedAmbiguously()}{activatedAmbiguously()}
266
signal to the \a functorAmbiguous.
267
268
The \a functor can be a pointer to a member function of the
269
\a context1 object.
270
The \a functorAmbiguous can be a pointer to a member function of the
271
\a context2 object.
272
273
If the \a context1 object is destroyed, the \a functor will not be called.
274
If the \a context2 object is destroyed, the \a functorAmbiguous
275
will not be called.
276
*/
277
278
/*!
279
\fn template<typename Functor> QShortcut::QShortcut(QKeySequence::StandardKey key, QObject *parent, Functor functor, Qt::ShortcutContext shortcutContext = Qt::WindowShortcut)
280
\since 6.0
281
\overload
282
283
This is a QShortcut convenience constructor which connects the shortcut's
284
\l{QShortcut::activated()}{activated()} signal to the \a functor.
285
*/
286
/*!
287
\fn template<typename Functor> QShortcut::QShortcut(QKeySequence::StandardKey key, QObject *parent, const QObject *context, Functor functor, Qt::ShortcutContext shortcutContext = Qt::WindowShortcut)
288
\since 6.0
289
\overload
290
291
This is a QShortcut convenience constructor which connects the shortcut's
292
\l{QShortcut::activated()}{activated()} signal to the \a functor.
293
294
The \a functor can be a pointer to a member function of the \a context object.
295
296
If the \a context object is destroyed, the \a functor will not be called.
297
*/
298
/*!
299
\fn template<typename Functor, typename FunctorAmbiguous> QShortcut::QShortcut(QKeySequence::StandardKey key, QObject *parent, const QObject *context, Functor functor, FunctorAmbiguous functorAmbiguous, Qt::ShortcutContext shortcutContext = Qt::WindowShortcut)
300
\since 6.0
301
\overload
302
303
This is a QShortcut convenience constructor which connects the shortcut's
304
\l{QShortcut::activated()}{activated()} signal to the \a functor and
305
\l{QShortcut::activatedAmbiguously()}{activatedAmbiguously()}
306
signal to the \a functorAmbiguous.
307
308
The \a functor and \a functorAmbiguous can be a pointer to a member
309
function of the \a context object.
310
311
If the \a context object is destroyed, the \a functor and
312
\a functorAmbiguous will not be called.
313
*/
314
/*!
315
\fn template<typename Functor, typename FunctorAmbiguous> QShortcut::QShortcut(QKeySequence::StandardKey key, QObject *parent, const QObject *context1, Functor functor, const QObject *context2, FunctorAmbiguous functorAmbiguous, Qt::ShortcutContext shortcutContext = Qt::WindowShortcut)
316
\since 6.0
317
\overload
318
319
This is a QShortcut convenience constructor which connects the shortcut's
320
\l{QShortcut::activated()}{activated()} signal to the \a functor and
321
\l{QShortcut::activatedAmbiguously()}{activatedAmbiguously()}
322
signal to the \a functorAmbiguous.
323
324
The \a functor can be a pointer to a member function of the
325
\a context1 object.
326
The \a functorAmbiguous can be a pointer to a member function of the
327
\a context2 object.
328
329
If the \a context1 object is destroyed, the \a functor will not be called.
330
If the \a context2 object is destroyed, the \a functorAmbiguous
331
will not be called.
332
*/
333
334
/*!
335
Destroys the shortcut.
336
*/
337
QShortcut::~QShortcut()
338
{
339
Q_D(QShortcut);
340
if
(
qApp
) {
341
for
(
int
id : std::as_const(d->sc_ids))
342
QGuiApplicationPrivate::instance()->shortcutMap.removeShortcut(id,
this
);
343
}
344
}
345
346
/*!
347
\property QShortcut::key
348
\brief the shortcut's primary key sequence
349
350
This is a key sequence with an optional combination of Shift, Ctrl,
351
and Alt. The key sequence may be supplied in a number of ways:
352
353
\snippet code/src_gui_kernel_qshortcut.cpp 1
354
355
By default, this property contains an empty key sequence.
356
*/
357
void
QShortcut::setKey(
const
QKeySequence &key)
358
{
359
if
(key.isEmpty())
360
setKeys({});
361
else
362
setKeys({ key });
363
}
364
365
QKeySequence QShortcut::key()
const
366
{
367
Q_D(
const
QShortcut);
368
if
(d->sc_sequences.isEmpty())
369
return
QKeySequence();
370
return
d->sc_sequences.first();
371
}
372
373
/*!
374
Sets \a keys as the list of key sequences that trigger the
375
shortcut.
376
377
\since 6.0
378
379
\sa key, keys()
380
*/
381
void
QShortcut::setKeys(
const
QList<QKeySequence> &keys)
382
{
383
Q_D(QShortcut);
384
if
(d->sc_sequences == keys)
385
return
;
386
QAPP_CHECK
(
"setKeys"
);
387
d->sc_sequences = keys;
388
d->redoGrab(QGuiApplicationPrivate::instance()->shortcutMap);
389
}
390
391
/*!
392
Sets the triggers to those matching the standard key \a key.
393
394
\since 6.0
395
396
\sa key, keys()
397
*/
398
void
QShortcut::setKeys(QKeySequence::StandardKey key)
399
{
400
setKeys(QKeySequence::keyBindings(key));
401
}
402
403
/*!
404
Returns the list of key sequences which trigger this
405
shortcut.
406
407
\since 6.0
408
\sa key, setKeys()
409
*/
410
QList<QKeySequence> QShortcut::keys()
const
411
{
412
Q_D(
const
QShortcut);
413
return
d->sc_sequences;
414
}
415
416
/*!
417
\property QShortcut::enabled
418
\brief whether the shortcut is enabled
419
420
An enabled shortcut emits the activated() or activatedAmbiguously()
421
signal when a QShortcutEvent occurs that matches the shortcut's
422
key() sequence.
423
424
If the application is in \c WhatsThis mode the shortcut will not emit
425
the signals, but will show the "What's This?" text instead.
426
427
By default, this property is \c true.
428
429
\sa whatsThis
430
*/
431
void
QShortcut::setEnabled(
bool
enable)
432
{
433
Q_D(QShortcut);
434
if
(d->sc_enabled == enable)
435
return
;
436
QAPP_CHECK
(
"setEnabled"
);
437
d->sc_enabled = enable;
438
for
(
int
id : d->sc_ids)
439
QGuiApplicationPrivate::instance()->shortcutMap.setShortcutEnabled(enable, id,
this
);
440
}
441
442
bool
QShortcut::isEnabled()
const
443
{
444
Q_D(
const
QShortcut);
445
return
d->sc_enabled;
446
}
447
448
/*!
449
\property QShortcut::context
450
\brief the context in which the shortcut is valid
451
452
A shortcut's context decides in which circumstances a shortcut is
453
allowed to be triggered. The normal context is Qt::WindowShortcut,
454
which allows the shortcut to trigger if the parent (the widget
455
containing the shortcut) is a subwidget of the active top-level
456
window.
457
458
By default, this property is set to Qt::WindowShortcut.
459
*/
460
void
QShortcut::setContext(Qt::ShortcutContext context)
461
{
462
Q_D(QShortcut);
463
if
(d->sc_context == context)
464
return
;
465
QAPP_CHECK
(
"setContext"
);
466
d->sc_context = context;
467
d->redoGrab(QGuiApplicationPrivate::instance()->shortcutMap);
468
}
469
470
Qt::ShortcutContext QShortcut::context()
const
471
{
472
Q_D(
const
QShortcut);
473
return
d->sc_context;
474
}
475
476
/*!
477
\property QShortcut::autoRepeat
478
\brief whether the shortcut can auto repeat
479
480
If true, the shortcut will auto repeat when the keyboard shortcut
481
combination is held down, provided that keyboard auto repeat is
482
enabled on the system.
483
The default value is true.
484
*/
485
void
QShortcut::setAutoRepeat(
bool
on)
486
{
487
Q_D(QShortcut);
488
if
(d->sc_autorepeat == on)
489
return
;
490
QAPP_CHECK
(
"setAutoRepeat"
);
491
d->sc_autorepeat = on;
492
for
(
int
id : d->sc_ids)
493
QGuiApplicationPrivate::instance()->shortcutMap.setShortcutAutoRepeat(on, id,
this
);
494
}
495
496
bool
QShortcut::autoRepeat()
const
497
{
498
Q_D(
const
QShortcut);
499
return
d->sc_autorepeat;
500
}
501
502
503
/*!
504
Sets the shortcut's "What's This?" help \a text.
505
506
The text will be shown when a widget application is in "What's
507
This?" mode and the user types the shortcut key() sequence.
508
509
To set "What's This?" help on a menu item (with or without a
510
shortcut key), set the help on the item's action.
511
512
By default, the help text is an empty string.
513
514
This function has no effect in applications that don't use
515
widgets.
516
517
\sa QWhatsThis::inWhatsThisMode(), QAction::setWhatsThis()
518
*/
519
void
QShortcut::setWhatsThis(
const
QString &text)
520
{
521
Q_D(QShortcut);
522
d->sc_whatsthis = text;
523
}
524
525
/*!
526
Returns the shortcut's "What's This?" help text.
527
528
\sa setWhatsThis()
529
*/
530
QString QShortcut::whatsThis()
const
531
{
532
Q_D(
const
QShortcut);
533
return
d->sc_whatsthis;
534
}
535
536
#
if
QT_DEPRECATED_SINCE
(
6
,
0
)
537
/*!
538
Returns the primary key binding's ID.
539
540
\deprecated
541
542
\sa QShortcutEvent::shortcutId()
543
*/
544
int
QShortcut::id()
const
545
{
546
Q_D(
const
QShortcut);
547
if
(d->sc_ids.isEmpty())
548
return
0;
549
return
d->sc_ids.first();
550
}
551
#
endif
552
553
/*!
554
\fn QWidget *QShortcut::parentWidget() const
555
556
\deprecated [6.0] Use parent() with qobject_cast() instead.
557
558
Returns the shortcut's parent widget.
559
*/
560
561
/*!
562
\internal
563
*/
564
bool
QShortcut::event(QEvent *e)
565
{
566
Q_D(QShortcut);
567
if
(d->sc_enabled && e->type() == QEvent::Shortcut) {
568
auto
se =
static_cast
<QShortcutEvent *>(e);
569
if
(!d->handleWhatsThis()) {
570
Q_ASSERT_X(d->sc_ids.contains(se->shortcutId()),
"QShortcut::event"
,
"Received shortcut event from wrong shortcut"
);
571
if
(se->isAmbiguous())
572
emit activatedAmbiguously();
573
else
574
emit activated();
575
return
true
;
576
}
577
}
578
return
QObject::event(e);
579
}
580
581
QT_END_NAMESPACE
582
583
#
undef
QAPP_CHECK
584
585
#
include
"moc_qshortcut.cpp"
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qsequentialanimationgroup.cpp:47
QAPP_CHECK
#define QAPP_CHECK(functionName)
Definition
qaction.cpp:19
qApp
#define qApp
Definition
qcoreapplication.h:38
qtbase
src
gui
kernel
qshortcut.cpp
Generated on
for Qt by
1.18.0