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
qmainwindow.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 "qmainwindow.h"
7
8#if QT_CONFIG(dockwidget)
9#include "qdockwidget.h"
10#endif
11#if QT_CONFIG(toolbar)
12#include "qtoolbar.h"
13#endif
14
15#include <qapplication.h>
16#include <qmenu.h>
17#if QT_CONFIG(menubar)
18#include <qmenubar.h>
19#endif
20#if QT_CONFIG(statusbar)
21#include <qstatusbar.h>
22#endif
23#include <qevent.h>
24#include <qstyle.h>
25#include <qdebug.h>
26#include <qpainter.h>
27#include <qmimedata.h>
28
29#include <private/qwidget_p.h>
30#if QT_CONFIG(toolbar)
31#include "qtoolbar_p.h"
32#endif
34#include <QtGui/qpa/qplatformwindow.h>
35#include <QtGui/qpa/qplatformwindow_p.h>
36
38
39using namespace Qt::StringLiterals;
40
42{
43 Q_DECLARE_PUBLIC(QMainWindow)
44public:
47#ifdef Q_OS_MACOS
48 , useUnifiedToolBar(false)
49#endif
50 { }
55#ifdef Q_OS_MACOS
57#endif
58 void init();
59
60 static inline QMainWindowLayout *mainWindowLayout(const QMainWindow *mainWindow)
61 {
62 return mainWindow ? mainWindow->d_func()->layout.data() : static_cast<QMainWindowLayout *>(nullptr);
63 }
64};
65
66QMainWindowLayout *qt_mainwindow_layout(const QMainWindow *mainWindow)
67{
68 return QMainWindowPrivate::mainWindowLayout(mainWindow);
69}
70
72{
73 Q_Q(QMainWindow);
74
75 layout = new QMainWindowLayout(q, nullptr);
76
77 const int metric = q->style()->pixelMetric(QStyle::PM_ToolBarIconSize, nullptr, q);
78 iconSize = QSize(metric, metric);
79 q->setAttribute(Qt::WA_Hover);
80 q->setAcceptDrops(true);
81}
82
83/*
84 The Main Window:
85
86 +----------------------------------------------------------+
87 | Menu Bar |
88 +----------------------------------------------------------+
89 | Tool Bar Area |
90 | +--------------------------------------------------+ |
91 | | Dock Window Area | |
92 | | +------------------------------------------+ | |
93 | | | | | |
94 | | | Central Widget | | |
95 | | | | | |
96 | | | | | |
97 | | | | | |
98 | | | | | |
99 | | | | | |
100 | | | | | |
101 | | | | | |
102 | | | | | |
103 | | | | | |
104 | | | | | |
105 | | +------------------------------------------+ | |
106 | | | |
107 | +--------------------------------------------------+ |
108 | |
109 +----------------------------------------------------------+
110 | Status Bar |
111 +----------------------------------------------------------+
112
113*/
114
115/*!
116 \class QMainWindow
117 \brief The QMainWindow class provides a main application
118 window.
119 \ingroup mainwindow-classes
120 \inmodule QtWidgets
121
122 \section1 Qt Main Window Framework
123
124 A main window provides a framework for building an
125 application's user interface. Qt has QMainWindow and its \l{Main
126 Window and Related Classes}{related classes} for main window
127 management. QMainWindow has its own layout to which you can add
128 \l{QToolBar}s, \l{QDockWidget}s, a
129 QMenuBar, and a QStatusBar. The layout has a center area that can
130 be occupied by any kind of widget. You can see an image of the
131 layout below.
132
133 \image mainwindowlayout.png
134 {Diagram of main window and the position of its components}
135
136 \section1 Creating Main Window Components
137
138 A central widget will typically be a standard Qt widget such
139 as a QTextEdit or a QGraphicsView. Custom widgets can also be
140 used for advanced applications. You set the central widget with \c
141 setCentralWidget().
142
143 Main windows have either a single (SDI) or multiple (MDI)
144 document interface. You create MDI applications in Qt by using a
145 QMdiArea as the central widget.
146
147 We will now examine each of the other widgets that can be
148 added to a main window. We give examples on how to create and add
149 them.
150
151 \section2 Creating Menus
152
153 Qt implements menus in QMenu and QMainWindow keeps them in a
154 QMenuBar. \l{QAction}{QAction}s are added to the menus, which
155 display them as menu items.
156
157 You can add new menus to the main window's menu bar by calling
158 \c menuBar(), which returns the QMenuBar for the window, and then
159 add a menu with QMenuBar::addMenu().
160
161 QMainWindow comes with a default menu bar, but you can also
162 set one yourself with \c setMenuBar(). If you wish to implement a
163 custom menu bar (i.e., not use the QMenuBar widget), you can set it
164 with \c setMenuWidget().
165
166 An example of how to create menus follows:
167
168 \snippet code/src_widgets_widgets_qmainwindow.cpp 0
169
170 The \c createPopupMenu() function creates popup menus when the
171 main window receives context menu events. The default
172 implementation generates a menu with the checkable actions from
173 the dock widgets and toolbars. You can reimplement \c
174 createPopupMenu() for a custom menu.
175
176 \section2 Creating Toolbars
177
178 Toolbars are implemented in the QToolBar class. You add a
179 toolbar to a main window with \c addToolBar().
180
181 You control the initial position of toolbars by assigning them
182 to a specific Qt::ToolBarArea. You can split an area by inserting
183 a toolbar break - think of this as a line break in text editing -
184 with \c addToolBarBreak() or \c insertToolBarBreak(). You can also
185 restrict placement by the user with QToolBar::setAllowedAreas()
186 and QToolBar::setMovable().
187
188 The size of toolbar icons can be retrieved with \c iconSize().
189 The sizes are platform dependent; you can set a fixed size with \c
190 setIconSize(). You can alter the appearance of all tool buttons in
191 the toolbars with \c setToolButtonStyle().
192
193 An example of toolbar creation follows:
194
195 \snippet code/src_widgets_widgets_qmainwindow.cpp 1
196
197 \section2 Creating Dock Widgets
198
199 Dock widgets are implemented in the QDockWidget class. A dock
200 widget is a window that can be docked into the main window. You
201 add dock widgets to a main window with \c addDockWidget().
202
203 There are four dock widget areas as given by the
204 Qt::DockWidgetArea enum: left, right, top, and bottom. You can
205 specify which dock widget area that should occupy the corners
206 where the areas overlap with \c setCorner(). By default
207 each area can only contain one row (vertical or horizontal) of
208 dock widgets, but if you enable nesting with \c
209 setDockNestingEnabled(), dock widgets can be added in either
210 direction.
211
212 Two dock widgets may also be stacked on top of each other. A
213 QTabBar is then used to select which of the widgets should be
214 displayed.
215
216 We give an example of how to create and add dock widgets to a
217 main window:
218
219 \snippet mainwindowsnippet.cpp 0
220
221 \section2 The Status Bar
222
223 You can set a status bar with \c setStatusBar(), but one is
224 created the first time \c statusBar() (which returns the main
225 window's status bar) is called. See QStatusBar for information on
226 how to use it.
227
228 \section1 Storing State
229
230 QMainWindow can store the state of its layout with \c
231 saveState(); it can later be retrieved with \c restoreState(). It
232 is the position and size (relative to the size of the main window)
233 of the toolbars and dock widgets that are stored.
234
235 \section1 Security Considerations
236
237 The restoreState() function deserializes a versioned binary blob that
238 describes the toolbar and dock widget layout, including a recursively
239 nested tree structure for split and tabbed dock areas. The format's magic
240 marker and version are validated, but individual fields - such as dock area
241 indices and the depth of the nested layout tree - are not bounds-checked
242 against the main window's actual configuration once the outer structure is
243 accepted.
244
245 Only pass restoreState() a QByteArray that was previously produced by
246 saveState() and persisted by the same, or a compatible, version of your
247 application, typically through QSettings. Do not call restoreState()
248 with data of unknown or untrusted origin, such as a file downloaded from
249 the network, a synced or shared configuration file, or data supplied by
250 another, potentially compromised, application.
251
252 \sa QMenuBar, QToolBar, QStatusBar, QDockWidget, {Menus Example}
253*/
254
255/*!
256 \fn void QMainWindow::iconSizeChanged(const QSize &iconSize)
257
258 This signal is emitted when the size of the icons used in the
259 window is changed. The new icon size is passed in \a iconSize.
260
261 You can connect this signal to other components to help maintain
262 a consistent appearance for your application.
263
264 \sa setIconSize()
265*/
266
267/*!
268 \fn void QMainWindow::toolButtonStyleChanged(Qt::ToolButtonStyle toolButtonStyle)
269
270 This signal is emitted when the style used for tool buttons in the
271 window is changed. The new style is passed in \a toolButtonStyle.
272
273 You can connect this signal to other components to help maintain
274 a consistent appearance for your application.
275
276 \sa setToolButtonStyle()
277*/
278
279#if QT_CONFIG(dockwidget)
280/*!
281 \fn void QMainWindow::tabifiedDockWidgetActivated(QDockWidget *dockWidget)
282
283 This signal is emitted when the tabified dock widget is activated by
284 selecting the tab. The activated dock widget is passed in \a dockWidget.
285
286 \since 5.8
287 \sa tabifyDockWidget(), tabifiedDockWidgets()
288*/
289#endif
290
291/*!
292 Constructs a QMainWindow with the given \a parent and the specified
293 widget \a flags.
294
295 QMainWindow sets the Qt::Window flag itself, and will hence
296 always be created as a top-level widget.
297 */
298QMainWindow::QMainWindow(QWidget *parent, Qt::WindowFlags flags)
299 : QWidget(*(new QMainWindowPrivate()), parent, flags | Qt::Window)
300{
301 d_func()->init();
302}
303
304
305/*!
306 Destroys the main window.
307 */
308QMainWindow::~QMainWindow()
309{ }
310
311/*! \property QMainWindow::iconSize
312 \brief size of toolbar icons in this mainwindow.
313
314 The default is the default tool bar icon size of the GUI style.
315 Note that the icons used must be at least of this size as the
316 icons are only scaled down.
317*/
318
319/*!
320 \property QMainWindow::dockOptions
321 \brief the docking behavior of QMainWindow
322 \since 4.3
323
324 The default value is AnimatedDocks | AllowTabbedDocks.
325*/
326
327/*!
328 \enum QMainWindow::DockOption
329 \since 4.3
330
331 This enum contains flags that specify the docking behavior of QMainWindow.
332
333 \value AnimatedDocks Identical to the \l animated property.
334
335 \value AllowNestedDocks Identical to the \l dockNestingEnabled property.
336
337 \value AllowTabbedDocks The user can drop one dock widget "on top" of
338 another. The two widgets are stacked and a tab
339 bar appears for selecting which one is visible.
340
341 \value ForceTabbedDocks Each dock area contains a single stack of tabbed
342 dock widgets. In other words, dock widgets cannot
343 be placed next to each other in a dock area. If
344 this option is set, AllowNestedDocks has no effect.
345
346 \value VerticalTabs The two vertical dock areas on the sides of the
347 main window show their tabs vertically. If this
348 option is not set, all dock areas show their tabs
349 at the bottom. Implies AllowTabbedDocks. See also
350 \l setTabPosition().
351
352 \value GroupedDragging When dragging the titlebar of a dock, all the tabs
353 that are tabbed with it are going to be dragged.
354 Implies AllowTabbedDocks. Does not work well if
355 some QDockWidgets have restrictions in which area
356 they are allowed. (This enum value was added in Qt
357 5.6.)
358
359 These options only control how dock widgets may be dropped in a QMainWindow.
360 They do not re-arrange the dock widgets to conform with the specified
361 options. For this reason they should be set before any dock widgets
362 are added to the main window. Exceptions to this are the AnimatedDocks and
363 VerticalTabs options, which may be set at any time.
364*/
365
366void QMainWindow::setDockOptions(DockOptions opt)
367{
368 Q_D(QMainWindow);
369 d->layout->setDockOptions(opt);
370}
371
372QMainWindow::DockOptions QMainWindow::dockOptions() const
373{
374 Q_D(const QMainWindow);
375 return d->layout->dockOptions;
376}
377
378QSize QMainWindow::iconSize() const
379{ return d_func()->iconSize; }
380
381void QMainWindow::setIconSize(const QSize &iconSize)
382{
383 Q_D(QMainWindow);
384 QSize sz = iconSize;
385 if (!sz.isValid()) {
386 const int metric = style()->pixelMetric(QStyle::PM_ToolBarIconSize, nullptr, this);
387 sz = QSize(metric, metric);
388 }
389 if (d->iconSize != sz) {
390 d->iconSize = sz;
391 emit iconSizeChanged(d->iconSize);
392 }
393 d->explicitIconSize = iconSize.isValid();
394}
395
396/*! \property QMainWindow::toolButtonStyle
397 \brief style of toolbar buttons in this mainwindow.
398
399 To have the style of toolbuttons follow the system settings, set this property to Qt::ToolButtonFollowStyle.
400 On Unix, the user settings from the desktop environment will be used.
401 On other platforms, Qt::ToolButtonFollowStyle means icon only.
402
403 The default is Qt::ToolButtonIconOnly.
404*/
405
406Qt::ToolButtonStyle QMainWindow::toolButtonStyle() const
407{ return d_func()->toolButtonStyle; }
408
409void QMainWindow::setToolButtonStyle(Qt::ToolButtonStyle toolButtonStyle)
410{
411 Q_D(QMainWindow);
412 if (d->toolButtonStyle == toolButtonStyle)
413 return;
414 d->toolButtonStyle = toolButtonStyle;
415 emit toolButtonStyleChanged(d->toolButtonStyle);
416}
417
418#if QT_CONFIG(menubar)
419/*!
420 Returns the menu bar for the main window. This function creates
421 and returns an empty menu bar if the menu bar does not exist.
422
423 If you want all windows in a Mac application to share one menu
424 bar, don't use this function to create it, because the menu bar
425 created here will have this QMainWindow as its parent. Instead,
426 you must create a menu bar that does not have a parent, which you
427 can then share among all the Mac windows. Create a parent-less
428 menu bar this way:
429
430 \snippet code/src_gui_widgets_qmenubar.cpp 1
431
432 \sa setMenuBar()
433*/
434QMenuBar *QMainWindow::menuBar() const
435{
436 QMenuBar *menuBar = qobject_cast<QMenuBar *>(layout()->menuBar());
437 if (!menuBar) {
438 QMainWindow *self = const_cast<QMainWindow *>(this);
439 menuBar = new QMenuBar(self);
440 self->setMenuBar(menuBar);
441 }
442 return menuBar;
443}
444
445/*!
446 Sets the menu bar for the main window to \a menuBar.
447
448 Note: QMainWindow takes ownership of the \a menuBar pointer and
449 deletes it at the appropriate time.
450
451 \sa menuBar()
452*/
453void QMainWindow::setMenuBar(QMenuBar *menuBar)
454{
455 QLayout *topLayout = layout();
456
457 if (QWidget *existingMenuBar = topLayout->menuBar(); existingMenuBar && existingMenuBar != menuBar) {
458 // Reparent corner widgets before we delete the old menu bar.
459 QMenuBar *oldMenuBar = qobject_cast<QMenuBar *>(existingMenuBar);
460 if (oldMenuBar && menuBar) {
461 // TopLeftCorner widget.
462 QWidget *cornerWidget = oldMenuBar->cornerWidget(Qt::TopLeftCorner);
463 if (cornerWidget)
464 menuBar->setCornerWidget(cornerWidget, Qt::TopLeftCorner);
465 // TopRightCorner widget.
466 cornerWidget = oldMenuBar->cornerWidget(Qt::TopRightCorner);
467 if (cornerWidget)
468 menuBar->setCornerWidget(cornerWidget, Qt::TopRightCorner);
469 }
470
471 existingMenuBar->hide();
472 existingMenuBar->setParent(nullptr);
473 existingMenuBar->deleteLater();
474 }
475 topLayout->setMenuBar(menuBar);
476}
477
478/*!
479 \since 4.2
480
481 Returns the menu bar for the main window. This function returns
482 null if a menu bar hasn't been constructed yet.
483*/
484QWidget *QMainWindow::menuWidget() const
485{
486 QWidget *menuBar = d_func()->layout->menuBar();
487 return menuBar;
488}
489
490/*!
491 \since 4.2
492
493 Sets the menu bar for the main window to \a menuBar.
494
495 QMainWindow takes ownership of the \a menuBar pointer and
496 deletes it at the appropriate time.
497*/
498void QMainWindow::setMenuWidget(QWidget *menuBar)
499{
500 Q_D(QMainWindow);
501 if (d->layout->menuBar() && d->layout->menuBar() != menuBar) {
502 d->layout->menuBar()->hide();
503 d->layout->menuBar()->deleteLater();
504 }
505 d->layout->setMenuBar(menuBar);
506}
507#endif // QT_CONFIG(menubar)
508
509#if QT_CONFIG(statusbar)
510/*!
511 Returns the status bar for the main window. This function creates
512 and returns an empty status bar if the status bar does not exist.
513
514 \sa setStatusBar()
515*/
516QStatusBar *QMainWindow::statusBar() const
517{
518 QStatusBar *statusbar = d_func()->layout->statusBar();
519 if (!statusbar) {
520 QMainWindow *self = const_cast<QMainWindow *>(this);
521 statusbar = new QStatusBar(self);
522 statusbar->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed);
523 self->setStatusBar(statusbar);
524 }
525 return statusbar;
526}
527
528/*!
529 Sets the status bar for the main window to \a statusbar.
530
531 Setting the status bar to \nullptr will remove it from the main window.
532 Note that QMainWindow takes ownership of the \a statusbar pointer
533 and deletes it at the appropriate time.
534
535 \sa statusBar()
536*/
537void QMainWindow::setStatusBar(QStatusBar *statusbar)
538{
539 Q_D(QMainWindow);
540 if (d->layout->statusBar() && d->layout->statusBar() != statusbar) {
541 d->layout->statusBar()->hide();
542 d->layout->statusBar()->deleteLater();
543 }
544 d->layout->setStatusBar(statusbar);
545}
546#endif // QT_CONFIG(statusbar)
547
548/*!
549 Returns the central widget for the main window. This function
550 returns \nullptr if the central widget has not been set.
551
552 \sa setCentralWidget()
553*/
554QWidget *QMainWindow::centralWidget() const
555{ return d_func()->layout->centralWidget(); }
556
557/*!
558 Sets the given \a widget to be the main window's central widget.
559
560 Note: QMainWindow takes ownership of the \a widget pointer and
561 deletes it at the appropriate time.
562
563 \sa centralWidget()
564*/
565void QMainWindow::setCentralWidget(QWidget *widget)
566{
567 Q_D(QMainWindow);
568 if (d->layout->centralWidget() && d->layout->centralWidget() != widget) {
569 d->layout->centralWidget()->hide();
570 d->layout->centralWidget()->deleteLater();
571 }
572 d->layout->setCentralWidget(widget);
573}
574
575/*!
576 Removes the central widget from this main window.
577
578 The ownership of the removed widget is passed to the caller.
579
580 \since 5.2
581*/
582QWidget *QMainWindow::takeCentralWidget()
583{
584 Q_D(QMainWindow);
585 QWidget *oldcentralwidget = d->layout->centralWidget();
586 if (oldcentralwidget) {
587 oldcentralwidget->setParent(nullptr);
588 d->layout->setCentralWidget(nullptr);
589 }
590 return oldcentralwidget;
591}
592
593#if QT_CONFIG(dockwidget)
594/*!
595 Sets the given dock widget \a area to occupy the specified \a
596 corner.
597
598 \sa corner()
599*/
600void QMainWindow::setCorner(Qt::Corner corner, Qt::DockWidgetArea area)
601{
602 bool valid = false;
603 switch (corner) {
604 case Qt::TopLeftCorner:
605 valid = (area == Qt::TopDockWidgetArea || area == Qt::LeftDockWidgetArea);
606 break;
607 case Qt::TopRightCorner:
608 valid = (area == Qt::TopDockWidgetArea || area == Qt::RightDockWidgetArea);
609 break;
610 case Qt::BottomLeftCorner:
611 valid = (area == Qt::BottomDockWidgetArea || area == Qt::LeftDockWidgetArea);
612 break;
613 case Qt::BottomRightCorner:
614 valid = (area == Qt::BottomDockWidgetArea || area == Qt::RightDockWidgetArea);
615 break;
616 }
617 if (Q_UNLIKELY(!valid))
618 qWarning("QMainWindow::setCorner(): 'area' is not valid for 'corner'");
619 else
620 d_func()->layout->setCorner(corner, area);
621}
622
623/*!
624 Returns the dock widget area that occupies the specified \a
625 corner.
626
627 \sa setCorner()
628*/
629Qt::DockWidgetArea QMainWindow::corner(Qt::Corner corner) const
630{ return d_func()->layout->corner(corner); }
631#endif
632
633#if QT_CONFIG(toolbar)
634
635static bool checkToolBarArea(Qt::ToolBarArea area, const char *where)
636{
637 switch (area) {
638 case Qt::LeftToolBarArea:
639 case Qt::RightToolBarArea:
640 case Qt::TopToolBarArea:
641 case Qt::BottomToolBarArea:
642 return true;
643 default:
644 break;
645 }
646 qWarning("%s: invalid 'area' argument", where);
647 return false;
648}
649
650/*!
651 Adds a toolbar break to the given \a area after all the other
652 objects that are present.
653*/
654void QMainWindow::addToolBarBreak(Qt::ToolBarArea area)
655{
656 if (!checkToolBarArea(area, "QMainWindow::addToolBarBreak"))
657 return;
658 d_func()->layout->addToolBarBreak(area);
659}
660
661/*!
662 Inserts a toolbar break before the toolbar specified by \a before.
663*/
664void QMainWindow::insertToolBarBreak(QToolBar *before)
665{ d_func()->layout->insertToolBarBreak(before); }
666
667/*!
668 Removes a toolbar break previously inserted before the toolbar specified by \a before.
669*/
670
671void QMainWindow::removeToolBarBreak(QToolBar *before)
672{
673 Q_D(QMainWindow);
674 d->layout->removeToolBarBreak(before);
675}
676
677/*!
678 Adds the \a toolbar into the specified \a area in this main
679 window. The \a toolbar is placed at the end of the current tool
680 bar block (i.e. line). If the main window already manages \a toolbar
681 then it will only move the toolbar to \a area.
682
683 \sa insertToolBar(), addToolBarBreak(), insertToolBarBreak()
684*/
685void QMainWindow::addToolBar(Qt::ToolBarArea area, QToolBar *toolbar)
686{
687 if (!checkToolBarArea(area, "QMainWindow::addToolBar"))
688 return;
689
690 Q_D(QMainWindow);
691
692 disconnect(this, SIGNAL(iconSizeChanged(QSize)),
693 toolbar, SLOT(_q_updateIconSize(QSize)));
694 disconnect(this, SIGNAL(toolButtonStyleChanged(Qt::ToolButtonStyle)),
695 toolbar, SLOT(_q_updateToolButtonStyle(Qt::ToolButtonStyle)));
696
697 if (toolbar->d_func()->state && toolbar->d_func()->state->dragging) {
698 //removing a toolbar which is dragging will cause crash
699#if QT_CONFIG(dockwidget)
700 bool animated = isAnimated();
701 setAnimated(false);
702#endif
703 toolbar->d_func()->endDrag();
704#if QT_CONFIG(dockwidget)
705 setAnimated(animated);
706#endif
707 }
708
709 d->layout->removeToolBar(toolbar);
710
711 toolbar->d_func()->_q_updateIconSize(d->iconSize);
712 toolbar->d_func()->_q_updateToolButtonStyle(d->toolButtonStyle);
713 connect(this, SIGNAL(iconSizeChanged(QSize)),
714 toolbar, SLOT(_q_updateIconSize(QSize)));
715 connect(this, SIGNAL(toolButtonStyleChanged(Qt::ToolButtonStyle)),
716 toolbar, SLOT(_q_updateToolButtonStyle(Qt::ToolButtonStyle)));
717
718 d->layout->addToolBar(area, toolbar);
719}
720
721/*! \overload
722 Equivalent of calling addToolBar(Qt::TopToolBarArea, \a toolbar)
723*/
724void QMainWindow::addToolBar(QToolBar *toolbar)
725{ addToolBar(Qt::TopToolBarArea, toolbar); }
726
727/*!
728 \overload
729
730 Creates a QToolBar object, setting its window title to \a title,
731 and inserts it into the top toolbar area.
732
733 \sa setWindowTitle()
734*/
735QToolBar *QMainWindow::addToolBar(const QString &title)
736{
737 QToolBar *toolBar = new QToolBar(this);
738 toolBar->setWindowTitle(title);
739 addToolBar(toolBar);
740 return toolBar;
741}
742
743/*!
744 Inserts the \a toolbar into the area occupied by the \a before toolbar
745 so that it appears before it. For example, in normal left-to-right
746 layout operation, this means that \a toolbar will appear to the left
747 of the toolbar specified by \a before in a horizontal toolbar area.
748
749 \sa insertToolBarBreak(), addToolBar(), addToolBarBreak()
750*/
751void QMainWindow::insertToolBar(QToolBar *before, QToolBar *toolbar)
752{
753 Q_D(QMainWindow);
754
755 d->layout->removeToolBar(toolbar);
756
757 toolbar->d_func()->_q_updateIconSize(d->iconSize);
758 toolbar->d_func()->_q_updateToolButtonStyle(d->toolButtonStyle);
759 connect(this, SIGNAL(iconSizeChanged(QSize)),
760 toolbar, SLOT(_q_updateIconSize(QSize)));
761 connect(this, SIGNAL(toolButtonStyleChanged(Qt::ToolButtonStyle)),
762 toolbar, SLOT(_q_updateToolButtonStyle(Qt::ToolButtonStyle)));
763
764 d->layout->insertToolBar(before, toolbar);
765}
766
767/*!
768 Removes the \a toolbar from the main window layout and hides
769 it. Note that the \a toolbar is \e not deleted.
770*/
771void QMainWindow::removeToolBar(QToolBar *toolbar)
772{
773 if (toolbar) {
774 d_func()->layout->removeToolBar(toolbar);
775 toolbar->hide();
776 }
777}
778
779/*!
780 Returns the Qt::ToolBarArea for \a toolbar. If \a toolbar has not
781 been added to the main window, this function returns \c
782 Qt::NoToolBarArea.
783
784 \sa addToolBar(), addToolBarBreak(), Qt::ToolBarArea
785*/
786Qt::ToolBarArea QMainWindow::toolBarArea(const QToolBar *toolbar) const
787{ return d_func()->layout->toolBarArea(toolbar); }
788
789/*!
790
791 Returns whether there is a toolbar
792 break before the \a toolbar.
793
794 \sa addToolBarBreak(), insertToolBarBreak()
795*/
796bool QMainWindow::toolBarBreak(QToolBar *toolbar) const
797{
798 return d_func()->layout->toolBarBreak(toolbar);
799}
800
801#endif // QT_CONFIG(toolbar)
802
803#if QT_CONFIG(dockwidget)
804
805/*! \property QMainWindow::animated
806 \brief whether manipulating dock widgets and tool bars is animated
807 \since 4.2
808
809 When a dock widget or tool bar is dragged over the
810 main window, the main window adjusts its contents
811 to indicate where the dock widget or tool bar will
812 be docked if it is dropped. Setting this property
813 causes QMainWindow to move its contents in a smooth
814 animation. Clearing this property causes the contents
815 to snap into their new positions.
816
817 By default, this property is set. It may be cleared if
818 the main window contains widgets which are slow at resizing
819 or repainting themselves.
820
821 Setting this property is identical to setting the AnimatedDocks
822 option using setDockOptions().
823*/
824
825bool QMainWindow::isAnimated() const
826{
827 Q_D(const QMainWindow);
828 return d->layout->dockOptions & AnimatedDocks;
829}
830
831void QMainWindow::setAnimated(bool enabled)
832{
833 Q_D(QMainWindow);
834
835 DockOptions opts = d->layout->dockOptions;
836 opts.setFlag(AnimatedDocks, enabled);
837
838 d->layout->setDockOptions(opts);
839}
840
841/*! \property QMainWindow::dockNestingEnabled
842 \brief whether docks can be nested
843 \since 4.2
844
845 If this property is \c false, dock areas can only contain a single row
846 (horizontal or vertical) of dock widgets. If this property is \c true,
847 the area occupied by a dock widget can be split in either direction to contain
848 more dock widgets.
849
850 Dock nesting is only necessary in applications that contain a lot of
851 dock widgets. It gives the user greater freedom in organizing their
852 main window. However, dock nesting leads to more complex
853 (and less intuitive) behavior when a dock widget is dragged over the
854 main window, since there are more ways in which a dropped dock widget
855 may be placed in the dock area.
856
857 Setting this property is identical to setting the AllowNestedDocks option
858 using setDockOptions().
859*/
860
861bool QMainWindow::isDockNestingEnabled() const
862{
863 Q_D(const QMainWindow);
864 return d->layout->dockOptions & AllowNestedDocks;
865}
866
867void QMainWindow::setDockNestingEnabled(bool enabled)
868{
869 Q_D(QMainWindow);
870
871 DockOptions opts = d->layout->dockOptions;
872 opts.setFlag(AllowNestedDocks, enabled);
873
874 d->layout->setDockOptions(opts);
875}
876
877#if 0
878// If added back in, add the '!' to the qdoc comment marker as well.
879/*
880 \property QMainWindow::verticalTabsEnabled
881 \brief whether left and right dock areas use vertical tabs
882 \since 4.2
883
884 If this property is set to false, dock areas containing tabbed dock widgets
885 display horizontal tabs, similar to Visual Studio.
886
887 If this property is set to true, then the right and left dock areas display vertical
888 tabs, similar to KDevelop.
889
890 This property should be set before any dock widgets are added to the main window.
891*/
892
893bool QMainWindow::verticalTabsEnabled() const
894{
895 return d_func()->layout->verticalTabsEnabled();
896}
897
898void QMainWindow::setVerticalTabsEnabled(bool enabled)
899{
900 d_func()->layout->setVerticalTabsEnabled(enabled);
901}
902#endif
903
904static bool checkDockWidgetArea(Qt::DockWidgetArea area, const char *where)
905{
906 switch (area) {
907 case Qt::LeftDockWidgetArea:
908 case Qt::RightDockWidgetArea:
909 case Qt::TopDockWidgetArea:
910 case Qt::BottomDockWidgetArea:
911 return true;
912 default:
913 break;
914 }
915 qWarning("%s: invalid 'area' argument", where);
916 return false;
917}
918
919#if QT_CONFIG(tabbar)
920/*!
921 \property QMainWindow::documentMode
922 \brief whether the tab bar for tabbed dockwidgets is set to document mode.
923 \since 4.5
924
925 The default is false.
926
927 \sa QTabBar::documentMode
928*/
929bool QMainWindow::documentMode() const
930{
931 return d_func()->layout->documentMode();
932}
933
934void QMainWindow::setDocumentMode(bool enabled)
935{
936 d_func()->layout->setDocumentMode(enabled);
937}
938#endif // QT_CONFIG(tabbar)
939
940#if QT_CONFIG(tabwidget)
941/*!
942 \property QMainWindow::tabShape
943 \brief the tab shape used for tabbed dock widgets.
944 \since 4.5
945
946 The default is \l QTabWidget::Rounded.
947
948 \sa setTabPosition()
949*/
950QTabWidget::TabShape QMainWindow::tabShape() const
951{
952 return d_func()->layout->tabShape();
953}
954
955void QMainWindow::setTabShape(QTabWidget::TabShape tabShape)
956{
957 d_func()->layout->setTabShape(tabShape);
958}
959
960/*!
961 \since 4.5
962
963 Returns the tab position for \a area.
964
965 \note The \l VerticalTabs dock option overrides the tab positions returned
966 by this function.
967
968 \sa setTabPosition(), tabShape()
969*/
970QTabWidget::TabPosition QMainWindow::tabPosition(Qt::DockWidgetArea area) const
971{
972 if (!checkDockWidgetArea(area, "QMainWindow::tabPosition"))
973 return QTabWidget::South;
974 return d_func()->layout->tabPosition(area);
975}
976
977/*!
978 \since 4.5
979
980 Sets the tab position for the given dock widget \a areas to the specified
981 \a tabPosition. By default, all dock areas show their tabs at the bottom.
982
983 \note The \l VerticalTabs dock option overrides the tab positions set by
984 this method.
985
986 \sa tabPosition(), setTabShape()
987*/
988void QMainWindow::setTabPosition(Qt::DockWidgetAreas areas, QTabWidget::TabPosition tabPosition)
989{
990 d_func()->layout->setTabPosition(areas, tabPosition);
991}
992#endif // QT_CONFIG(tabwidget)
993
994/*!
995 Adds the given \a dockwidget to the specified \a area in the main window.
996*/
997void QMainWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget *dockwidget)
998{
999 if (!checkDockWidgetArea(area, "QMainWindow::addDockWidget"))
1000 return;
1001
1002 Qt::Orientation orientation = Qt::Vertical;
1003 switch (area) {
1004 case Qt::TopDockWidgetArea:
1005 case Qt::BottomDockWidgetArea:
1006 orientation = Qt::Horizontal;
1007 break;
1008 default:
1009 break;
1010 }
1011 const Qt::DockWidgetArea oldArea = dockWidgetArea(dockwidget);
1012 d_func()->layout->removeWidget(dockwidget); // in case it was already in here
1013 addDockWidget(area, dockwidget, orientation);
1014 if (oldArea != area)
1015 emit dockwidget->dockLocationChanged(area);
1016}
1017
1018/*!
1019 Restores the state of \a dockwidget if it is created after the call
1020 to restoreState(). Returns \c true if the state was restored; otherwise
1021 returns \c false.
1022
1023 \sa restoreState(), saveState()
1024*/
1025
1026bool QMainWindow::restoreDockWidget(QDockWidget *dockwidget)
1027{
1028 return d_func()->layout->restoreDockWidget(dockwidget);
1029}
1030
1031/*!
1032 Adds \a dockwidget into the given \a area in the direction
1033 specified by the \a orientation.
1034*/
1035void QMainWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget *dockwidget,
1036 Qt::Orientation orientation)
1037{
1038 if (!checkDockWidgetArea(area, "QMainWindow::addDockWidget"))
1039 return;
1040
1041 // add a window to an area, placing done relative to the previous
1042 d_func()->layout->addDockWidget(area, dockwidget, orientation);
1043}
1044
1045/*!
1046 \fn void QMainWindow::splitDockWidget(QDockWidget *first, QDockWidget *second, Qt::Orientation orientation)
1047
1048 Splits the space covered by the \a first dock widget into two parts,
1049 moves the \a first dock widget into the first part, and moves the
1050 \a second dock widget into the second part.
1051
1052 The \a orientation specifies how the space is divided: A Qt::Horizontal
1053 split places the second dock widget to the right of the first; a
1054 Qt::Vertical split places the second dock widget below the first.
1055
1056 \e Note: if \a first is currently in a tabbed docked area, \a second will
1057 be added as a new tab, not as a neighbor of \a first. This is because a
1058 single tab can contain only one dock widget.
1059
1060 \e Note: The Qt::LayoutDirection influences the order of the dock widgets
1061 in the two parts of the divided area. When right-to-left layout direction
1062 is enabled, the placing of the dock widgets will be reversed.
1063
1064 \sa tabifyDockWidget(), addDockWidget(), removeDockWidget()
1065*/
1066void QMainWindow::splitDockWidget(QDockWidget *after, QDockWidget *dockwidget,
1067 Qt::Orientation orientation)
1068{
1069 d_func()->layout->splitDockWidget(after, dockwidget, orientation);
1070}
1071
1072#if QT_CONFIG(tabbar)
1073/*!
1074 \fn void QMainWindow::tabifyDockWidget(QDockWidget *first, QDockWidget *second)
1075
1076 Moves \a second dock widget on top of \a first dock widget, creating a tabbed
1077 dock area at the current location of \a first.
1078
1079 Both dock widgets must have been added to the main window with
1080 addDockWidget() before calling this function, and neither can already be tabbed.
1081
1082 \sa tabifiedDockWidgets(), addDockWidget()
1083*/
1084void QMainWindow::tabifyDockWidget(QDockWidget *first, QDockWidget *second)
1085{
1086 d_func()->layout->tabifyDockWidget(first, second);
1087}
1088
1089
1090/*!
1091 \fn QList<QDockWidget*> QMainWindow::tabifiedDockWidgets(QDockWidget *dockwidget) const
1092
1093 Returns the dock widgets that are tabified together with \a dockwidget.
1094
1095 \since 4.5
1096 \sa tabifyDockWidget()
1097*/
1098
1099QList<QDockWidget*> QMainWindow::tabifiedDockWidgets(QDockWidget *dockwidget) const
1100{
1101 Q_D(const QMainWindow);
1102 return d->layout ? d->layout->tabifiedDockWidgets(dockwidget) : QList<QDockWidget *>();
1103}
1104#endif // QT_CONFIG(tabbar)
1105
1106
1107/*!
1108 Removes the \a dockwidget from the main window layout and hides
1109 it. Note that the \a dockwidget is \e not deleted.
1110*/
1111void QMainWindow::removeDockWidget(QDockWidget *dockwidget)
1112{
1113 if (dockwidget) {
1114 d_func()->layout->removeWidget(dockwidget);
1115 dockwidget->hide();
1116 }
1117}
1118
1119/*!
1120 Returns the Qt::DockWidgetArea for \a dockwidget. If \a dockwidget
1121 has not been added to the main window, this function returns \c
1122 Qt::NoDockWidgetArea.
1123
1124 \sa addDockWidget(), splitDockWidget(), Qt::DockWidgetArea
1125*/
1126Qt::DockWidgetArea QMainWindow::dockWidgetArea(QDockWidget *dockwidget) const
1127{ return d_func()->layout->dockWidgetArea(dockwidget); }
1128
1129
1130/*!
1131 \since 5.6
1132 Resizes the dock widgets in the list \a docks to the corresponding size in
1133 pixels from the list \a sizes. If \a orientation is Qt::Horizontal, adjusts
1134 the width, otherwise adjusts the height of the dock widgets.
1135 The sizes will be adjusted such that the maximum and the minimum sizes are
1136 respected and the QMainWindow itself will not be resized.
1137 Any additional/missing space is distributed amongst the widgets according
1138 to the relative weight of the sizes.
1139
1140 Example:
1141 \snippet code/src_widgets_widgets_qmainwindow.cpp 2
1142
1143 If the blue and the yellow widget are nested on the same level they will be
1144 resized such that the yellowWidget is twice as big as the blueWidget
1145
1146 If some widgets are grouped in tabs, only one widget per group should be
1147 specified. Widgets not in the list might be changed to respect the constraints.
1148*/
1149void QMainWindow::resizeDocks(const QList<QDockWidget *> &docks,
1150 const QList<int> &sizes, Qt::Orientation orientation)
1151{
1152 d_func()->layout->layoutState.dockAreaLayout.resizeDocks(docks, sizes, orientation);
1153 d_func()->layout->invalidate();
1154}
1155
1156
1157#endif // QT_CONFIG(dockwidget)
1158
1159/*!
1160 Saves the current state of this mainwindow's toolbars and
1161 dockwidgets. This includes the corner settings which can
1162 be set with setCorner(). The \a version number is stored
1163 as part of the data.
1164
1165 The \l{QObject::objectName}{objectName} property is used
1166 to identify each QToolBar and QDockWidget. You should make sure
1167 that this property is unique for each QToolBar and QDockWidget you
1168 add to the QMainWindow
1169
1170 To restore the saved state, pass the return value and \a version
1171 number to restoreState().
1172
1173 To save the geometry when the window closes, you can
1174 implement a close event like this:
1175
1176 \snippet code/src_gui_widgets_qmainwindow.cpp 0
1177
1178 \sa restoreState(), QWidget::saveGeometry(), QWidget::restoreGeometry()
1179*/
1180QByteArray QMainWindow::saveState(int version) const
1181{
1182 QByteArray data;
1183 QDataStream stream(&data, QIODevice::WriteOnly);
1184 stream.setVersion(QDataStream::Qt_5_0);
1185 stream << QMainWindowLayout::VersionMarker;
1186 stream << version;
1187 d_func()->layout->saveState(stream);
1188 return data;
1189}
1190
1191/*!
1192 Restores the \a state of this mainwindow's toolbars and
1193 dockwidgets. Also restores the corner settings too. The
1194 \a version number is compared with that stored in \a state.
1195 If they do not match, the mainwindow's state is left
1196 unchanged, and this function returns \c false; otherwise, the state
1197 is restored, and this function returns \c true.
1198
1199 To restore geometry saved using QSettings, you can use code like
1200 this:
1201
1202 \snippet code/src_gui_widgets_qmainwindow.cpp 1
1203
1204 \sa saveState(), QWidget::saveGeometry(),
1205 QWidget::restoreGeometry(), restoreDockWidget()
1206*/
1207bool QMainWindow::restoreState(const QByteArray &state, int version)
1208{
1209 if (state.isEmpty())
1210 return false;
1211 QByteArray sd = state;
1212 QDataStream stream(&sd, QIODevice::ReadOnly);
1213 stream.setVersion(QDataStream::Qt_5_0);
1214 int marker, v;
1215 stream >> marker;
1216 stream >> v;
1217 if (stream.status() != QDataStream::Ok || marker != QMainWindowLayout::VersionMarker || v != version)
1218 return false;
1219 bool restored = d_func()->layout->restoreState(stream);
1220 return restored;
1221}
1222
1223/*! \reimp */
1224bool QMainWindow::event(QEvent *event)
1225{
1226 Q_D(QMainWindow);
1227
1228#if QT_CONFIG(dockwidget)
1229 if (d->layout && d->layout->windowEvent(event))
1230 return true;
1231#endif
1232
1233 switch (event->type()) {
1234
1235#if QT_CONFIG(toolbar)
1236 case QEvent::ToolBarChange: {
1237 Q_ASSERT(d->layout);
1238 d->layout->toggleToolBarsVisible();
1239 return true;
1240 }
1241#endif
1242
1243#if QT_CONFIG(statustip)
1244 case QEvent::StatusTip:
1245#if QT_CONFIG(statusbar)
1246 Q_ASSERT(d->layout);
1247 if (QStatusBar *sb = d->layout->statusBar())
1248 sb->showMessage(static_cast<QStatusTipEvent*>(event)->tip());
1249 else
1250#endif
1251 static_cast<QStatusTipEvent*>(event)->ignore();
1252 return true;
1253#endif // QT_CONFIG(statustip)
1254
1255 case QEvent::StyleChange:
1256#if QT_CONFIG(dockwidget)
1257 Q_ASSERT(d->layout);
1258 d->layout->layoutState.dockAreaLayout.styleChangedEvent();
1259#endif
1260 if (!d->explicitIconSize)
1261 setIconSize(QSize());
1262 break;
1263#if QT_CONFIG(draganddrop)
1264 case QEvent::DragEnter:
1265 case QEvent::Drop:
1266 if (!d->layout->draggingWidget)
1267 break;
1268 event->accept();
1269 return true;
1270 case QEvent::DragMove: {
1271 if (!d->layout->draggingWidget)
1272 break;
1273 auto dragMoveEvent = static_cast<QDragMoveEvent *>(event);
1274 d->layout->hover(d->layout->draggingWidget,
1275 mapToGlobal(dragMoveEvent->position()).toPoint());
1276 event->accept();
1277 return true;
1278 }
1279 case QEvent::DragLeave:
1280 if (!d->layout->draggingWidget)
1281 break;
1282 d->layout->hover(d->layout->draggingWidget, pos() - QPoint(1, 1));
1283 return true;
1284#endif
1285 default:
1286 break;
1287 }
1288
1289 return QWidget::event(event);
1290}
1291
1292#if QT_CONFIG(toolbar)
1293
1294/*!
1295 \property QMainWindow::unifiedTitleAndToolBarOnMac
1296 \brief whether the window uses the unified title and toolbar look on \macos
1297
1298 Note that the Qt 5 implementation has several limitations compared to Qt 4:
1299 \list
1300 \li Use in windows with OpenGL content is not supported. This includes QOpenGLWidget.
1301 \li Using dockable or movable toolbars may result in painting errors and is not recommended
1302 \endlist
1303
1304 \since 5.2
1305*/
1306void QMainWindow::setUnifiedTitleAndToolBarOnMac(bool enabled)
1307{
1308#ifdef Q_OS_MACOS
1309 if (!isWindow())
1310 return;
1311
1312 Q_D(QMainWindow);
1313 d->useUnifiedToolBar = enabled;
1314
1315 // The unified toolbar is drawn by the macOS style with a transparent background.
1316 // To ensure a suitable surface format is used we need to first create backing
1317 // QWindow so we have something to update the surface format on, and then let
1318 // QWidget know about the translucency, which it will propagate to the surface.
1319 setAttribute(Qt::WA_NativeWindow);
1320 setAttribute(Qt::WA_TranslucentBackground, enabled);
1321
1322 d->create(); // Create first, so we can update the window flag without hiding the window
1323
1324 auto *windowHandle = window()->windowHandle();
1325 windowHandle->setFlag(Qt::NoTitleBarBackgroundHint, enabled);
1326 // Expand client area if we need to manage a titlebar visual effects view ourselves
1327 if (QOperatingSystemVersion::current() < QOperatingSystemVersion::MacOSTahoe)
1328 windowHandle->setFlag(Qt::ExpandedClientAreaHint, enabled);
1329 overrideWindowFlags(windowHandle->flags());
1330
1331 d->layout->updateUnifiedToolBarArea();
1332
1333 update();
1334#else
1335 Q_UNUSED(enabled);
1336#endif
1337}
1338
1339bool QMainWindow::unifiedTitleAndToolBarOnMac() const
1340{
1341#ifdef Q_OS_MACOS
1342 return d_func()->useUnifiedToolBar;
1343#endif
1344 return false;
1345}
1346
1347#endif // QT_CONFIG(toolbar)
1348
1349/*!
1350 \internal
1351*/
1352bool QMainWindow::isSeparator(const QPoint &pos) const
1353{
1354#if QT_CONFIG(dockwidget)
1355 Q_D(const QMainWindow);
1356 return !d->layout->layoutState.dockAreaLayout.findSeparator(pos).isEmpty();
1357#else
1358 Q_UNUSED(pos);
1359 return false;
1360#endif
1361}
1362
1363#ifndef QT_NO_CONTEXTMENU
1364/*!
1365 \reimp
1366*/
1367void QMainWindow::contextMenuEvent(QContextMenuEvent *event)
1368{
1369 event->ignore();
1370 // only show the context menu for direct QDockWidget and QToolBar
1371 // children and for the menu bar as well
1372 QWidget *child = childAt(event->pos());
1373 while (child && child != this) {
1374#if QT_CONFIG(menubar)
1375 if (QMenuBar *mb = qobject_cast<QMenuBar *>(child)) {
1376 if (mb->parentWidget() != this)
1377 return;
1378 break;
1379 }
1380#endif
1381#if QT_CONFIG(dockwidget)
1382 if (QDockWidget *dw = qobject_cast<QDockWidget *>(child)) {
1383 if (dw->parentWidget() != this)
1384 return;
1385 if (dw->widget()
1386 && dw->widget()->geometry().contains(child->mapFrom(this, event->pos()))) {
1387 // ignore the event if the mouse is over the QDockWidget contents
1388 return;
1389 }
1390 break;
1391 }
1392#endif // QT_CONFIG(dockwidget)
1393#if QT_CONFIG(toolbar)
1394 if (QToolBar *tb = qobject_cast<QToolBar *>(child)) {
1395 if (tb->parentWidget() != this)
1396 return;
1397 break;
1398 }
1399#endif
1400 child = child->parentWidget();
1401 }
1402 if (child == this)
1403 return;
1404
1405#if QT_CONFIG(menu)
1406 QMenu *popup = createPopupMenu();
1407 if (popup) {
1408 if (!popup->isEmpty()) {
1409 popup->setAttribute(Qt::WA_DeleteOnClose);
1410 popup->popup(event->globalPos());
1411 event->accept();
1412 } else {
1413 delete popup;
1414 }
1415 }
1416#endif
1417}
1418#endif // QT_NO_CONTEXTMENU
1419
1420#if QT_CONFIG(menu)
1421/*!
1422 Returns a popup menu containing checkable entries for the toolbars and
1423 dock widgets present in the main window. If there are no toolbars and
1424 dock widgets present, this function returns \nullptr.
1425
1426 By default, this function is called by the main window when the user
1427 activates a context menu, typically by right-clicking on a toolbar or a dock
1428 widget.
1429
1430 If you want to create a custom popup menu, reimplement this function and
1431 return a newly-created popup menu. Ownership of the popup menu is transferred
1432 to the caller.
1433
1434 \sa addDockWidget(), addToolBar(), menuBar()
1435*/
1436QMenu *QMainWindow::createPopupMenu()
1437{
1438 Q_D(QMainWindow);
1439 QMenu *menu = nullptr;
1440#if QT_CONFIG(dockwidget)
1441 QList<QDockWidget *> dockwidgets = findChildren<QDockWidget *>();
1442 if (dockwidgets.size()) {
1443 menu = new QMenu(this);
1444 for (int i = 0; i < dockwidgets.size(); ++i) {
1445 QDockWidget *dockWidget = dockwidgets.at(i);
1446 // filter to find out if we own this QDockWidget
1447 if (dockWidget->parentWidget() == this) {
1448 if (d->layout->layoutState.dockAreaLayout.indexOf(dockWidget).isEmpty())
1449 continue;
1450 } else if (QDockWidgetGroupWindow *dwgw =
1451 qobject_cast<QDockWidgetGroupWindow *>(dockWidget->parentWidget())) {
1452 if (dwgw->parentWidget() != this)
1453 continue;
1454 if (dwgw->layoutInfo()->indexOf(dockWidget).isEmpty())
1455 continue;
1456 } else {
1457 continue;
1458 }
1459 menu->addAction(dockwidgets.at(i)->toggleViewAction());
1460 }
1461 menu->addSeparator();
1462 }
1463#endif // QT_CONFIG(dockwidget)
1464#if QT_CONFIG(toolbar)
1465 QList<QToolBar *> toolbars = findChildren<QToolBar *>();
1466 if (toolbars.size()) {
1467 if (!menu)
1468 menu = new QMenu(this);
1469 for (int i = 0; i < toolbars.size(); ++i) {
1470 QToolBar *toolBar = toolbars.at(i);
1471 if (toolBar->parentWidget() == this
1472 && (!d->layout->layoutState.toolBarAreaLayout.indexOf(toolBar).isEmpty())) {
1473 menu->addAction(toolbars.at(i)->toggleViewAction());
1474 }
1475 }
1476 }
1477#endif
1478 Q_UNUSED(d);
1479 return menu;
1480}
1481#endif // QT_CONFIG(menu)
1482
1483QT_END_NAMESPACE
1484
1485#include "moc_qmainwindow.cpp"
Qt::ToolButtonStyle toolButtonStyle
static QMainWindowLayout * mainWindowLayout(const QMainWindow *mainWindow)
Combined button and popup list for selecting options.
QMainWindowLayout * qt_mainwindow_layout(const QMainWindow *mainWindow)