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
qquickdialog.cpp
Go to the documentation of this file.
1// Copyright (C) 2017 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
11#include <qpa/qplatformintegration.h>
12#include <private/qguiapplication_p.h>
13
15
16/*!
17 \qmltype Dialog
18 \inherits Popup
19//! \nativetype QQuickDialog
20 \inqmlmodule QtQuick.Controls
21 \ingroup qtquickcontrols-dialogs
22 \ingroup qtquickcontrols-popups
23 \brief Popup dialog with standard buttons and a title, used for short-term interaction with the user.
24 \since 5.8
25
26 A dialog is a popup mostly used for short-term tasks and brief communications
27 with the user. Similarly to \l ApplicationWindow and \l Page, Dialog is organized
28 into three sections: \l header, \l {Popup::}{contentItem}, and \l footer.
29
30 \image qtquickcontrols-page-wireframe.webp
31
32 The \l {Popup::}{padding} properties only affect the contentItem. Use the
33 \l {Popup::}{spacing} property to affect the space between header,
34 contentItem and footer.
35
36 By default, Dialogs have \l {QQuickItem::}{focus}.
37
38 \section1 Dialog Title and Buttons
39
40 Dialog's \l title is displayed by a style-specific title bar that is assigned
41 as a dialog \l header by default.
42
43 Dialog's standard buttons are managed by a \l DialogButtonBox that is assigned
44 as a dialog \l footer by default. The dialog's \l standardButtons property is
45 forwarded to the respective property of the button box. Furthermore, the
46 \l {DialogButtonBox::}{accepted()} and \l {DialogButtonBox::}{rejected()}
47 signals of the button box are connected to the respective signals in Dialog.
48
49 \snippet qtquickcontrols-dialog.qml 1
50
51 \section1 Modal Dialogs
52
53 A \l {Popup::}{modal} dialog blocks input to other content beneath
54 the dialog. When a modal dialog is opened, the user must finish
55 interacting with the dialog and close it before they can access any
56 other content in the same window.
57
58 \snippet qtquickcontrols-dialog-modal.qml 1
59
60 \section1 Modeless Dialogs
61
62 A modeless dialog is a dialog that operates independently of other
63 content around the dialog. When a modeless dialog is opened, the user
64 is allowed to interact with both the dialog and the other content in
65 the same window.
66
67 \snippet qtquickcontrols-dialog-modeless.qml 1
68
69 \sa DialogButtonBox, {Popup Controls}
70*/
71
72/*!
73 \qmlsignal QtQuick.Controls::Dialog::accepted()
74
75 This signal is emitted when the dialog has been accepted either
76 interactively or by calling \l accept().
77
78 \note This signal is \e not emitted when closing the dialog with
79 \l {Popup::}{close()} or setting \l {Popup::}{visible} to \c false.
80
81 \sa rejected()
82*/
83
84/*!
85 \qmlsignal QtQuick.Controls::Dialog::rejected()
86
87 This signal is emitted when the dialog has been rejected either
88 interactively or by calling \l reject().
89
90 \note This signal is \e not emitted when closing the dialog with
91 \l {Popup::}{close()} or setting \l {Popup::}{visible} to \c false.
92
93 \sa accepted()
94*/
95
96/*!
97 \since QtQuick.Controls 2.3 (Qt 5.10)
98 \qmlsignal QtQuick.Controls::Dialog::applied()
99
100 This signal is emitted when the \c Dialog.Apply standard button is clicked.
101
102 \sa discarded(), reset()
103*/
104
105/*!
106 \since QtQuick.Controls 2.3 (Qt 5.10)
107 \qmlsignal QtQuick.Controls::Dialog::reset()
108
109 This signal is emitted when the \c Dialog.Reset standard button is clicked.
110
111 \sa discarded(), applied()
112*/
113
114/*!
115 \since QtQuick.Controls 2.3 (Qt 5.10)
116 \qmlsignal QtQuick.Controls::Dialog::discarded()
117
118 This signal is emitted when the \c Dialog.Discard standard button is clicked.
119
120 \sa reset(), applied()
121*/
122
123/*!
124 \since QtQuick.Controls 2.3 (Qt 5.10)
125 \qmlsignal QtQuick.Controls::Dialog::helpRequested()
126
127 This signal is emitted when the \c Dialog.Help standard button is clicked.
128
129 \sa accepted(), rejected()
130*/
131
132QPlatformDialogHelper::ButtonRole QQuickDialogPrivate::buttonRole(QQuickAbstractButton *button)
133{
134 const QQuickDialogButtonBoxAttached *attached = qobject_cast<QQuickDialogButtonBoxAttached *>(qmlAttachedPropertiesObject<QQuickDialogButtonBox>(button, false));
135 return attached ? attached->buttonRole() : QPlatformDialogHelper::InvalidRole;
136}
137
138void QQuickDialogPrivate::handleAccept()
139{
140 Q_Q(QQuickDialog);
141 q->accept();
142}
143
144void QQuickDialogPrivate::handleReject()
145{
146 Q_Q(QQuickDialog);
147 q->reject();
148}
149
150void QQuickDialogPrivate::handleClick(QQuickAbstractButton *button)
151{
152 Q_Q(QQuickDialog);
153 switch (buttonRole(button)) {
154 case QPlatformDialogHelper::ApplyRole:
155 emit q->applied();
156 break;
157 case QPlatformDialogHelper::ResetRole:
158 emit q->reset();
159 break;
160 case QPlatformDialogHelper::DestructiveRole:
161 emit q->discarded();
162 q->close();
163 break;
164 case QPlatformDialogHelper::HelpRole:
165 emit q->helpRequested();
166 break;
167 default:
168 break;
169 }
170}
171
172Qt::WindowFlags QQuickDialogPrivate::popupWindowType() const
173{
174 return Qt::Dialog;
175}
176
177QQuickDialog::QQuickDialog(QObject *parent)
178 : QQuickDialog(*(new QQuickDialogPrivate), parent)
179{
180}
181
182QQuickDialog::QQuickDialog(QQuickDialogPrivate &dd, QObject *parent)
183 : QQuickPopup(dd, parent)
184{
185 Q_D(QQuickDialog);
186
187 // Dialogs should get active focus when opened so that e.g. Cancel closes them.
188 setFocus(true);
189 QObject::connect(d->popupItem, &QQuickPopupItem::headerChanged, this, &QQuickDialog::headerChanged);
190 QObject::connect(d->popupItem, &QQuickPopupItem::footerChanged, this, &QQuickDialog::footerChanged);
191 QObject::connect(d->popupItem, &QQuickPopupItem::implicitHeaderWidthChanged, this, &QQuickDialog::implicitHeaderWidthChanged);
192 QObject::connect(d->popupItem, &QQuickPopupItem::implicitHeaderHeightChanged, this, &QQuickDialog::implicitHeaderHeightChanged);
193 QObject::connect(d->popupItem, &QQuickPopupItem::implicitFooterWidthChanged, this, &QQuickDialog::implicitFooterWidthChanged);
194 QObject::connect(d->popupItem, &QQuickPopupItem::implicitFooterHeightChanged, this, &QQuickDialog::implicitFooterHeightChanged);
195}
196
197QQuickDialog::~QQuickDialog()
198{
199 Q_D(QQuickDialog);
200 QObject::disconnect(d->popupItem, &QQuickPopupItem::headerChanged, this, &QQuickDialog::headerChanged);
201 QObject::disconnect(d->popupItem, &QQuickPopupItem::footerChanged, this, &QQuickDialog::footerChanged);
202 QObject::disconnect(d->popupItem, &QQuickPopupItem::implicitHeaderWidthChanged, this, &QQuickDialog::implicitHeaderWidthChanged);
203 QObject::disconnect(d->popupItem, &QQuickPopupItem::implicitHeaderHeightChanged, this, &QQuickDialog::implicitHeaderHeightChanged);
204 QObject::disconnect(d->popupItem, &QQuickPopupItem::implicitFooterWidthChanged, this, &QQuickDialog::implicitFooterWidthChanged);
205 QObject::disconnect(d->popupItem, &QQuickPopupItem::implicitFooterHeightChanged, this, &QQuickDialog::implicitFooterHeightChanged);
206}
207
208/*!
209 \qmlproperty string QtQuick.Controls::Dialog::title
210
211 This property holds the dialog title.
212
213 The title is displayed in the dialog header.
214
215 \code
216 Dialog {
217 title: qsTr("About")
218
219 Label {
220 text: "Lorem ipsum..."
221 }
222 }
223 \endcode
224*/
225QString QQuickDialog::title() const
226{
227 Q_D(const QQuickDialog);
228 return d->title;
229}
230
231void QQuickDialog::setTitle(const QString &title)
232{
233 Q_D(QQuickDialog);
234 if (d->title == title)
235 return;
236 d->title = title;
237
238 if (d->popupWindow)
239 d->popupWindow->setTitle(title);
240 else
241 d->popupItem->setTitle(title);
242
243 emit titleChanged();
244}
245
246/*!
247 \qmlproperty Item QtQuick.Controls::Dialog::header
248
249 This property holds the dialog header item. The header item is positioned to
250 the top, and resized to the width of the dialog. The default value is \c null.
251
252 \note Assigning a \l DialogButtonBox as a dialog header automatically connects
253 its \l {DialogButtonBox::}{accepted()} and \l {DialogButtonBox::}{rejected()}
254 signals to the respective signals in Dialog.
255
256 \note Assigning a \l DialogButtonBox, \l ToolBar, or \l TabBar as a dialog
257 header automatically sets the respective \l DialogButtonBox::position,
258 \l ToolBar::position, or \l TabBar::position property to \c Header.
259
260 \sa footer
261*/
262QQuickItem *QQuickDialog::header() const
263{
264 Q_D(const QQuickDialog);
265 return d->popupItem->header();
266}
267
268void QQuickDialog::setHeader(QQuickItem *header)
269{
270 Q_D(QQuickDialog);
271 QQuickItem *oldHeader = d->popupItem->header();
272 if (oldHeader == header)
273 return;
274
275 QQuickControlPrivate::warnIfCustomizationNotSupported(this, header, QStringLiteral("header"));
276
277 if (QQuickDialogButtonBox *buttonBox = qobject_cast<QQuickDialogButtonBox *>(oldHeader)) {
278 QObjectPrivate::disconnect(buttonBox, &QQuickDialogButtonBox::accepted, d, &QQuickDialogPrivate::handleAccept);
279 QObjectPrivate::disconnect(buttonBox, &QQuickDialogButtonBox::rejected, d, &QQuickDialogPrivate::handleReject);
280 QObjectPrivate::disconnect(buttonBox, &QQuickDialogButtonBox::clicked, d, &QQuickDialogPrivate::handleClick);
281 if (d->buttonBox == buttonBox)
282 d->buttonBox = nullptr;
283 }
284
285 if (QQuickDialogButtonBox *buttonBox = qobject_cast<QQuickDialogButtonBox *>(header)) {
286 QObjectPrivate::connect(buttonBox, &QQuickDialogButtonBox::accepted, d, &QQuickDialogPrivate::handleAccept);
287 QObjectPrivate::connect(buttonBox, &QQuickDialogButtonBox::rejected, d, &QQuickDialogPrivate::handleReject);
288 QObjectPrivate::connect(buttonBox, &QQuickDialogButtonBox::clicked, d, &QQuickDialogPrivate::handleClick);
289 d->buttonBox = buttonBox;
290 buttonBox->setStandardButtons(d->standardButtons);
291 }
292
293 d->popupItem->setHeader(header);
294}
295
296/*!
297 \qmlproperty Item QtQuick.Controls::Dialog::footer
298
299 This property holds the dialog footer item. The footer item is positioned to
300 the bottom, and resized to the width of the dialog. The default value is \c null.
301
302 \note Assigning a \l DialogButtonBox as a dialog footer automatically connects
303 its \l {DialogButtonBox::}{accepted()} and \l {DialogButtonBox::}{rejected()}
304 signals to the respective signals in Dialog.
305
306 \note Assigning a \l DialogButtonBox, \l ToolBar, or \l TabBar as a dialog
307 footer automatically sets the respective \l DialogButtonBox::position,
308 \l ToolBar::position, or \l TabBar::position property to \c Footer.
309
310 \sa header
311*/
312QQuickItem *QQuickDialog::footer() const
313{
314 Q_D(const QQuickDialog);
315 return d->popupItem->footer();
316}
317
318void QQuickDialog::setFooter(QQuickItem *footer)
319{
320 Q_D(QQuickDialog);
321 QQuickItem *oldFooter = d->popupItem->footer();
322 if (oldFooter == footer)
323 return;
324
325 QQuickControlPrivate::warnIfCustomizationNotSupported(this, footer, QStringLiteral("footer"));
326
327 if (QQuickDialogButtonBox *buttonBox = qobject_cast<QQuickDialogButtonBox *>(oldFooter)) {
328 QObjectPrivate::disconnect(buttonBox, &QQuickDialogButtonBox::accepted, d, &QQuickDialogPrivate::handleAccept);
329 QObjectPrivate::disconnect(buttonBox, &QQuickDialogButtonBox::rejected, d, &QQuickDialogPrivate::handleReject);
330 QObjectPrivate::disconnect(buttonBox, &QQuickDialogButtonBox::clicked, d, &QQuickDialogPrivate::handleClick);
331 if (d->buttonBox == buttonBox)
332 d->buttonBox = nullptr;
333 }
334 if (QQuickDialogButtonBox *buttonBox = qobject_cast<QQuickDialogButtonBox *>(footer)) {
335 QObjectPrivate::connect(buttonBox, &QQuickDialogButtonBox::accepted, d, &QQuickDialogPrivate::handleAccept);
336 QObjectPrivate::connect(buttonBox, &QQuickDialogButtonBox::rejected, d, &QQuickDialogPrivate::handleReject);
337 QObjectPrivate::connect(buttonBox, &QQuickDialogButtonBox::clicked, d, &QQuickDialogPrivate::handleClick);
338 d->buttonBox = buttonBox;
339 buttonBox->setStandardButtons(d->standardButtons);
340 }
341
342 d->popupItem->setFooter(footer);
343}
344
345/*!
346 \qmlproperty enumeration QtQuick.Controls::Dialog::standardButtons
347
348 This property holds a combination of standard buttons that are used by the dialog.
349
350 \snippet qtquickcontrols-dialog.qml 1
351
352 The buttons will be positioned in the appropriate order for the user's platform.
353
354 Possible flags:
355 \value Dialog.Ok An "OK" button defined with the \c AcceptRole.
356 \value Dialog.Open An "Open" button defined with the \c AcceptRole.
357 \value Dialog.Save A "Save" button defined with the \c AcceptRole.
358 \value Dialog.Cancel A "Cancel" button defined with the \c RejectRole.
359 \value Dialog.Close A "Close" button defined with the \c RejectRole.
360 \value Dialog.Discard A "Discard" or "Don't Save" button, depending on the platform, defined with the \c DestructiveRole.
361 \value Dialog.Apply An "Apply" button defined with the \c ApplyRole.
362 \value Dialog.Reset A "Reset" button defined with the \c ResetRole.
363 \value Dialog.RestoreDefaults A "Restore Defaults" button defined with the \c ResetRole.
364 \value Dialog.Help A "Help" button defined with the \c HelpRole.
365 \value Dialog.SaveAll A "Save All" button defined with the \c AcceptRole.
366 \value Dialog.Yes A "Yes" button defined with the \c YesRole.
367 \value Dialog.YesToAll A "Yes to All" button defined with the \c YesRole.
368 \value Dialog.No A "No" button defined with the \c NoRole.
369 \value Dialog.NoToAll A "No to All" button defined with the \c NoRole.
370 \value Dialog.Abort An "Abort" button defined with the \c RejectRole.
371 \value Dialog.Retry A "Retry" button defined with the \c AcceptRole.
372 \value Dialog.Ignore An "Ignore" button defined with the \c AcceptRole.
373 \value Dialog.NoButton An invalid button.
374
375 \sa DialogButtonBox
376*/
377QPlatformDialogHelper::StandardButtons QQuickDialog::standardButtons() const
378{
379 Q_D(const QQuickDialog);
380 return d->standardButtons;
381}
382
383void QQuickDialog::setStandardButtons(QPlatformDialogHelper::StandardButtons buttons)
384{
385 Q_D(QQuickDialog);
386 if (d->standardButtons == buttons)
387 return;
388
389 d->standardButtons = buttons;
390 if (d->buttonBox)
391 d->buttonBox->setStandardButtons(buttons);
392 emit standardButtonsChanged();
393}
394
395/*!
396 \since QtQuick.Controls 2.3 (Qt 5.10)
397 \qmlmethod AbstractButton QtQuick.Controls::Dialog::standardButton(StandardButton button)
398
399 Returns the specified standard \a button, or \c null if it does not exist.
400
401 \sa standardButtons
402*/
403QQuickAbstractButton *QQuickDialog::standardButton(QPlatformDialogHelper::StandardButton button) const
404{
405 Q_D(const QQuickDialog);
406 if (!d->buttonBox)
407 return nullptr;
408 return d->buttonBox->standardButton(button);
409}
410
411/*!
412 \since QtQuick.Controls 2.3 (Qt 5.10)
413 \qmlproperty int QtQuick.Controls::Dialog::result
414
415 This property holds the result code.
416
417 Standard result codes:
418 \value Dialog.Accepted The dialog was accepted.
419 \value Dialog.Rejected The dialog was rejected.
420
421 \sa accept(), reject(), done()
422*/
423int QQuickDialog::result() const
424{
425 Q_D(const QQuickDialog);
426 return d->result;
427}
428
429void QQuickDialog::setResult(int result)
430{
431 Q_D(QQuickDialog);
432 if (d->result == result)
433 return;
434
435 d->result = result;
436 emit resultChanged();
437}
438
439/*!
440 \since QtQuick.Controls 2.5 (Qt 5.12)
441 \qmlproperty real QtQuick.Controls::Dialog::implicitHeaderWidth
442 \readonly
443
444 This property holds the implicit header width.
445
446 The value is equal to \c {header && header.visible ? header.implicitWidth : 0}.
447
448 \sa implicitHeaderHeight, implicitFooterWidth
449*/
450qreal QQuickDialog::implicitHeaderWidth() const
451{
452 Q_D(const QQuickDialog);
453 return d->popupItem->implicitHeaderWidth();
454}
455
456/*!
457 \since QtQuick.Controls 2.5 (Qt 5.12)
458 \qmlproperty real QtQuick.Controls::Dialog::implicitHeaderHeight
459 \readonly
460
461 This property holds the implicit header height.
462
463 The value is equal to \c {header && header.visible ? header.implicitHeight : 0}.
464
465 \sa implicitHeaderWidth, implicitFooterHeight
466*/
467qreal QQuickDialog::implicitHeaderHeight() const
468{
469 Q_D(const QQuickDialog);
470 return d->popupItem->implicitHeaderHeight();
471}
472
473/*!
474 \since QtQuick.Controls 2.5 (Qt 5.12)
475 \qmlproperty real QtQuick.Controls::Dialog::implicitFooterWidth
476 \readonly
477
478 This property holds the implicit footer width.
479
480 The value is equal to \c {footer && footer.visible ? footer.implicitWidth : 0}.
481
482 \sa implicitFooterHeight, implicitHeaderWidth
483*/
484qreal QQuickDialog::implicitFooterWidth() const
485{
486 Q_D(const QQuickDialog);
487 return d->popupItem->implicitFooterWidth();
488}
489
490/*!
491 \since QtQuick.Controls 2.5 (Qt 5.12)
492 \qmlproperty real QtQuick.Controls::Dialog::implicitFooterHeight
493 \readonly
494
495 This property holds the implicit footer height.
496
497 The value is equal to \c {footer && footer.visible ? footer.implicitHeight : 0}.
498
499 \sa implicitFooterWidth, implicitHeaderHeight
500*/
501qreal QQuickDialog::implicitFooterHeight() const
502{
503 Q_D(const QQuickDialog);
504 return d->popupItem->implicitFooterHeight();
505}
506
507void QQuickDialog::setOpacity(qreal opacity)
508{
509 Q_D(QQuickDialog);
510 QQuickPopup::setOpacity(d->popupWindow ? qreal(!qFuzzyIsNull(opacity)) : opacity);
511}
512
513/*!
514 \qmlmethod void QtQuick.Controls::Dialog::accept()
515
516 Emits the \l accepted() signal and closes the dialog.
517
518 \sa reject(), done()
519*/
520void QQuickDialog::accept()
521{
522 done(Accepted);
523}
524
525/*!
526 \qmlmethod void QtQuick.Controls::Dialog::reject()
527
528 Emits the \l rejected() signal and closes the dialog.
529
530 \sa accept(), done()
531*/
532void QQuickDialog::reject()
533{
534 done(Rejected);
535}
536
537/*!
538 \since QtQuick.Controls 2.3 (Qt 5.10)
539 \qmlmethod void QtQuick.Controls::Dialog::done(int result)
540
541 \list 1
542 \li Sets the \a result.
543 \li Emits \l accepted() or \l rejected() depending on
544 whether the result is \c Dialog.Accepted or \c Dialog.Rejected,
545 respectively.
546 \li Emits \l{Popup::}{closed()}.
547 \endlist
548
549 \sa accept(), reject(), result
550*/
551void QQuickDialog::done(int result)
552{
553 setResult(result);
554
555 if (result == Accepted)
556 emit accepted();
557 else if (result == Rejected)
558 emit rejected();
559
560 close();
561}
562
563#if QT_CONFIG(accessibility)
564QAccessible::Role QQuickDialog::accessibleRole() const
565{
566 return QAccessible::Dialog;
567}
568
569void QQuickDialog::accessibilityActiveChanged(bool active)
570{
571 Q_D(QQuickDialog);
572 QQuickPopup::accessibilityActiveChanged(active);
573
574 if (active)
575 maybeSetAccessibleName(d->popupItem->title());
576}
577#endif
578
579QT_END_NAMESPACE
580
581#include "moc_qquickdialog_p.cpp"