Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qsignalmapper.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 "qglobal.h"
6
8#include "qhash.h"
9#include "qobject_p.h"
10
12
39
40/*!
41 \class QSignalMapper
42 \inmodule QtCore
43 \brief The QSignalMapper class bundles signals from identifiable senders.
44
45 \ingroup objectmodel
46
47
48 This class collects a set of parameterless signals, and re-emits
49 them with integer, string or widget parameters corresponding to
50 the object that sent the signal. Note that in most cases you can
51 use lambdas for passing custom parameters to slots. This is less
52 costly and will simplify the code.
53
54 The class supports the mapping of particular strings, integers,
55 objects and widgets with particular objects using setMapping().
56 The objects' signals can then be connected to the map() slot which
57 will emit a signal (it could be mappedInt(), mappedString()
58 and mappedObject()) with a value associated with
59 the original signalling object. Mappings can be removed later using
60 removeMappings().
61
62 Example: Suppose we want to create a custom widget that contains
63 a group of buttons (like a tool palette). One approach is to
64 connect each button's \c clicked() signal to its own custom slot;
65 but in this example we want to connect all the buttons to a
66 single slot and parameterize the slot by the button that was
67 clicked.
68
69 Here's the definition of a simple custom widget that has a single
70 signal, \c clicked(), which is emitted with the text of the button
71 that was clicked:
72
73 \snippet qsignalmapper/buttonwidget.h 0
74 \snippet qsignalmapper/buttonwidget.h 1
75
76 The only function that we need to implement is the constructor:
77
78 \snippet qsignalmapper/buttonwidget.cpp OpenCtor
79 \snippet qsignalmapper/buttonwidget.cpp OldNotation
80 \snippet qsignalmapper/buttonwidget.cpp CloseBrackets
81
82 A list of texts is passed to the constructor. A signal mapper is
83 constructed and for each text in the list a QPushButton is
84 created. We connect each button's \c clicked() signal to the
85 signal mapper's map() slot, and create a mapping in the signal
86 mapper from each button to the button's text. Finally we connect
87 the signal mapper's mappedString() signal to the custom widget's
88 \c clicked() signal. When the user clicks a button, the custom
89 widget will emit a single \c clicked() signal whose argument is
90 the text of the button the user clicked.
91
92 This class was mostly useful before lambda functions could be used as
93 slots. The example above can be rewritten simpler without QSignalMapper
94 by connecting to a lambda function.
95
96 \snippet qsignalmapper/buttonwidget.cpp OpenCtor
97 \snippet qsignalmapper/buttonwidget.cpp ModernNotation
98 \snippet qsignalmapper/buttonwidget.cpp CloseBrackets
99
100 \sa QObject, QButtonGroup, QActionGroup
101*/
102
103/*!
104 Constructs a QSignalMapper with parent \a parent.
105*/
106QSignalMapper::QSignalMapper(QObject* parent)
107 : QObject(*new QSignalMapperPrivate, parent)
108{
109}
110
111/*!
112 Destroys the QSignalMapper.
113*/
114QSignalMapper::~QSignalMapper()
115{
116}
117
118/*!
119 Adds a mapping so that when map() is signalled from the given \a
120 sender, the signal mappedInt(\a id) is emitted.
121
122 There may be at most one integer ID for each sender.
123
124 \sa mapping()
125*/
126void QSignalMapper::setMapping(QObject *sender, int id)
127{
128 Q_D(QSignalMapper);
129 d->intHash.insert(sender, id);
130 connect(sender, &QObject::destroyed, this, &QSignalMapper::removeMappings);
131}
132
133/*!
134 Adds a mapping so that when map() is signalled from the \a sender,
135 the signal mappedString(\a text ) is emitted.
136
137 There may be at most one text for each sender.
138*/
139void QSignalMapper::setMapping(QObject *sender, const QString &text)
140{
141 Q_D(QSignalMapper);
142 d->stringHash.insert(sender, text);
143 connect(sender, &QObject::destroyed, this, &QSignalMapper::removeMappings);
144}
145
146/*!
147 Adds a mapping so that when map() is signalled from the \a sender,
148 the signal mappedObject(\a object ) is emitted.
149
150 There may be at most one object for each sender.
151*/
152void QSignalMapper::setMapping(QObject *sender, QObject *object)
153{
154 Q_D(QSignalMapper);
155 d->objectHash.insert(sender, object);
156 connect(sender, &QObject::destroyed, this, &QSignalMapper::removeMappings);
157}
158
159/*!
160 Returns the sender QObject that is associated with the \a id.
161
162 \sa setMapping()
163*/
164QObject *QSignalMapper::mapping(int id) const
165{
166 Q_D(const QSignalMapper);
167 return d->intHash.key(id);
168}
169
170/*!
171 \overload mapping()
172*/
173QObject *QSignalMapper::mapping(const QString &id) const
174{
175 Q_D(const QSignalMapper);
176 return d->stringHash.key(id);
177}
178
179/*!
180 \overload mapping()
181
182 Returns the sender QObject that is associated with the \a object.
183*/
184QObject *QSignalMapper::mapping(QObject *object) const
185{
186 Q_D(const QSignalMapper);
187 return d->objectHash.key(object);
188}
189
190/*!
191 Removes all mappings for \a sender.
192
193 This is done automatically when mapped objects are destroyed.
194
195 \note This does not disconnect any signals. If \a sender is not destroyed
196 then this will need to be done explicitly if required.
197*/
198void QSignalMapper::removeMappings(QObject *sender)
199{
200 Q_D(QSignalMapper);
201
202 d->intHash.remove(sender);
203 d->stringHash.remove(sender);
204 d->objectHash.remove(sender);
205}
206
207/*!
208 This slot emits signals based on which object sends signals to it.
209*/
210void QSignalMapper::map() { map(sender()); }
211
212/*!
213 This slot emits signals based on the \a sender object.
214*/
215void QSignalMapper::map(QObject *sender)
216{
217 d_func()->emitMappedValues(sender);
218}
219
220/*!
221 \fn void QSignalMapper::mappedInt(int i)
222 \since 5.15
223
224 This signal is emitted when map() is signalled from an object that
225 has an integer mapping set. The object's mapped integer is passed
226 in \a i.
227
228 \sa setMapping()
229*/
230
231/*!
232 \fn void QSignalMapper::mappedString(const QString &text)
233 \since 5.15
234
235 This signal is emitted when map() is signalled from an object that
236 has a string mapping set. The object's mapped string is passed in
237 \a text.
238
239 \sa setMapping()
240*/
241
242/*!
243 \fn void QSignalMapper::mappedObject(QObject *object)
244 \since 5.15
245
246 This signal is emitted when map() is signalled from an object that
247 has an object mapping set. The object provided by the map is passed in
248 \a object.
249
250 \sa setMapping()
251*/
252
253QT_END_NAMESPACE
254
255#include "moc_qsignalmapper.cpp"
QHash< QObject *, QObject * > objectHash
QHash< QObject *, QString > stringHash
Combined button and popup list for selecting options.