7#include <QtWidgets/QGridLayout>
8#include <QtWidgets/QLabel>
9#include <QtWidgets/QToolButton>
16 Q_DECLARE_PUBLIC(QtButtonPropertyBrowser)
25 {
return q_ptr->createEditor(property, parent); }
46 void insertRow(QGridLayout *layout,
int row)
const;
47 void removeRow(QGridLayout *layout,
int row)
const;
50 void setExpanded(
WidgetItem *item,
bool expanded);
51 QToolButton *createButton(QWidget *panret = 0)
const;
53 QHash<QtBrowserItem *, WidgetItem *> m_indexToItem;
54 QHash<WidgetItem *, QtBrowserItem *> m_itemToIndex;
55 QHash<QWidget *, WidgetItem *> m_widgetToItem;
56 QHash<QObject *, WidgetItem *> m_buttonToItem;
57 QGridLayout *m_mainLayout =
nullptr;
58 QList<WidgetItem *> m_children;
59 QList<WidgetItem *> m_recreateQueue;
64 auto *button =
new QToolButton(parent);
65 button->setCheckable(
true);
66 button->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed));
67 button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
68 button->setArrowType(Qt::DownArrow);
69 button->setIconSize(QSize(3, 16));
71
72
73
74
75
81 QList<WidgetItem *> siblings;
85 siblings = m_children;
88 for (WidgetItem *sibling : std::as_const(siblings)) {
91 row += gridSpan(sibling);
105 m_mainLayout =
new QGridLayout();
106 parent->setLayout(m_mainLayout);
107 auto *item =
new QSpacerItem(0, 0, QSizePolicy::Fixed, QSizePolicy::Expanding);
108 m_mainLayout->addItem(item, 0, 0);
113 auto *editor = qobject_cast<QWidget *>(q_ptr->sender());
116 if (!m_widgetToItem.contains(editor))
118 m_widgetToItem[editor]->widget =
nullptr;
119 m_widgetToItem.remove(editor);
124 for (WidgetItem *item : std::as_const(m_recreateQueue)) {
125 WidgetItem *parent = item->parent;
126 QWidget *w =
nullptr;
127 QGridLayout *l =
nullptr;
128 const int oldRow = gridRow(item);
130 w = parent->container;
138 if (!item->widget && !item->widgetLabel)
140 item->label =
new QLabel(w);
141 item->label->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
142 l->addWidget(item->label, oldRow, 0, 1, span);
146 m_recreateQueue.clear();
154 if (!item->container)
158 const int row = gridRow(item);
160 QGridLayout *l =
nullptr;
167 insertRow(l, row + 1);
168 l->addWidget(item->container, row + 1, 0, 1, 2);
169 item->container->show();
171 l->removeWidget(item->container);
172 item->container->hide();
173 removeRow(l, row + 1);
176 item->button->setChecked(expanded);
177 item->button->setArrowType(expanded ? Qt::UpArrow : Qt::DownArrow);
182 WidgetItem *item = m_buttonToItem.value(q_ptr->sender());
186 setExpanded(item, checked);
189 emit q_ptr->expanded(m_itemToIndex.value(item));
191 emit q_ptr->collapsed(m_itemToIndex.value(item));
196 QMetaObject::invokeMethod(q_ptr, [
this] { slotUpdate(); }, Qt::QueuedConnection);
201 WidgetItem *afterItem = m_indexToItem.value(afterIndex);
202 WidgetItem *parentItem = m_indexToItem.value(index->parent());
207 QGridLayout *layout =
nullptr;
208 QWidget *parentWidget =
nullptr;
213 parentItem->children.insert(0, newItem);
215 m_children.insert(0, newItem);
217 row = gridRow(afterItem) + gridSpan(afterItem);
219 parentItem->children.insert(parentItem->children.indexOf(afterItem) + 1, newItem);
221 m_children.insert(m_children.indexOf(afterItem) + 1, newItem);
225 layout = m_mainLayout;
226 parentWidget = q_ptr;
228 if (!parentItem->container) {
229 m_recreateQueue.removeAll(parentItem);
231 QGridLayout *l =
nullptr;
232 const int oldRow = gridRow(parentItem);
234 l = grandParent->layout;
238 auto *container =
new QFrame();
239 container->setFrameShape(QFrame::Panel);
240 container->setFrameShadow(QFrame::Raised);
241 parentItem->container = container;
242 parentItem->button = createButton();
243 m_buttonToItem[parentItem->button] = parentItem;
244 q_ptr->connect(parentItem->button, &QAbstractButton::toggled,
245 q_ptr, [
this](
bool checked) { slotToggled(checked); });
246 parentItem->layout =
new QGridLayout();
247 container->setLayout(parentItem->layout);
248 if (parentItem->label) {
249 l->removeWidget(parentItem->label);
250 delete parentItem->label;
251 parentItem->label =
nullptr;
254 if (!parentItem->widget && !parentItem->widgetLabel)
256 l->addWidget(parentItem->button, oldRow, 0, 1, span);
257 updateItem(parentItem);
259 layout = parentItem->layout;
260 parentWidget = parentItem->container;
263 newItem->label =
new QLabel(parentWidget);
264 newItem->label->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
265 newItem->widget = createEditor(index->property(), parentWidget);
266 if (newItem->widget) {
267 QObject::connect(newItem->widget, &QWidget::destroyed,
268 q_ptr, [
this] { slotEditorDestroyed(); });
269 m_widgetToItem[newItem->widget] = newItem;
271 newItem->widgetLabel =
new QLabel(parentWidget);
272 newItem->widgetLabel->setSizePolicy(QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed));
275 insertRow(layout, row);
278 layout->addWidget(newItem->widget, row, 1);
279 else if (newItem->widgetLabel)
280 layout->addWidget(newItem->widgetLabel, row, 1);
283 layout->addWidget(newItem->label, row, 0, span, 1);
285 m_itemToIndex[newItem] = index;
286 m_indexToItem[index] = newItem;
293 WidgetItem *item = m_indexToItem.value(index);
295 m_indexToItem.remove(index);
296 m_itemToIndex.remove(item);
300 const int row = gridRow(item);
303 parentItem->children.removeAt(parentItem->children.indexOf(item));
305 m_children.removeAt(m_children.indexOf(item));
307 const int colSpan = gridSpan(item);
309 m_buttonToItem.remove(item->button);
315 if (item->widgetLabel)
316 delete item->widgetLabel;
320 delete item->container;
323 removeRow(m_mainLayout, row);
325 removeRow(m_mainLayout, row);
326 }
else if (parentItem->children.size() != 0) {
327 removeRow(parentItem->layout, row);
329 removeRow(parentItem->layout, row);
332 QGridLayout *l =
nullptr;
334 l = grandParent->layout;
339 const int parentRow = gridRow(parentItem);
340 const int parentSpan = gridSpan(parentItem);
342 l->removeWidget(parentItem->button);
343 l->removeWidget(parentItem->container);
344 delete parentItem->button;
345 delete parentItem->container;
346 parentItem->button =
nullptr;
347 parentItem->container =
nullptr;
348 parentItem->layout =
nullptr;
349 if (!m_recreateQueue.contains(parentItem))
350 m_recreateQueue.append(parentItem);
352 removeRow(l, parentRow + 1);
356 m_recreateQueue.removeAll(item);
363 QHash<QLayoutItem *, QRect> itemToPos;
365 while (idx < layout->count()) {
367 layout->getItemPosition(idx, &r, &c, &rs, &cs);
369 itemToPos[layout->takeAt(idx)] = QRect(r + 1, c, rs, cs);
375 for (
auto it = itemToPos.constBegin(), icend = itemToPos.constEnd(); it != icend; ++it) {
376 const QRect r = it.value();
377 layout->addItem(it.key(), r.x(), r.y(), r.width(), r.height());
383 QHash<QLayoutItem *, QRect> itemToPos;
385 while (idx < layout->count()) {
387 layout->getItemPosition(idx, &r, &c, &rs, &cs);
389 itemToPos[layout->takeAt(idx)] = QRect(r - 1, c, rs, cs);
395 for (
auto it = itemToPos.constBegin(), icend = itemToPos.constEnd(); it != icend; ++it) {
396 const QRect r = it.value();
397 layout->addItem(it.key(), r.x(), r.y(), r.width(), r.height());
403 WidgetItem *item = m_indexToItem.value(index);
410 QtProperty *property = m_itemToIndex[item]->property();
412 QFont font = item->button->font();
414 item->button->setFont(font);
415 item->button->setText(property->propertyName());
416 item->button->setToolTip(property->descriptionToolTip());
417 item->button->setStatusTip(property->statusTip());
418 item->button->setWhatsThis(property->whatsThis());
422 QFont font = item->label->font();
424 item->label->setFont(font);
425 item->label->setText(property->propertyName());
426 item->label->setToolTip(property->descriptionToolTip());
427 item->label->setStatusTip(property->statusTip());
428 item->label->setWhatsThis(property->whatsThis());
431 if (item->widgetLabel) {
432 QFont font = item->widgetLabel->font();
433 font.setUnderline(
false);
434 item->widgetLabel->setFont(font);
435 item->widgetLabel->setText(property->valueText());
436 item->widgetLabel->setToolTip(property->valueText());
440 QFont font = item->widget->font();
441 font.setUnderline(
false);
442 item->widget->setFont(font);
444 const QString valueToolTip = property->valueToolTip();
445 item->widget->setToolTip(valueToolTip.isEmpty() ? property->valueText() : valueToolTip);
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
481
482
483
484
485
486
489
490
491
492
493
494
497
498
508
509
510
511
512
513
514
515
516
519 for (
auto it = d_ptr->m_itemToIndex.cbegin(), icend = d_ptr->m_itemToIndex.cend(); it != icend; ++it)
524
525
528 d_ptr->propertyInserted(item, afterItem);
532
533
536 d_ptr->propertyRemoved(item);
540
541
544 d_ptr->propertyChanged(item);
548
549
550
551
557 d_ptr->setExpanded(itm, expanded);
561
562
563
564
576#include "moc_qtbuttonpropertybrowser_p.cpp"
QtAbstractPropertyBrowser provides a base class for implementing property browsers.
The QtBrowserItem class represents a property in a property browser instance.
QtProperty * property() const
Returns the property which is accosiated with this item.
The QtProperty class encapsulates an instance of a property.
bool isEnabled() const
Returns whether the property is enabled.
bool hasValue() const
Returns whether the property has a value.
bool isModified() const
Returns whether the property is modified.
Combined button and popup list for selecting options.