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
qstatusbar.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
"qstatusbar.h"
6
7
#
include
"qlist.h"
8
#
include
"qdebug.h"
9
#
include
"qevent.h"
10
#
include
"qlayout.h"
11
#
include
"qpainter.h"
12
#
include
"qtimer.h"
13
#
include
"qstyle.h"
14
#
include
"qstyleoption.h"
15
#
if
QT_CONFIG
(
sizegrip
)
16
#
include
"qsizegrip.h"
17
#
endif
18
#
if
QT_CONFIG
(
mainwindow
)
19
#
include
"qmainwindow.h"
20
#
endif
21
22
#
if
QT_CONFIG
(
accessibility
)
23
#
include
"qaccessible.h"
24
#
endif
25
26
#
include
<
private
/
qlayoutengine_p
.
h
>
27
#
include
<
private
/
qwidget_p
.
h
>
28
29
QT_BEGIN_NAMESPACE
30
31
class
QStatusBarPrivate
:
public
QWidgetPrivate
32
{
33
Q_DECLARE_PUBLIC(QStatusBar)
34
public
:
35
QStatusBarPrivate
() {}
36
37
enum
ItemCategory
38
{
39
Normal
,
40
Permanent
41
};
42
43
struct
SBItem
{
44
QWidget
*
widget
=
nullptr
;
45
int
stretch
= 0;
46
ItemCategory
category
=
Normal
;
47
bool
isPermanent
()
const
{
return
category == Permanent; }
48
};
49
50
QList
<
SBItem
>
items
;
51
QString
tempItem
;
52
53
QBoxLayout
*
box
;
54
QTimer
*
timer
;
55
56
#
if
QT_CONFIG
(
sizegrip
)
57
QSizeGrip
*
resizer
;
58
bool
showSizeGrip
;
59
#
endif
60
61
int
savedStrut
;
62
63
int
indexToLastNonPermanentWidget
()
const
64
{
65
int
i = items.size() - 1;
66
for
(; i >= 0; --i) {
67
const
SBItem
&item = items.at(i);
68
if
(!item
.
isPermanent
(
)
)
69
break
;
70
}
71
return
i;
72
}
73
74
#
if
QT_CONFIG
(
sizegrip
)
75
void
tryToShowSizeGrip
()
76
{
77
if
(!
showSizeGrip
)
78
return
;
79
showSizeGrip
=
false
;
80
if
(!
resizer
||
resizer
->
isVisible
())
81
return
;
82
resizer
->
setAttribute
(
Qt
::
WA_WState_ExplicitShowHide
,
false
);
83
QMetaObject
::
invokeMethod
(
resizer
,
"_q_showIfNotHidden"
,
Qt
::
DirectConnection
);
84
resizer
->
setAttribute
(
Qt
::
WA_WState_ExplicitShowHide
,
false
);
85
}
86
#
endif
87
88
QRect
messageRect
()
const
;
89
};
90
91
92
QRect
QStatusBarPrivate
::
messageRect
()
const
93
{
94
Q_Q(
const
QStatusBar);
95
const
bool
rtl = q->layoutDirection() == Qt::RightToLeft;
96
97
int
left = 6;
98
int
right = q->width() - 12;
99
100
#
if
QT_CONFIG
(
sizegrip
)
101
if
(resizer && resizer->isVisible()) {
102
if
(rtl)
103
left = resizer->x() + resizer->width();
104
else
105
right = resizer->x();
106
}
107
#
endif
108
109
for
(
const
auto
&item : items) {
110
if
(item.isPermanent() && item.widget->isVisible()) {
111
if
(rtl)
112
left = qMax(left, item.widget->x() + item.widget->width() + 2);
113
else
114
right = qMin(right, item.widget->x() - 2);
115
break
;
116
}
117
}
118
return
QRect(left, 0, right-left, q->height());
119
}
120
121
122
/*!
123
\class QStatusBar
124
\brief The QStatusBar class provides a horizontal bar suitable for
125
presenting status information.
126
127
\ingroup mainwindow-classes
128
\ingroup helpsystem
129
\inmodule QtWidgets
130
131
Each status indicator falls into one of three categories:
132
133
\list
134
\li \e Temporary - briefly occupies most of the status bar. Used
135
to explain tool tip texts or menu entries, for example.
136
\li \e Normal - occupies part of the status bar and may be hidden
137
by temporary messages. Used to display the page and line
138
number in a word processor, for example.
139
\li \e Permanent - is never hidden. Used for important mode
140
indications, for example, some applications put a Caps Lock
141
indicator in the status bar.
142
\endlist
143
144
QStatusBar lets you display all three types of indicators.
145
146
Typically, a request for the status bar functionality occurs in
147
relation to a QMainWindow object. QMainWindow provides a main
148
application window, with a menu bar, tool bars, dock widgets \e
149
and a status bar around a large central widget. The status bar can
150
be retrieved using the QMainWindow::statusBar() function, and
151
replaced using the QMainWindow::setStatusBar() function.
152
153
Use the showMessage() slot to display a \e temporary message:
154
155
\snippet code/src_gui_widgets_qstatusbar.cpp 1
156
157
To remove a temporary message, use the clearMessage() slot, or set
158
a time limit when calling showMessage(). For example:
159
160
\snippet code/src_gui_widgets_qstatusbar.cpp 2
161
162
Use the currentMessage() function to retrieve the temporary
163
message currently shown. The QStatusBar class also provide the
164
messageChanged() signal which is emitted whenever the temporary
165
status message changes.
166
167
\target permanent message
168
\e Normal and \e Permanent messages are displayed by creating a
169
small widget (QLabel, QProgressBar or even QToolButton) and then
170
adding it to the status bar using the addWidget() or the
171
addPermanentWidget() function. Use the removeWidget() function to
172
remove such messages from the status bar.
173
174
\snippet code/src_gui_widgets_qstatusbar.cpp 0
175
176
By default QStatusBar provides a QSizeGrip in the lower-right
177
corner. You can disable it using the setSizeGripEnabled()
178
function. Use the isSizeGripEnabled() function to determine the
179
current status of the size grip.
180
181
\image fusion-statusbar-sizegrip.png A status bar shown in the Fusion widget style
182
183
\sa QMainWindow, QStatusTipEvent
184
*/
185
186
187
/*!
188
Constructs a status bar with a size grip and the given \a parent.
189
190
\sa setSizeGripEnabled()
191
*/
192
QStatusBar::QStatusBar(QWidget * parent)
193
: QWidget(*
new
QStatusBarPrivate, parent, { })
194
{
195
Q_D(QStatusBar);
196
d->box =
nullptr
;
197
d->timer =
nullptr
;
198
199
#
if
QT_CONFIG
(
sizegrip
)
200
d->resizer =
nullptr
;
201
setSizeGripEnabled(
true
);
// causes reformat()
202
#
else
203
reformat();
204
#
endif
205
}
206
207
/*!
208
Destroys this status bar and frees any allocated resources and
209
child widgets.
210
*/
211
QStatusBar::~QStatusBar()
212
{
213
}
214
215
216
/*!
217
Adds the given \a widget to this status bar, reparenting the
218
widget if it isn't already a child of this QStatusBar object. The
219
\a stretch parameter is used to compute a suitable size for the
220
given \a widget as the status bar grows and shrinks. The default
221
stretch factor is 0, i.e giving the widget a minimum of space.
222
223
The widget is located to the far left of the first permanent
224
widget (see addPermanentWidget()) and may be obscured by temporary
225
messages.
226
227
\sa insertWidget(), removeWidget(), addPermanentWidget()
228
*/
229
230
void
QStatusBar::addWidget(QWidget * widget,
int
stretch)
231
{
232
if
(!widget)
233
return
;
234
insertWidget(d_func()->indexToLastNonPermanentWidget() + 1, widget, stretch);
235
}
236
237
/*!
238
\since 4.2
239
240
Inserts the given \a widget at the given \a index to this status bar,
241
reparenting the widget if it isn't already a child of this
242
QStatusBar object. If \a index is out of range, the widget is appended
243
(in which case it is the actual index of the widget that is returned).
244
245
The \a stretch parameter is used to compute a suitable size for
246
the given \a widget as the status bar grows and shrinks. The
247
default stretch factor is 0, i.e giving the widget a minimum of
248
space.
249
250
The widget is located to the far left of the first permanent
251
widget (see addPermanentWidget()) and may be obscured by temporary
252
messages.
253
254
\sa addWidget(), removeWidget(), addPermanentWidget()
255
*/
256
int
QStatusBar::insertWidget(
int
index, QWidget *widget,
int
stretch)
257
{
258
if
(!widget)
259
return
-1;
260
261
Q_D(QStatusBar);
262
QStatusBarPrivate::SBItem item{widget, stretch, QStatusBarPrivate::Normal};
263
264
int
idx = d->indexToLastNonPermanentWidget();
265
if
(Q_UNLIKELY(index < 0 || index > d->items.size() || (idx >= 0 && index > idx + 1))) {
266
qWarning(
"QStatusBar::insertWidget: Index out of range (%d), appending widget"
, index);
267
index = idx + 1;
268
}
269
d->items.insert(index, item);
270
271
if
(!d->tempItem.isEmpty())
272
widget->hide();
273
274
reformat();
275
if
(!QWidgetPrivate::get(widget)->isExplicitlyHidden())
276
widget->show();
277
278
return
index;
279
}
280
281
/*!
282
Adds the given \a widget permanently to this status bar,
283
reparenting the widget if it isn't already a child of this
284
QStatusBar object. The \a stretch parameter is used to compute a
285
suitable size for the given \a widget as the status bar grows and
286
shrinks. The default stretch factor is 0, i.e giving the widget a
287
minimum of space.
288
289
Permanently means that the widget may not be obscured by temporary
290
messages. It is located at the far right of the status bar.
291
292
\sa insertPermanentWidget(), removeWidget(), addWidget()
293
*/
294
295
void
QStatusBar::addPermanentWidget(QWidget * widget,
int
stretch)
296
{
297
if
(!widget)
298
return
;
299
insertPermanentWidget(d_func()->items.size(), widget, stretch);
300
}
301
302
/*!
303
\since 4.2
304
305
Inserts the given \a widget at the given \a index permanently to this status bar,
306
reparenting the widget if it isn't already a child of this
307
QStatusBar object. If \a index is out of range, the widget is appended
308
(in which case it is the actual index of the widget that is returned).
309
310
The \a stretch parameter is used to compute a
311
suitable size for the given \a widget as the status bar grows and
312
shrinks. The default stretch factor is 0, i.e giving the widget a
313
minimum of space.
314
315
Permanently means that the widget may not be obscured by temporary
316
messages. It is located at the far right of the status bar.
317
318
\sa addPermanentWidget(), removeWidget(), addWidget()
319
*/
320
int
QStatusBar::insertPermanentWidget(
int
index, QWidget *widget,
int
stretch)
321
{
322
if
(!widget)
323
return
-1;
324
325
Q_D(QStatusBar);
326
QStatusBarPrivate::SBItem item{widget, stretch, QStatusBarPrivate::Permanent};
327
328
int
idx = d->indexToLastNonPermanentWidget();
329
if
(Q_UNLIKELY(index < 0 || index > d->items.size() || (idx >= 0 && index <= idx))) {
330
qWarning(
"QStatusBar::insertPermanentWidget: Index out of range (%d), appending widget"
, index);
331
index = d->items.size();
332
}
333
d->items.insert(index, item);
334
335
reformat();
336
if
(!QWidgetPrivate::get(widget)->isExplicitlyHidden())
337
widget->show();
338
339
return
index;
340
}
341
342
/*!
343
Removes the specified \a widget from the status bar.
344
345
\note This function does not delete the widget but \e hides it.
346
To add the widget again, you must call both the addWidget() and
347
show() functions.
348
349
\sa addWidget(), addPermanentWidget(), clearMessage()
350
*/
351
352
void
QStatusBar::removeWidget(QWidget *widget)
353
{
354
if
(!widget)
355
return
;
356
357
Q_D(QStatusBar);
358
if
(d->items.removeIf([widget](
const
auto
&item) {
return
item.widget == widget; })) {
359
widget->hide();
360
reformat();
361
}
362
#
if
defined
(
QT_DEBUG
)
363
else
364
qDebug(
"QStatusBar::removeWidget(): Widget not found."
);
365
#
endif
366
}
367
368
/*!
369
\property QStatusBar::sizeGripEnabled
370
371
\brief whether the QSizeGrip in the bottom-right corner of the
372
status bar is enabled
373
374
The size grip is enabled by default.
375
*/
376
377
bool
QStatusBar::isSizeGripEnabled()
const
378
{
379
#
if
!
QT_CONFIG
(
sizegrip
)
380
return
false
;
381
#
else
382
Q_D(
const
QStatusBar);
383
return
!!d->resizer;
384
#
endif
385
}
386
387
void
QStatusBar::setSizeGripEnabled(
bool
enabled)
388
{
389
#
if
!
QT_CONFIG
(
sizegrip
)
390
Q_UNUSED(enabled);
391
#
else
392
Q_D(QStatusBar);
393
if
(!enabled != !d->resizer) {
394
if
(enabled) {
395
d->resizer =
new
QSizeGrip(
this
);
396
d->resizer->hide();
397
d->resizer->installEventFilter(
this
);
398
d->showSizeGrip =
true
;
399
}
else
{
400
delete
d->resizer;
401
d->resizer =
nullptr
;
402
d->showSizeGrip =
false
;
403
}
404
reformat();
405
if
(d->resizer && isVisible())
406
d->tryToShowSizeGrip();
407
}
408
#
endif
409
}
410
411
412
/*!
413
Changes the status bar's appearance to account for item changes.
414
415
Special subclasses may need this function, but geometry management
416
will usually take care of any necessary rearrangements.
417
*/
418
void
QStatusBar::reformat()
419
{
420
Q_D(QStatusBar);
421
if
(d->box)
422
delete
d->box;
423
424
QBoxLayout *vbox;
425
#
if
QT_CONFIG
(
sizegrip
)
426
if
(d->resizer) {
427
d->box =
new
QHBoxLayout(
this
);
428
d->box->setContentsMargins(QMargins());
429
vbox =
new
QVBoxLayout;
430
d->box->addLayout(vbox);
431
}
else
432
#
endif
433
{
434
vbox = d->box =
new
QVBoxLayout(
this
);
435
d->box->setContentsMargins(QMargins());
436
}
437
vbox->addSpacing(3);
438
QBoxLayout* l =
new
QHBoxLayout;
439
vbox->addLayout(l);
440
l->addSpacing(2);
441
l->setSpacing(6);
442
443
int
maxH = fontMetrics().height();
444
445
qsizetype i;
446
for
(i = 0; i < d->items.size(); ++i) {
447
const
auto
&item = d->items.at(i);
448
if
(item.isPermanent())
449
break
;
450
l->addWidget(item.widget, item.stretch);
451
int
itemH = qMin(qSmartMinSize(item.widget).height(), item.widget->maximumHeight());
452
maxH = qMax(maxH, itemH);
453
}
454
455
l->addStretch(0);
456
457
for
(; i < d->items.size(); ++i) {
458
const
auto
&item = d->items.at(i);
459
l->addWidget(item.widget, item.stretch);
460
int
itemH = qMin(qSmartMinSize(item.widget).height(), item.widget->maximumHeight());
461
maxH = qMax(maxH, itemH);
462
}
463
#
if
QT_CONFIG
(
sizegrip
)
464
if
(d->resizer) {
465
maxH = qMax(maxH, d->resizer->sizeHint().height());
466
d->box->addSpacing(1);
467
d->box->addWidget(d->resizer, 0, Qt::AlignBottom);
468
}
469
#
endif
470
l->addStrut(maxH);
471
d->savedStrut = maxH;
472
vbox->addSpacing(2);
473
d->box->activate();
474
update();
475
}
476
477
/*!
478
479
Hides the normal status indications and displays the given \a
480
message for the specified number of milli-seconds (\a{timeout}). If
481
\a{timeout} is 0 (default), the \a {message} remains displayed until
482
the clearMessage() slot is called or until the showMessage() slot is
483
called again to change the message.
484
485
Note that showMessage() is called to show temporary explanations of
486
tool tip texts, so passing a \a{timeout} of 0 is not sufficient to
487
display a \l{permanent message}{permanent message}.
488
489
\sa messageChanged(), currentMessage(), clearMessage()
490
*/
491
void
QStatusBar::showMessage(
const
QString &message,
int
timeout)
492
{
493
Q_D(QStatusBar);
494
495
if
(timeout > 0) {
496
if
(!d->timer) {
497
d->timer =
new
QTimer(
this
);
498
connect(d->timer, &QTimer::timeout,
this
, &QStatusBar::clearMessage);
499
}
500
d->timer->start(timeout);
501
}
else
if
(d->timer) {
502
delete
d->timer;
503
d->timer =
nullptr
;
504
}
505
if
(d->tempItem == message)
506
return
;
507
d->tempItem = message;
508
509
hideOrShow();
510
}
511
512
/*!
513
Removes any temporary message being shown.
514
515
\sa currentMessage(), showMessage(), removeWidget()
516
*/
517
518
void
QStatusBar::clearMessage()
519
{
520
Q_D(QStatusBar);
521
if
(d->tempItem.isEmpty())
522
return
;
523
if
(d->timer) {
524
delete
d->timer;
525
d->timer =
nullptr
;
526
}
527
d->tempItem.clear();
528
hideOrShow();
529
}
530
531
/*!
532
Returns the temporary message currently shown,
533
or an empty string if there is no such message.
534
535
\sa showMessage()
536
*/
537
QString QStatusBar::currentMessage()
const
538
{
539
Q_D(
const
QStatusBar);
540
return
d->tempItem;
541
}
542
543
/*!
544
\fn void QStatusBar::messageChanged(const QString &message)
545
546
This signal is emitted whenever the temporary status message
547
changes. The new temporary message is passed in the \a message
548
parameter which is a null-string when the message has been
549
removed.
550
551
\sa showMessage(), clearMessage()
552
*/
553
554
/*!
555
Ensures that the right widgets are visible.
556
557
Used by the showMessage() and clearMessage() functions.
558
*/
559
void
QStatusBar::hideOrShow()
560
{
561
Q_D(QStatusBar);
562
bool
haveMessage = !d->tempItem.isEmpty();
563
564
for
(
const
auto
&item : std::as_const(d->items)) {
565
if
(item.isPermanent())
566
break
;
567
if
(haveMessage && item.widget->isVisible()) {
568
item.widget->hide();
569
item.widget->setAttribute(Qt::WA_WState_ExplicitShowHide,
false
);
570
}
else
if
(!haveMessage && !item.widget->testAttribute(Qt::WA_WState_ExplicitShowHide)) {
571
item.widget->show();
572
}
573
}
574
575
emit messageChanged(d->tempItem);
576
577
#
if
QT_CONFIG
(
accessibility
)
578
if
(QAccessible::isActive()) {
579
QAccessibleEvent event(
this
, QAccessible::NameChanged);
580
QAccessible::updateAccessibility(&event);
581
}
582
#
endif
583
584
update(d->messageRect());
585
}
586
587
/*!
588
\reimp
589
*/
590
void
QStatusBar::showEvent(QShowEvent *)
591
{
592
#
if
QT_CONFIG
(
sizegrip
)
593
Q_D(QStatusBar);
594
if
(d->resizer && d->showSizeGrip)
595
d->tryToShowSizeGrip();
596
#
endif
597
}
598
599
/*!
600
\reimp
601
\fn void QStatusBar::paintEvent(QPaintEvent *event)
602
603
Shows the temporary message, if appropriate, in response to the
604
paint \a event.
605
*/
606
void
QStatusBar::paintEvent(QPaintEvent *event)
607
{
608
Q_D(QStatusBar);
609
bool
haveMessage = !d->tempItem.isEmpty();
610
611
QPainter p(
this
);
612
QStyleOption opt;
613
opt.initFrom(
this
);
614
style()->drawPrimitive(QStyle::PE_PanelStatusBar, &opt, &p,
this
);
615
616
for
(
const
auto
&item : std::as_const(d->items)) {
617
if
(item.widget->isVisible() && (!haveMessage || item.isPermanent())) {
618
QRect ir = item.widget->geometry().adjusted(-2, -1, 2, 1);
619
if
(event->rect().intersects(ir)) {
620
QStyleOption opt(0);
621
opt.rect = ir;
622
opt.palette = palette();
623
opt.state = QStyle::State_None;
624
style()->drawPrimitive(QStyle::PE_FrameStatusBarItem, &opt, &p, item.widget);
625
}
626
}
627
}
628
if
(haveMessage) {
629
p.setPen(palette().windowText().color());
630
p.drawText(d->messageRect(), Qt::AlignLeading | Qt::AlignVCenter | Qt::TextSingleLine, d->tempItem);
631
}
632
}
633
634
/*!
635
\reimp
636
*/
637
void
QStatusBar::resizeEvent(QResizeEvent * e)
638
{
639
QWidget::resizeEvent(e);
640
}
641
642
/*!
643
\reimp
644
*/
645
646
bool
QStatusBar::event(QEvent *e)
647
{
648
Q_D(QStatusBar);
649
650
switch
(e->type()) {
651
case
QEvent::LayoutRequest: {
652
// Calculate new strut height and call reformat() if it has changed
653
int
maxH = fontMetrics().height();
654
655
for
(
const
auto
&item : std::as_const(d->items)) {
656
const
int
itemH = qMin(qSmartMinSize(item.widget).height(), item.widget->maximumHeight());
657
maxH = qMax(maxH, itemH);
658
}
659
660
#
if
QT_CONFIG
(
sizegrip
)
661
if
(d->resizer)
662
maxH = qMax(maxH, d->resizer->sizeHint().height());
663
#
endif
664
665
if
(maxH != d->savedStrut)
666
reformat();
667
else
668
update();
669
break
;
670
}
671
case
QEvent::ChildRemoved:
672
for
(
int
i = 0; i < d->items.size(); ++i) {
673
const
auto
&item = d->items.at(i);
674
if
(item.widget ==
static_cast
<QChildEvent *>(e)->child())
675
d->items.removeAt(i);
676
}
677
break
;
678
default
:
679
break
;
680
}
681
682
return
QWidget::event(e);
683
}
684
685
QT_END_NAMESPACE
686
687
#
include
"moc_qstatusbar.cpp"
QList
Definition
qlist.h:82
QPainter::QWidget
friend class QWidget
Definition
qpainter.h:432
QStatusBarPrivate
Definition
qstatusbar.cpp:32
QStatusBarPrivate::messageRect
QRect messageRect() const
Definition
qstatusbar.cpp:92
QStatusBarPrivate::indexToLastNonPermanentWidget
int indexToLastNonPermanentWidget() const
Definition
qstatusbar.cpp:63
QStatusBarPrivate::timer
QTimer * timer
Definition
qstatusbar.cpp:54
QStatusBarPrivate::tempItem
QString tempItem
Definition
qstatusbar.cpp:51
QStatusBarPrivate::items
QList< SBItem > items
Definition
qstatusbar.cpp:50
QStatusBarPrivate::savedStrut
int savedStrut
Definition
qstatusbar.cpp:61
QStatusBarPrivate::box
QBoxLayout * box
Definition
qstatusbar.cpp:53
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qsequentialanimationgroup.cpp:47
QStatusBarPrivate::SBItem
Definition
qstatusbar.cpp:43
QStatusBarPrivate::SBItem::stretch
int stretch
Definition
qstatusbar.cpp:45
QStatusBarPrivate::SBItem::isPermanent
bool isPermanent() const
Definition
qstatusbar.cpp:47
QStatusBarPrivate::SBItem::category
ItemCategory category
Definition
qstatusbar.cpp:46
QStatusBarPrivate::SBItem::widget
QWidget * widget
Definition
qstatusbar.cpp:44
qtbase
src
widgets
widgets
qstatusbar.cpp
Generated on
for Qt by
1.18.0