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