Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
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
4#include "qstatusbar.h"
5
6#include "qlist.h"
7#include "qdebug.h"
8#include "qevent.h"
9#include "qlayout.h"
10#include "qpainter.h"
11#include "qtimer.h"
12#include "qstyle.h"
13#include "qstyleoption.h"
14#if QT_CONFIG(sizegrip)
15#include "qsizegrip.h"
16#endif
17#if QT_CONFIG(mainwindow)
18#include "qmainwindow.h"
19#endif
20
21#if QT_CONFIG(accessibility)
22#include "qaccessible.h"
23#endif
24
25#include <private/qlayoutengine_p.h>
26#include <private/qwidget_p.h>
27
29
31{
32 Q_DECLARE_PUBLIC(QStatusBar)
33public:
35
41
42 struct SBItem {
43 QWidget *widget = nullptr;
44 int stretch = 0;
46 bool isPermanent() const { return category == Permanent; }
47 };
48
49 QList<SBItem> items;
51
54
55#if QT_CONFIG(sizegrip)
56 QSizeGrip *resizer;
57 bool showSizeGrip;
58#endif
59
61
63 {
64 int i = items.size() - 1;
65 for (; i >= 0; --i) {
66 const SBItem &item = items.at(i);
67 if (!item.isPermanent())
68 break;
69 }
70 return i;
71 }
72
73#if QT_CONFIG(sizegrip)
74 void tryToShowSizeGrip()
75 {
76 if (!showSizeGrip)
77 return;
78 showSizeGrip = false;
79 if (!resizer || resizer->isVisible())
80 return;
82 QMetaObject::invokeMethod(resizer, "_q_showIfNotHidden", Qt::DirectConnection);
84 }
85#endif
86
87 QRect messageRect() const;
88};
89
90
92{
93 Q_Q(const QStatusBar);
94 const bool rtl = q->layoutDirection() == Qt::RightToLeft;
95
96 int left = 6;
97 int right = q->width() - 12;
98
99#if QT_CONFIG(sizegrip)
100 if (resizer && resizer->isVisible()) {
101 if (rtl)
102 left = resizer->x() + resizer->width();
103 else
104 right = resizer->x();
105 }
106#endif
107
108 for (const auto &item : items) {
109 if (item.isPermanent() && item.widget->isVisible()) {
110 if (rtl)
111 left = qMax(left, item.widget->x() + item.widget->width() + 2);
112 else
113 right = qMin(right, item.widget->x() - 2);
114 break;
115 }
116 }
117 return QRect(left, 0, right-left, q->height());
118}
119
120
192 : QWidget(*new QStatusBarPrivate, parent, { })
193{
194 Q_D(QStatusBar);
195 d->box = nullptr;
196 d->timer = nullptr;
197
198#if QT_CONFIG(sizegrip)
199 d->resizer = nullptr;
200 setSizeGripEnabled(true); // causes reformat()
201#else
202 reformat();
203#endif
204}
205
213
214
230{
231 if (!widget)
232 return;
233 insertWidget(d_func()->indexToLastNonPermanentWidget() + 1, widget, stretch);
234}
235
256{
257 if (!widget)
258 return -1;
259
260 Q_D(QStatusBar);
262
263 int idx = d->indexToLastNonPermanentWidget();
264 if (Q_UNLIKELY(index < 0 || index > d->items.size() || (idx >= 0 && index > idx + 1))) {
265 qWarning("QStatusBar::insertWidget: Index out of range (%d), appending widget", index);
266 index = idx + 1;
267 }
268 d->items.insert(index, item);
269
270 if (!d->tempItem.isEmpty())
271 widget->hide();
272
273 reformat();
274 if (!QWidgetPrivate::get(widget)->isExplicitlyHidden())
275 widget->show();
276
277 return index;
278}
279
295{
296 if (!widget)
297 return;
298 insertPermanentWidget(d_func()->items.size(), widget, stretch);
299}
300
320{
321 if (!widget)
322 return -1;
323
324 Q_D(QStatusBar);
326
327 int idx = d->indexToLastNonPermanentWidget();
328 if (Q_UNLIKELY(index < 0 || index > d->items.size() || (idx >= 0 && index <= idx))) {
329 qWarning("QStatusBar::insertPermanentWidget: Index out of range (%d), appending widget", index);
330 index = d->items.size();
331 }
332 d->items.insert(index, item);
333
334 reformat();
335 if (!QWidgetPrivate::get(widget)->isExplicitlyHidden())
336 widget->show();
337
338 return index;
339}
340
352{
353 if (!widget)
354 return;
355
356 Q_D(QStatusBar);
357 if (d->items.removeIf([widget](const auto &item) { return item.widget == widget; })) {
358 widget->hide();
359 reformat();
360 }
361#if defined(QT_DEBUG)
362 else
363 qDebug("QStatusBar::removeWidget(): Widget not found.");
364#endif
365}
366
377{
378#if !QT_CONFIG(sizegrip)
379 return false;
380#else
381 Q_D(const QStatusBar);
382 return !!d->resizer;
383#endif
384}
385
387{
388#if !QT_CONFIG(sizegrip)
390#else
391 Q_D(QStatusBar);
392 if (!enabled != !d->resizer) {
393 if (enabled) {
394 d->resizer = new QSizeGrip(this);
395 d->resizer->hide();
396 d->resizer->installEventFilter(this);
397 d->showSizeGrip = true;
398 } else {
399 delete d->resizer;
400 d->resizer = nullptr;
401 d->showSizeGrip = false;
402 }
403 reformat();
404 if (d->resizer && isVisible())
405 d->tryToShowSizeGrip();
406 }
407#endif
408}
409
410
418{
419 Q_D(QStatusBar);
420 if (d->box)
421 delete d->box;
422
424#if QT_CONFIG(sizegrip)
425 if (d->resizer) {
426 d->box = new QHBoxLayout(this);
427 d->box->setContentsMargins(QMargins());
428 vbox = new QVBoxLayout;
429 d->box->addLayout(vbox);
430 } else
431#endif
432 {
433 vbox = d->box = new QVBoxLayout(this);
434 d->box->setContentsMargins(QMargins());
435 }
436 vbox->addSpacing(3);
437 QBoxLayout* l = new QHBoxLayout;
438 vbox->addLayout(l);
439 l->addSpacing(2);
440 l->setSpacing(6);
441
442 int maxH = fontMetrics().height();
443
444 qsizetype i;
445 for (i = 0; i < d->items.size(); ++i) {
446 const auto &item = d->items.at(i);
447 if (item.isPermanent())
448 break;
449 l->addWidget(item.widget, item.stretch);
450 int itemH = qMin(qSmartMinSize(item.widget).height(), item.widget->maximumHeight());
451 maxH = qMax(maxH, itemH);
452 }
453
454 l->addStretch(0);
455
456 for (; i < d->items.size(); ++i) {
457 const auto &item = d->items.at(i);
458 l->addWidget(item.widget, item.stretch);
459 int itemH = qMin(qSmartMinSize(item.widget).height(), item.widget->maximumHeight());
460 maxH = qMax(maxH, itemH);
461 }
462#if QT_CONFIG(sizegrip)
463 if (d->resizer) {
464 maxH = qMax(maxH, d->resizer->sizeHint().height());
465 d->box->addSpacing(1);
466 d->box->addWidget(d->resizer, 0, Qt::AlignBottom);
467 }
468#endif
469 l->addStrut(maxH);
470 d->savedStrut = maxH;
471 vbox->addSpacing(2);
472 d->box->activate();
473 update();
474}
475
491{
492 Q_D(QStatusBar);
493
494 if (timeout > 0) {
495 if (!d->timer) {
496 d->timer = new QTimer(this);
498 }
499 d->timer->start(timeout);
500 } else if (d->timer) {
501 delete d->timer;
502 d->timer = nullptr;
503 }
504 if (d->tempItem == message)
505 return;
506 d->tempItem = message;
507
508 hideOrShow();
509}
510
518{
519 Q_D(QStatusBar);
520 if (d->tempItem.isEmpty())
521 return;
522 if (d->timer) {
523 delete d->timer;
524 d->timer = nullptr;
525 }
526 d->tempItem.clear();
527 hideOrShow();
528}
529
537{
538 Q_D(const QStatusBar);
539 return d->tempItem;
540}
541
559{
560 Q_D(QStatusBar);
561 bool haveMessage = !d->tempItem.isEmpty();
562
563 for (const auto &item : std::as_const(d->items)) {
564 if (item.isPermanent())
565 break;
566 if (haveMessage && item.widget->isVisible()) {
567 item.widget->hide();
568 item.widget->setAttribute(Qt::WA_WState_ExplicitShowHide, false);
569 } else if (!haveMessage && !item.widget->testAttribute(Qt::WA_WState_ExplicitShowHide)) {
570 item.widget->show();
571 }
572 }
573
574 emit messageChanged(d->tempItem);
575
576#if QT_CONFIG(accessibility)
577 if (QAccessible::isActive()) {
578 QAccessibleEvent event(this, QAccessible::NameChanged);
579 QAccessible::updateAccessibility(&event);
580 }
581#endif
582
583 update(d->messageRect());
584}
585
590{
591#if QT_CONFIG(sizegrip)
592 Q_D(QStatusBar);
593 if (d->resizer && d->showSizeGrip)
594 d->tryToShowSizeGrip();
595#endif
596}
597
606{
607 Q_D(QStatusBar);
608 bool haveMessage = !d->tempItem.isEmpty();
609
610 QPainter p(this);
612 opt.initFrom(this);
614
615 for (const auto &item : std::as_const(d->items)) {
616 if (item.widget->isVisible() && (!haveMessage || item.isPermanent())) {
617 QRect ir = item.widget->geometry().adjusted(-2, -1, 2, 1);
618 if (event->rect().intersects(ir)) {
619 QStyleOption opt(0);
620 opt.rect = ir;
621 opt.palette = palette();
624 }
625 }
626 }
627 if (haveMessage) {
628 p.setPen(palette().windowText().color());
629 p.drawText(d->messageRect(), Qt::AlignLeading | Qt::AlignVCenter | Qt::TextSingleLine, d->tempItem);
630 }
631}
632
640
646{
647 Q_D(QStatusBar);
648
649 switch (e->type()) {
651 // Calculate new strut height and call reformat() if it has changed
652 int maxH = fontMetrics().height();
653
654 for (const auto &item : std::as_const(d->items)) {
655 const int itemH = qMin(qSmartMinSize(item.widget).height(), item.widget->maximumHeight());
656 maxH = qMax(maxH, itemH);
657 }
658
659#if QT_CONFIG(sizegrip)
660 if (d->resizer)
661 maxH = qMax(maxH, d->resizer->sizeHint().height());
662#endif
663
664 if (maxH != d->savedStrut)
665 reformat();
666 else
667 update();
668 break;
669 }
671 for (int i = 0; i < d->items.size(); ++i) {
672 const auto &item = d->items.at(i);
673 if (item.widget == static_cast<QChildEvent *>(e)->child())
674 d->items.removeAt(i);
675 }
676 break;
677 default:
678 break;
679 }
680
681 return QWidget::event(e);
682}
683
685
686#include "moc_qstatusbar.cpp"
The QBoxLayout class lines up child widgets horizontally or vertically.
Definition qboxlayout.h:21
void addWidget(QWidget *, int stretch=0, Qt::Alignment alignment=Qt::Alignment())
Adds widget to the end of this box layout, with a stretch factor of stretch and alignment alignment.
void addStrut(int)
Limits the perpendicular dimension of the box (e.g.
void addSpacing(int size)
Adds a non-stretchable space (a QSpacerItem) with size size to the end of this box layout.
void addStretch(int stretch=0)
Adds a stretchable space (a QSpacerItem) with zero minimum size and stretch factor stretch to the end...
void setSpacing(int spacing) override
Reimplements QLayout::setSpacing().
void addLayout(QLayout *layout, int stretch=0)
Adds layout to the end of the box, with serial stretch factor stretch.
\inmodule QtCore
Definition qcoreevent.h:379
QObject * child() const
Returns the child object that was added or removed.
Definition qcoreevent.h:384
\inmodule QtCore
Definition qcoreevent.h:45
@ ChildRemoved
Definition qcoreevent.h:108
@ LayoutRequest
Definition qcoreevent.h:112
Type type() const
Returns the event type.
Definition qcoreevent.h:304
int height() const
Returns the height of the font.
void show()
Shows the item (items are visible by default).
qreal x() const
This convenience function is equivalent to calling pos().x().
bool isVisible() const
Returns true if the item is visible; otherwise, false is returned.
void hide()
Hides the item (items are visible by default).
The QHBoxLayout class lines up widgets horizontally.
Definition qboxlayout.h:78
qsizetype size() const noexcept
Definition qlist.h:397
\inmodule QtCore
Definition qmargins.h:24
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
The QPaintEvent class contains event parameters for paint events.
Definition qevent.h:486
The QPainter class performs low-level painting on widgets and other paint devices.
Definition qpainter.h:46
\inmodule QtCore\reentrant
Definition qrect.h:30
The QResizeEvent class contains event parameters for resize events.
Definition qevent.h:548
The QShowEvent class provides an event that is sent when a widget is shown.
Definition qevent.h:578
The QSizeGrip class provides a resize handle for resizing top-level windows.
Definition qsizegrip.h:16
QList< SBItem > items
QRect messageRect() const
int indexToLastNonPermanentWidget() const
QBoxLayout * box
The QStatusBar class provides a horizontal bar suitable for presenting status information.
Definition qstatusbar.h:17
int insertWidget(int index, QWidget *widget, int stretch=0)
int insertPermanentWidget(int index, QWidget *widget, int stretch=0)
QStatusBar(QWidget *parent=nullptr)
Constructs a status bar with a size grip and the given parent.
void showMessage(const QString &text, int timeout=0)
Hides the normal status indications and displays the given message for the specified number of milli-...
void resizeEvent(QResizeEvent *) override
\reimp
QString currentMessage() const
Returns the temporary message currently shown, or an empty string if there is no such message.
void addWidget(QWidget *widget, int stretch=0)
Adds the given widget to this status bar, reparenting the widget if it isn't already a child of this ...
bool isSizeGripEnabled() const
void addPermanentWidget(QWidget *widget, int stretch=0)
Adds the given widget permanently to this status bar, reparenting the widget if it isn't already a ch...
void clearMessage()
Removes any temporary message being shown.
virtual ~QStatusBar()
Destroys this status bar and frees any allocated resources and child widgets.
void showEvent(QShowEvent *) override
\reimp
void messageChanged(const QString &text)
This signal is emitted whenever the temporary status message changes.
bool event(QEvent *) override
\reimp
void removeWidget(QWidget *widget)
Removes the specified widget from the status bar.
void setSizeGripEnabled(bool)
void reformat()
Changes the status bar's appearance to account for item changes.
void paintEvent(QPaintEvent *) override
\reimp
void hideOrShow()
Ensures that the right widgets are visible.
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
The QStyleOption class stores the parameters used by QStyle functions.
QStyle::State state
QPalette palette
void initFrom(const QWidget *w)
@ State_None
Definition qstyle.h:66
@ PE_PanelStatusBar
Definition qstyle.h:156
@ PE_FrameStatusBarItem
Definition qstyle.h:110
virtual void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p, const QWidget *w=nullptr) const =0
Draws the given primitive element with the provided painter using the style options specified by opti...
\inmodule QtCore
Definition qtimer.h:20
void timeout(QPrivateSignal)
This signal is emitted when the timer times out.
The QVBoxLayout class lines up widgets vertically.
Definition qboxlayout.h:91
static QWidgetPrivate * get(QWidget *w)
Definition qwidget_p.h:212
The QWidget class is the base class of all user interface objects.
Definition qwidget.h:99
void setAttribute(Qt::WidgetAttribute, bool on=true)
Sets the attribute attribute on this widget if on is true; otherwise clears the attribute.
QPalette palette
the widget's palette
Definition qwidget.h:132
int width
the width of the widget excluding any window frame
Definition qwidget.h:114
QFontMetrics fontMetrics() const
Returns the font metrics for the widget's current font.
Definition qwidget.h:847
void hide()
Hides the widget.
Definition qwidget.cpp:8135
void show()
Shows the widget and its child widgets.
Definition qwidget.cpp:7875
int x
the x coordinate of the widget relative to its parent including any window frame
Definition qwidget.h:109
void update()
Updates the widget unless updates are disabled or the widget is hidden.
bool event(QEvent *event) override
This is the main event handler; it handles event event.
Definition qwidget.cpp:8866
QStyle * style() const
Definition qwidget.cpp:2600
virtual void resizeEvent(QResizeEvent *event)
This event handler can be reimplemented in a subclass to receive widget resize events which are passe...
Definition qwidget.cpp:9822
bool isVisible() const
Definition qwidget.h:874
QOpenGLWidget * widget
[1]
QStyleOptionButton opt
Combined button and popup list for selecting options.
@ AlignLeading
Definition qnamespace.h:145
@ AlignBottom
Definition qnamespace.h:154
@ AlignVCenter
Definition qnamespace.h:155
@ WA_WState_ExplicitShowHide
Definition qnamespace.h:335
@ RightToLeft
@ TextSingleLine
Definition qnamespace.h:170
@ DirectConnection
#define Q_UNLIKELY(x)
Q_WIDGETS_EXPORT QSize qSmartMinSize(const QSize &sizeHint, const QSize &minSizeHint, const QSize &minSize, const QSize &maxSize, const QSizePolicy &sizePolicy)
#define qDebug
[1]
Definition qlogging.h:164
#define qWarning
Definition qlogging.h:166
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
GLuint index
[2]
GLbitfield GLuint64 timeout
[4]
GLdouble GLdouble right
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLuint color
[2]
GLint left
GLuint GLsizei const GLchar * message
struct _cl_event * event
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLfloat GLfloat p
[1]
#define emit
#define Q_UNUSED(x)
ptrdiff_t qsizetype
Definition qtypes.h:165
QGraphicsItem * item
QList< QTreeWidgetItem * > items
QVBoxLayout * vbox
static bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType, QGenericReturnArgument ret, QGenericArgument val0=QGenericArgument(nullptr), QGenericArgument val1=QGenericArgument(), QGenericArgument val2=QGenericArgument(), QGenericArgument val3=QGenericArgument(), QGenericArgument val4=QGenericArgument(), QGenericArgument val5=QGenericArgument(), QGenericArgument val6=QGenericArgument(), QGenericArgument val7=QGenericArgument(), QGenericArgument val8=QGenericArgument(), QGenericArgument val9=QGenericArgument())
\threadsafe This is an overloaded member function, provided for convenience. It differs from the abov...