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
qtoolbox.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 "qtoolbox.h"
5
6#include <qapplication.h>
7#include <qeventloop.h>
8#include <qlayout.h>
9#include <qlist.h>
10#include <qpainter.h>
11#include <qscrollarea.h>
12#include <qstyle.h>
13#include <qstyleoption.h>
14#if QT_CONFIG(tooltip)
15#include <qtooltip.h>
16#endif
17#include <qabstractbutton.h>
18
19#include "qframe_p.h"
20
22
23using namespace Qt::StringLiterals;
24
26{
28public:
36
37 inline void setSelected(bool b) { selected = b; update(); }
38 inline void setIndex(int newIndex) { indexInPage = newIndex; }
39
40 QSize sizeHint() const override;
41 QSize minimumSizeHint() const override;
42
43protected:
45 void paintEvent(QPaintEvent *) override;
46
47private:
48 bool selected;
49 int indexInPage;
50};
51
52
54{
55 Q_DECLARE_PUBLIC(QToolBox)
56public:
57 struct Page
58 {
62
63 inline void setText(const QString &text) { button->setText(text); }
64 inline void setIcon(const QIcon &is) { button->setIcon(is); }
65#if QT_CONFIG(tooltip)
66 inline void setToolTip(const QString &tip) { button->setToolTip(tip); }
67 inline QString toolTip() const { return button->toolTip(); }
68#endif
69 inline QString text() const { return button->text(); }
70 inline QIcon icon() const { return button->icon(); }
71
72 inline bool operator==(const Page& other) const
73 {
74 return widget == other.widget;
75 }
76 };
77 typedef std::vector<std::unique_ptr<Page>> PageList;
78
81 {
82 }
83 void _q_buttonClicked();
85
86 const Page *page(const QObject *widget) const;
87 const Page *page(int index) const;
88 Page *page(int index);
89
90 void updateTabs();
91 void relayout();
92
96};
97
99{
100 if (!widget)
101 return nullptr;
102
103 for (const auto &page : pageList) {
104 if (page->widget == widget)
105 return page.get();
106 }
107 return nullptr;
108}
109
111{
112 if (index >= 0 && index < static_cast<int>(pageList.size()))
113 return pageList[index].get();
114 return nullptr;
115}
116
118{
119 if (index >= 0 && index < static_cast<int>(pageList.size()))
120 return pageList[index].get();
121 return nullptr;
122}
123
125{
126 QToolBoxButton *lastButton = currentPage ? currentPage->button : nullptr;
127 bool after = false;
128 int index = 0;
129 for (const auto &page : pageList) {
130 QToolBoxButton *tB = page->button;
131 // update indexes, since the updates are delayed, the indexes will be correct
132 // when we actually paint.
133 tB->setIndex(index);
134 QWidget *tW = page->widget;
135 if (after) {
136 QPalette p = tB->palette();
137 p.setColor(tB->backgroundRole(), tW->palette().color(tW->backgroundRole()));
138 tB->setPalette(p);
139 tB->update();
140 } else if (tB->backgroundRole() != QPalette::Window) {
141 tB->setBackgroundRole(QPalette::Window);
142 tB->update();
143 }
144 after = tB == lastButton;
145 ++index;
146 }
147}
148
150{
151 QSize iconSize(8, 8);
152 if (!icon().isNull()) {
153 int icone = style()->pixelMetric(QStyle::PM_SmallIconSize, nullptr, parentWidget() /* QToolBox */);
154 iconSize += QSize(icone + 2, icone);
155 }
156 QSize textSize = fontMetrics().size(Qt::TextShowMnemonic, text()) + QSize(0, 8);
157
158 return QSize(iconSize.width() + textSize.width(), qMax(iconSize.height(), textSize.height()));
159}
160
162{
163 if (icon().isNull())
164 return QSize();
165 int icone = style()->pixelMetric(QStyle::PM_SmallIconSize, nullptr, parentWidget() /* QToolBox */);
166 return QSize(icone + 8, icone + 8);
167}
168
170{
171 if (!option)
172 return;
173 option->initFrom(this);
174 if (selected)
176 if (isDown())
178 option->text = text();
179 option->icon = icon();
180
181 QToolBox *toolBox = static_cast<QToolBox *>(parentWidget()); // I know I'm in a tool box.
182 const int widgetCount = toolBox->count();
183 const int currIndex = toolBox->currentIndex();
184 if (widgetCount == 1) {
186 } else if (indexInPage == 0) {
188 } else if (indexInPage == widgetCount - 1) {
190 } else {
192 }
193 if (currIndex == indexInPage - 1) {
195 } else if (currIndex == indexInPage + 1) {
197 } else {
198 option->selectedPosition = QStyleOptionToolBox::NotAdjacent;
199 }
200}
201
210
260QToolBox::QToolBox(QWidget *parent, Qt::WindowFlags f)
261 : QFrame(*new QToolBoxPrivate, parent, f)
262{
263 Q_D(QToolBox);
264 d->layout = new QVBoxLayout(this);
265 d->layout->setContentsMargins(QMargins());
267}
268
276
309{
310 if (!widget)
311 return -1;
312
313 Q_D(QToolBox);
314 connect(widget, SIGNAL(destroyed(QObject*)), this, SLOT(_q_widgetDestroyed(QObject*)));
315
316 auto newPage = std::make_unique<QToolBoxPrivate::Page>();
317 auto &c = *newPage;
318 c.widget = widget;
319 c.button = new QToolBoxButton(this);
320 c.button->setObjectName("qt_toolbox_toolboxbutton"_L1);
321 connect(c.button, SIGNAL(clicked()), this, SLOT(_q_buttonClicked()));
322
323 c.sv = new QScrollArea(this);
324 c.sv->setWidget(widget);
325 c.sv->setWidgetResizable(true);
326 c.sv->hide();
327 c.sv->setFrameStyle(QFrame::NoFrame);
328
329 c.setText(text);
330 c.setIcon(icon);
331
332 if (index < 0 || index >= static_cast<int>(d->pageList.size())) {
333 index = static_cast<int>(d->pageList.size());
334 d->pageList.push_back(std::move(newPage));
335 d->layout->addWidget(c.button);
336 d->layout->addWidget(c.sv);
337 if (index == 0)
339 } else {
340 d->pageList.insert(d->pageList.cbegin() + index, std::move(newPage));
341 d->relayout();
342 if (d->currentPage) {
343 QWidget *current = d->currentPage->widget;
344 int oldindex = indexOf(current);
345 if (index <= oldindex) {
346 d->currentPage = nullptr; // trigger change
347 setCurrentIndex(oldindex);
348 }
349 }
350 }
351
352 c.button->show();
353
354 d->updateTabs();
356 return index;
357}
358
360{
361 Q_Q(QToolBox);
362 QToolBoxButton *tb = qobject_cast<QToolBoxButton*>(q->sender());
363 QWidget* item = nullptr;
364 for (const auto &page : pageList) {
365 if (page->button == tb) {
366 item = page->widget;
367 break;
368 }
369 }
370
371 q->setCurrentIndex(q->indexOf(item));
372}
373
382{
383 Q_D(const QToolBox);
384 return static_cast<int>(d->pageList.size());
385}
386
388{
389 Q_D(QToolBox);
390 QToolBoxPrivate::Page *c = d->page(index);
391 if (!c || d->currentPage == c)
392 return;
393
394 c->button->setSelected(true);
395 if (d->currentPage) {
396 d->currentPage->sv->hide();
397 d->currentPage->button->setSelected(false);
398 }
399 d->currentPage = c;
400 d->currentPage->sv->show();
401 d->updateTabs();
403}
404
406{
407 Q_Q(QToolBox);
408 delete layout;
409 layout = new QVBoxLayout(q);
411 for (const auto &page : pageList) {
412 layout->addWidget(page->button);
413 layout->addWidget(page->sv);
414 }
415}
416
418 return [page](const std::unique_ptr<QToolBoxPrivate::Page> &ptr) {
419 return ptr.get() == page;
420 };
421};
422
424{
425 Q_Q(QToolBox);
426
427 const QToolBoxPrivate::Page * const c = page(object);
428 if (!c)
429 return;
430
431 layout->removeWidget(c->sv);
432 layout->removeWidget(c->button);
433 c->sv->deleteLater(); // page might still be a child of sv
434 delete c->button;
435
436 bool removeCurrent = c == currentPage;
437 pageList.erase(std::remove_if(pageList.begin(), pageList.end(), pageEquals(c)), pageList.end());
438
439 if (pageList.empty()) {
440 currentPage = nullptr;
441 emit q->currentChanged(-1);
442 } else if (removeCurrent) {
443 currentPage = nullptr;
444 q->setCurrentIndex(0);
445 }
446}
447
454{
455 Q_D(QToolBox);
456 if (QWidget *w = widget(index)) {
457 disconnect(w, SIGNAL(destroyed(QObject*)), this, SLOT(_q_widgetDestroyed(QObject*)));
458 w->setParent(this);
459 // destroy internal data
460 d->_q_widgetDestroyed(w);
462 }
463}
464
465
477{
478 Q_D(const QToolBox);
479 return d->currentPage ? indexOf(d->currentPage->widget) : -1;
480}
481
490{
491 Q_D(const QToolBox);
492 return d->currentPage ? d->currentPage->widget : nullptr;
493}
494
501{
502 int i = indexOf(widget);
503 if (Q_UNLIKELY(i < 0))
504 qWarning("QToolBox::setCurrentWidget: widget not contained in tool box");
505 else
507}
508
515{
516 Q_D(const QToolBox);
517 if (index < 0 || index >= static_cast<int>(d->pageList.size()))
518 return nullptr;
519 return d->pageList[index]->widget;
520}
521
528{
529 Q_D(const QToolBox);
530 const QToolBoxPrivate::Page *c = (widget ? d->page(widget) : nullptr);
531 if (!c)
532 return -1;
533 const auto it = std::find_if(d->pageList.cbegin(), d->pageList.cend(), pageEquals(c));
534 if (it == d->pageList.cend())
535 return -1;
536 return static_cast<int>(it - d->pageList.cbegin());
537}
538
545{
546 Q_D(QToolBox);
547 QToolBoxPrivate::Page *c = d->page(index);
548 if (!c)
549 return;
550
552 if (!enabled && c == d->currentPage) {
553 int curIndexUp = index;
554 int curIndexDown = curIndexUp;
555 const int count = static_cast<int>(d->pageList.size());
556 while (curIndexUp > 0 || curIndexDown < count-1) {
557 if (curIndexDown < count-1) {
558 if (d->page(++curIndexDown)->button->isEnabled()) {
559 index = curIndexDown;
560 break;
561 }
562 }
563 if (curIndexUp > 0) {
564 if (d->page(--curIndexUp)->button->isEnabled()) {
565 index = curIndexUp;
566 break;
567 }
568 }
569 }
571 }
572}
573
574
588{
589 Q_D(QToolBox);
590 QToolBoxPrivate::Page *c = d->page(index);
591 if (c)
592 c->setText(text);
593}
594
600{
601 Q_D(QToolBox);
602 QToolBoxPrivate::Page *c = d->page(index);
603 if (c)
604 c->setIcon(icon);
605}
606
607#if QT_CONFIG(tooltip)
612void QToolBox::setItemToolTip(int index, const QString &toolTip)
613{
614 Q_D(QToolBox);
615 QToolBoxPrivate::Page *c = d->page(index);
616 if (c)
617 c->setToolTip(toolTip);
618}
619#endif // QT_CONFIG(tooltip)
620
626{
627 Q_D(const QToolBox);
628 const QToolBoxPrivate::Page *c = d->page(index);
629 return c && c->button->isEnabled();
630}
631
638{
639 Q_D(const QToolBox);
640 const QToolBoxPrivate::Page *c = d->page(index);
641 return (c ? c->text() : QString());
642}
643
650{
651 Q_D(const QToolBox);
652 const QToolBoxPrivate::Page *c = d->page(index);
653 return (c ? c->icon() : QIcon());
654}
655
656#if QT_CONFIG(tooltip)
662QString QToolBox::itemToolTip(int index) const
663{
664 Q_D(const QToolBox);
665 const QToolBoxPrivate::Page *c = d->page(index);
666 return (c ? c->toolTip() : QString());
667}
668#endif // QT_CONFIG(tooltip)
669
675
678{
679 Q_D(QToolBox);
680 if (ev->type() == QEvent::StyleChange)
681 d->updateTabs();
683}
684
692{
694}
695
703{
705}
706
709{
710 return QFrame::event(e);
711}
712
714
715#include "moc_qtoolbox.cpp"
716#include "qtoolbox.moc"
The QAbstractButton class is the abstract base class of button widgets, providing functionality commo...
QIcon icon
the icon shown on the button
void setIcon(const QIcon &icon)
void setText(const QString &text)
QSize iconSize
the icon size used for this button.
QString text
the text shown on the button
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.
\inmodule QtCore
Definition qcoreevent.h:45
@ StyleChange
Definition qcoreevent.h:136
QSize size(int flags, const QString &str, int tabstops=0, int *tabarray=nullptr) const
Returns the size in pixels of text.
The QFrame class is the base class of widgets that can have a frame.
Definition qframe.h:17
bool event(QEvent *e) override
\reimp
Definition qframe.cpp:511
@ NoFrame
Definition qframe.h:39
void changeEvent(QEvent *) override
\reimp
Definition qframe.cpp:498
The QIcon class provides scalable icons in different modes and states.
Definition qicon.h:20
void removeWidget(QWidget *w)
Removes the widget widget from the layout.
Definition qlayout.cpp:1323
void setContentsMargins(int left, int top, int right, int bottom)
Definition qlayout.cpp:288
\inmodule QtCore
Definition qmargins.h:24
\inmodule QtCore
Definition qobject.h:103
QObject * parent() const
Returns a pointer to the parent object.
Definition qobject.h:346
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
void destroyed(QObject *=nullptr)
This signal is emitted immediately before the object obj is destroyed, after any instances of QPointe...
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
The QPalette class contains color groups for each widget state.
Definition qpalette.h:19
void setColor(ColorGroup cg, ColorRole cr, const QColor &color)
Sets the color in the specified color group, used for the given color role, to the specified solid co...
Definition qpalette.h:146
The QScrollArea class provides a scrolling view onto another widget.
Definition qscrollarea.h:17
const_iterator cend() const noexcept
Definition qset.h:142
const_iterator cbegin() const noexcept
Definition qset.h:138
The QShowEvent class provides an event that is sent when a widget is shown.
Definition qevent.h:578
\inmodule QtCore
Definition qsize.h:25
constexpr int height() const noexcept
Returns the height.
Definition qsize.h:133
constexpr int width() const noexcept
Returns the width.
Definition qsize.h:130
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
\variable QStyleOptionComboBox::editable
@ State_Sunken
Definition qstyle.h:69
@ State_Selected
Definition qstyle.h:82
@ CE_ToolBoxTab
Definition qstyle.h:206
@ PM_SmallIconSize
Definition qstyle.h:495
virtual void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p, const QWidget *w=nullptr) const =0
Draws the given element with the provided painter with the style options specified by option.
virtual int pixelMetric(PixelMetric metric, const QStyleOption *option=nullptr, const QWidget *widget=nullptr) const =0
Returns the value of the given pixel metric.
void setIndex(int newIndex)
Definition qtoolbox.cpp:38
void paintEvent(QPaintEvent *) override
\reimp
Definition qtoolbox.cpp:202
QSize minimumSizeHint() const override
Definition qtoolbox.cpp:161
void setSelected(bool b)
Definition qtoolbox.cpp:37
void initStyleOption(QStyleOptionToolBox *opt) const
Definition qtoolbox.cpp:169
QToolBoxButton(QWidget *parent)
Definition qtoolbox.cpp:29
QSize sizeHint() const override
Definition qtoolbox.cpp:149
void _q_buttonClicked()
Definition qtoolbox.cpp:359
QVBoxLayout * layout
Definition qtoolbox.cpp:94
Page * currentPage
Definition qtoolbox.cpp:95
void _q_widgetDestroyed(QObject *)
Definition qtoolbox.cpp:423
const Page * page(const QObject *widget) const
Definition qtoolbox.cpp:98
std::vector< std::unique_ptr< Page > > PageList
Definition qtoolbox.cpp:77
PageList pageList
Definition qtoolbox.cpp:93
The QToolBox class provides a column of tabbed widget items.
Definition qtoolbox.h:18
void showEvent(QShowEvent *e) override
\reimp
Definition qtoolbox.cpp:671
virtual void itemInserted(int index)
This virtual handler is called after a new item was added or inserted at position index.
Definition qtoolbox.cpp:691
QString itemText(int index) const
Returns the text of the item at position index, or an empty string if index is out of range.
Definition qtoolbox.cpp:637
QIcon itemIcon(int index) const
Returns the icon of the item at position index, or a null icon if index is out of range.
Definition qtoolbox.cpp:649
void setItemText(int index, const QString &text)
Sets the text of the item at position index to text.
Definition qtoolbox.cpp:587
void setItemEnabled(int index, bool enabled)
If enabled is true then the item at position index is enabled; otherwise the item at position index i...
Definition qtoolbox.cpp:544
void currentChanged(int index)
This signal is emitted when the current item is changed.
void changeEvent(QEvent *) override
\reimp
Definition qtoolbox.cpp:677
bool isItemEnabled(int index) const
Returns true if the item at position index is enabled; otherwise returns false.
Definition qtoolbox.cpp:625
bool event(QEvent *e) override
\reimp
Definition qtoolbox.cpp:708
int insertItem(int index, QWidget *widget, const QString &text)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qtoolbox.h:82
int count
The number of items contained in the toolbox.
Definition qtoolbox.h:21
QWidget * widget(int index) const
Returns the widget at position index, or \nullptr if there is no such item.
Definition qtoolbox.cpp:514
int currentIndex
the index of the current item
Definition qtoolbox.h:20
virtual void itemRemoved(int index)
This virtual handler is called after an item was removed from position index.
Definition qtoolbox.cpp:702
QToolBox(QWidget *parent=nullptr, Qt::WindowFlags f=Qt::WindowFlags())
Constructs a new toolbox with the given parent and the flags, f.
Definition qtoolbox.cpp:260
~QToolBox()
Destroys the toolbox.
Definition qtoolbox.cpp:273
void setCurrentIndex(int index)
Definition qtoolbox.cpp:387
void setCurrentWidget(QWidget *widget)
Makeswidget the current widget.
Definition qtoolbox.cpp:500
int indexOf(const QWidget *widget) const
Returns the index of widget, or -1 if the item does not exist.
Definition qtoolbox.cpp:527
QWidget * currentWidget() const
Returns a pointer to the current widget, or \nullptr if there is no such item.
Definition qtoolbox.cpp:489
void removeItem(int index)
Removes the item at position index from the toolbox.
Definition qtoolbox.cpp:453
void setItemIcon(int index, const QIcon &icon)
Sets the icon of the item at position index to icon.
Definition qtoolbox.cpp:599
The QVBoxLayout class lines up widgets vertically.
Definition qboxlayout.h:91
The QWidget class is the base class of all user interface objects.
Definition qwidget.h:99
void setBackgroundRole(QPalette::ColorRole)
Sets the background role of the widget to role.
Definition qwidget.cpp:4391
void setSizePolicy(QSizePolicy)
void setEnabled(bool)
Definition qwidget.cpp:3358
QFontMetrics fontMetrics() const
Returns the font metrics for the widget's current font.
Definition qwidget.h:847
void setFocusPolicy(Qt::FocusPolicy policy)
Definition qwidget.cpp:7822
bool isEnabled() const
Definition qwidget.h:814
void update()
Updates the widget unless updates are disabled or the widget is hidden.
QStyle * style() const
Definition qwidget.cpp:2600
QWidget * parentWidget() const
Returns the parent of this widget, or \nullptr if it does not have any parent widget.
Definition qwidget.h:904
virtual void showEvent(QShowEvent *event)
This event handler can be reimplemented in a subclass to receive widget show events which are passed ...
QOpenGLWidget * widget
[1]
QPainter paint
QString text
QSet< QString >::iterator it
QStyleOptionButton opt
Combined button and popup list for selecting options.
@ NoFocus
Definition qnamespace.h:107
@ TextShowMnemonic
Definition qnamespace.h:173
#define Q_UNLIKELY(x)
#define qWarning
Definition qlogging.h:166
static ControlElement< T > * ptr(QWidget *widget)
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
#define SLOT(a)
Definition qobjectdefs.h:52
#define SIGNAL(a)
Definition qobjectdefs.h:53
GLboolean GLboolean GLboolean b
GLfloat GLfloat GLfloat w
[0]
GLuint index
[2]
GLenum GLenum GLsizei count
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLfloat GLfloat f
const GLubyte * c
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLfloat GLfloat p
[1]
GLuint GLenum option
decorationRoleName setToolTip
#define Q_OBJECT
#define emit
auto pageEquals
Definition qtoolbox.cpp:417
#define Q_UNUSED(x)
QObject::connect nullptr
myObject disconnect()
[26]
QByteArray page
[45]
QSharedPointer< T > other(t)
[5]
QGraphicsItem * item
QIcon icon() const
Definition qtoolbox.cpp:70
QScrollArea * sv
Definition qtoolbox.cpp:60
QToolBoxButton * button
Definition qtoolbox.cpp:59
void setIcon(const QIcon &is)
Definition qtoolbox.cpp:64
QString text() const
Definition qtoolbox.cpp:69
bool operator==(const Page &other) const
Definition qtoolbox.cpp:72
void setText(const QString &text)
Definition qtoolbox.cpp:63