Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qtreewidget.cpp
Go to the documentation of this file.
1// Copyright (C) 2019 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 "qtreewidget.h"
5
6#include <qheaderview.h>
7#include <qpainter.h>
8#include <qitemdelegate.h>
9#include <qstack.h>
10#include <qdebug.h>
11#include <private/qtreewidget_p.h>
12#include <private/qwidgetitemdata_p.h>
13#include <private/qtreewidgetitemiterator_p.h>
14
15#include <QtCore/private/qduplicatetracker_p.h>
16
17#include <algorithm>
18
20
22{
23public:
24 inline bool operator()(QTreeWidgetItem *i1, QTreeWidgetItem *i2) const
25 { return *i1 < *i2; }
26};
27
29{
30public:
31 inline bool operator()(QTreeWidgetItem *i1, QTreeWidgetItem *i2) const
32 { return *i2 < *i1; }
33};
34
35/*
36 \class QTreeModel
37 \brief The QTreeModel class manages the items stored in a tree view.
38
39 \ingroup model-view
40 \inmodule QtWidgets
41
42*/
43
81 headerItem(new QTreeWidgetItem)
82{
83 rootItem->view = parent;
84 rootItem->itemFlags = Qt::ItemIsDropEnabled;
85 headerItem->view = parent;
86 setColumnCount(columns);
87}
88
96{
97 rootItem->view = parent;
98 rootItem->itemFlags = Qt::ItemIsDropEnabled;
99 headerItem->view = parent;
100}
101
109{
110 clear();
111 headerItem->view = nullptr;
112 delete headerItem;
113 rootItem->view = nullptr;
114 delete rootItem;
115}
116
124{
125 SkipSorting skipSorting(this);
127 for (int i = 0; i < rootItem->childCount(); ++i) {
128 QTreeWidgetItem *item = rootItem->children.at(i);
129 item->par = nullptr;
130 item->view = nullptr;
131 delete item;
132 }
133 rootItem->children.clear();
134 sortPendingTimer.stop();
136}
137
145{
146 SkipSorting skipSorting(this);
147 if (columns < 0)
148 return;
149 if (!headerItem) {
150 headerItem = new QTreeWidgetItem();
151 headerItem->view = view();
152 }
153 int count = columnCount();
154 if (count == columns)
155 return;
156
157 if (columns < count) {
158 beginRemoveColumns(QModelIndex(), columns, count - 1);
159 headerItem->values.resize(columns);
161 } else {
162 beginInsertColumns(QModelIndex(), count, columns - 1);
163 headerItem->values.resize(columns);
164 for (int i = count; i < columns; ++i) {// insert data without emitting the dataChanged signal
165 headerItem->values[i].append(QWidgetItemData(Qt::DisplayRole, QString::number(i + 1)));
166 headerItem->d->display.append(QString::number(i + 1));
167 }
169 }
170}
171
181{
182 if (!index.isValid())
183 return nullptr;
184 return static_cast<QTreeWidgetItem*>(index.internalPointer());
185}
186
195{
196 executePendingSort();
197
198 if (!item || (item == rootItem))
199 return QModelIndex();
200 const QTreeWidgetItem *par = item->parent();
201 QTreeWidgetItem *itm = const_cast<QTreeWidgetItem*>(item);
202 if (!par)
203 par = rootItem;
204 int row;
205 int guess = item->d->rowGuess;
206 if (guess >= 0
207 && par->children.size() > guess
208 && par->children.at(guess) == itm) {
209 row = guess;
210 } else {
211 row = par->children.lastIndexOf(itm);
212 itm->d->rowGuess = row;
213 }
214 return createIndex(row, column, itm);
215}
216
226{
227 executePendingSort();
228
229 int c = columnCount(parent);
230 if (row < 0 || column < 0 || column >= c)
231 return QModelIndex();
232
233 QTreeWidgetItem *parentItem = parent.isValid() ? item(parent) : rootItem;
234 if (parentItem && row < parentItem->childCount()) {
235 QTreeWidgetItem *itm = parentItem->child(row);
236 if (itm)
237 return createIndex(row, column, itm);
238 return QModelIndex();
239 }
240
241 return QModelIndex();
242}
243
253{
254 SkipSorting skipSorting(this); //The reason we don't sort here is that this might be called from a valid QPersistentModelIndex
255 //We don't want it to become suddenly invalid
256
257 if (!child.isValid())
258 return QModelIndex();
259 QTreeWidgetItem *itm = static_cast<QTreeWidgetItem *>(child.internalPointer());
260 if (!itm || itm == rootItem)
261 return QModelIndex();
262 QTreeWidgetItem *parent = itm->parent();
263 return index(parent, 0);
264}
265
274{
275 if (!parent.isValid())
276 return rootItem->childCount();
277
278 QTreeWidgetItem *parentItem = item(parent);
279 if (parentItem)
280 return parentItem->childCount();
281 return 0;
282}
283
293{
295 if (!headerItem)
296 return 0;
297 return headerItem->columnCount();
298}
299
301{
302 if (!parent.isValid())
303 return (rootItem->childCount() > 0);
304
306 if (!itm)
307 return false;
308 switch (itm->d->policy) {
310 return true;
312 return false;
314 return (itm->childCount() > 0);
315 }
316 return false;
317}
318
328{
329 if (!index.isValid())
330 return QVariant();
331 QTreeWidgetItem *itm = item(index);
332 if (itm)
333 return itm->data(index.column(), role);
334 return QVariant();
335}
336
347bool QTreeModel::setData(const QModelIndex &index, const QVariant &value, int role)
348{
349 if (!index.isValid())
350 return false;
351 QTreeWidgetItem *itm = item(index);
352 if (itm) {
353 itm->setData(index.column(), role, value);
354 return true;
355 }
356 return false;
357}
358
360{
362 return false;
363 QTreeWidgetItem *itm = item(index);
364 if (!itm)
365 return false;
366 const auto beginIter = itm->values.at(index.column()).cbegin();
367 const auto endIter = itm->values.at(index.column()).cend();
368 if (std::all_of(beginIter, endIter, [](const QWidgetItemData& data) -> bool { return !data.value.isValid(); })
369 && !itm->d->display.at(index.column()).isValid()) {
370 return true; //it's already cleared
371 }
372 itm->d->display[index.column()] = QVariant();
373 itm->values[index.column()].clear();
375 return true;
376}
377
379{
381 QTreeWidgetItem *itm = item(index);
382 if (itm) {
383 int column = index.column();
384 if (column < itm->values.size()) {
385 for (int i = 0; i < itm->values.at(column).size(); ++i) {
386 roles.insert(itm->values.at(column).at(i).role,
387 itm->values.at(column).at(i).value);
388 }
389 }
390
391 // the two special cases
392 QVariant displayValue = itm->data(column, Qt::DisplayRole);
393 if (displayValue.isValid())
394 roles.insert(Qt::DisplayRole, displayValue);
395
396 QVariant checkValue = itm->data(column, Qt::CheckStateRole);
397 if (checkValue.isValid())
398 roles.insert(Qt::CheckStateRole, checkValue);
399 }
400 return roles;
401}
402
408{
409 SkipSorting skipSorting(this);
410 if (count < 1 || row < 0 || row > rowCount(parent) || parent.column() > 0)
411 return false;
412
415 while (count > 0) {
417 item->view = view();
418 item->par = par;
419 if (par)
420 par->children.insert(row++, item);
421 else
422 rootItem->children.insert(row++, item);
423 --count;
424 }
426 return true;
427}
428
434{
435 SkipSorting skipSorting(this);
436 if (count < 1 || column < 0 || column > columnCount(parent) || parent.column() > 0 || !headerItem)
437 return false;
438
440
441 int oldCount = columnCount(parent);
442 column = qBound(0, column, oldCount);
443 headerItem->values.resize(oldCount + count);
444 for (int i = oldCount; i < oldCount + count; ++i) {
445 headerItem->values[i].append(QWidgetItemData(Qt::DisplayRole, QString::number(i + 1)));
446 headerItem->d->display.append(QString::number(i + 1));
447 }
448
449 QStack<QTreeWidgetItem*> itemstack;
450 itemstack.push(0);
451 while (!itemstack.isEmpty()) {
452 QTreeWidgetItem *par = itemstack.pop();
453 QList<QTreeWidgetItem*> children = par ? par->children : rootItem->children;
454 for (int row = 0; row < children.size(); ++row) {
456 if (child->children.size())
457 itemstack.push(child);
458 child->values.insert(column, count, QList<QWidgetItemData>());
459 }
460 }
461
463 return true;
464}
465
471 if (count < 1 || row < 0 || (row + count) > rowCount(parent))
472 return false;
473 QTreeWidgetItem *parentItem = item(parent);
474 // if parentItem is valid, begin/end RemoveRows is handled by takeChild below
475 if (!parentItem)
477 for (int i = row + count - 1; i >= row; --i) {
478 QTreeWidgetItem *child = parentItem ? parentItem->takeChild(i) : rootItem->children.takeAt(i);
480 child->view = nullptr;
481 delete child;
482 }
483 if (!parentItem)
485 return true;
486}
487
496QVariant QTreeModel::headerData(int section, Qt::Orientation orientation, int role) const
497{
498 if (orientation != Qt::Horizontal)
499 return QVariant();
500
501 if (headerItem)
502 return headerItem->data(section, role);
503 if (role == Qt::DisplayRole)
504 return QString::number(section + 1);
505 return QVariant();
506}
507
518bool QTreeModel::setHeaderData(int section, Qt::Orientation orientation,
519 const QVariant &value, int role)
520{
521 if (section < 0 || orientation != Qt::Horizontal || !headerItem || section >= columnCount())
522 return false;
523
524 headerItem->setData(section, role, value);
525 return true;
526}
527
535Qt::ItemFlags QTreeModel::flags(const QModelIndex &index) const
536{
537 if (!index.isValid())
538 return rootItem->flags();
539 QTreeWidgetItem *itm = item(index);
540 Q_ASSERT(itm);
541 return itm->flags();
542}
543
552{
553 SkipSorting skipSorting(this);
554 sortPendingTimer.stop();
555
556 if (column < 0 || column >= columnCount())
557 return;
558
559 //layoutAboutToBeChanged and layoutChanged will be called by sortChildren
560 rootItem->sortChildren(column, order, true);
561}
562
567 int start, int end, const QModelIndex &parent)
568{
569 if (isChanging())
570 return;
571
572 sortPendingTimer.stop();
573
574 if (column < 0 || column >= columnCount())
575 return;
576
577 SkipSorting skipSorting(this);
578
580 if (!itm)
581 itm = rootItem;
582 QList<QTreeWidgetItem*> lst = itm->children;
583
584 int count = end - start + 1;
586 for (int i = 0; i < count; ++i) {
587 sorting[i].first = lst.at(start + i);
588 sorting[i].second = start + i;
589 }
590
592 std::stable_sort(sorting.begin(), sorting.end(), compare);
593
594 QModelIndexList oldPersistentIndexes;
595 QModelIndexList newPersistentIndexes;
597 bool changed = false;
598
599 for (int i = 0; i < count; ++i) {
600 int oldRow = sorting.at(i).second;
601
602 int tmpitepos = lit - lst.begin();
603 QTreeWidgetItem *item = lst.takeAt(oldRow);
604 if (tmpitepos > lst.size())
605 --tmpitepos;
606 lit = lst.begin() + tmpitepos;
607
608 lit = sortedInsertionIterator(lit, lst.end(), order, item);
609 int newRow = qMax<qsizetype>(lit - lst.begin(), 0);
610
611 if ((newRow < oldRow) && !(*item < *lst.at(oldRow - 1)) && !(*lst.at(oldRow - 1) < *item ))
612 newRow = oldRow;
613
614 lit = lst.insert(lit, item);
615 if (newRow != oldRow) {
616 // we are going to change the persistent indexes, so we need to prepare
617 if (!changed) { // this will only happen once
618 changed = true;
619 emit layoutAboutToBeChanged({parent}, QAbstractItemModel::VerticalSortHint); // the selection model needs to know
620 oldPersistentIndexes = persistentIndexList();
621 newPersistentIndexes = oldPersistentIndexes;
622 }
623 for (int j = i + 1; j < count; ++j) {
624 int otherRow = sorting.at(j).second;
625 if (oldRow < otherRow && newRow >= otherRow)
626 --sorting[j].second;
627 else if (oldRow > otherRow && newRow <= otherRow)
628 ++sorting[j].second;
629 }
630 for (int k = 0; k < newPersistentIndexes.size(); ++k) {
631 QModelIndex pi = newPersistentIndexes.at(k);
632 if (pi.parent() != parent)
633 continue;
634 int oldPersistentRow = pi.row();
635 int newPersistentRow = oldPersistentRow;
636 if (oldPersistentRow == oldRow)
637 newPersistentRow = newRow;
638 else if (oldRow < oldPersistentRow && newRow >= oldPersistentRow)
639 newPersistentRow = oldPersistentRow - 1;
640 else if (oldRow > oldPersistentRow && newRow <= oldPersistentRow)
641 newPersistentRow = oldPersistentRow + 1;
642 if (newPersistentRow != oldPersistentRow)
643 newPersistentIndexes[k] = createIndex(newPersistentRow,
644 pi.column(), pi.internalPointer());
645 }
646 }
647 }
648
649 if (changed) {
650 itm->children = lst;
651 changePersistentIndexList(oldPersistentIndexes, newPersistentIndexes);
653 }
654}
655
667{
668 return *(left.first) < *(right.first);
669}
670
682{
683 return *(right.first) < *(left.first);
684}
685
693{
695 return std::lower_bound(begin, end, item, QTreeModelLessThan());
696 return std::lower_bound(begin, end, item, QTreeModelGreaterThan());
697}
698
700{
701 auto v = view();
702 if (v)
703 return v->mimeTypes();
704 return {};
705}
706
708{
709 return QAbstractItemModel::mimeData(cachedIndexes);
710}
711
713{
715 std::transform(indexes.begin(), indexes.end(), std::back_inserter(items),
716 [this](const QModelIndex &idx) -> QTreeWidgetItem * { return item(idx); });
717
718 // Ensure we only have one item as an item may have more than
719 // one index selected if there is more than one column
720 std::sort(items.begin(), items.end());
721 items.erase(std::unique(items.begin(), items.end()), items.end());
722
723 // cachedIndexes is a little hack to avoid copying from QModelIndexList to
724 // QList<QTreeWidgetItem*> and back again in the view
725 cachedIndexes = indexes;
727 cachedIndexes.clear();
728 return mimeData;
729}
730
732 int row, int column, const QModelIndex &parent)
733{
734 if (row == -1 && column == -1)
735 row = rowCount(parent); // append
736 return view()->dropMimeData(item(parent), row, data, action);
737}
738
739Qt::DropActions QTreeModel::supportedDropActions() const
740{
741 return view()->supportedDropActions();
742}
743
745{
746 SkipSorting skipSorting(this); //this is kind of wrong, but not doing this would kill performance
748 QModelIndex right = index(item, item->columnCount() - 1);
750}
751
752bool QTreeModel::isChanging() const
753{
754 Q_D(const QTreeModel);
755 return !d->changes.isEmpty();
756}
757
765{
766 if (signalsBlocked())
767 return;
768
769 if (headerItem == item && column < item->columnCount()) {
770 if (column == -1)
772 else
774 return;
775 }
776
777 SkipSorting skipSorting(this); //This is a little bit wrong, but not doing it would kill performance
778
779 QModelIndex bottomRight, topLeft;
780 if (column == -1) {
781 topLeft = index(item, 0);
782 bottomRight = createIndex(topLeft.row(), columnCount() - 1, item);
783 } else {
784 topLeft = index(item, column);
785 bottomRight = topLeft;
786 }
787 emit dataChanged(topLeft, bottomRight, roles);
788}
789
791{
792 QModelIndex par = index(parent, 0);
793 beginInsertRows(par, row, row + count - 1);
794}
795
797{
799}
800
802{
803 Q_ASSERT(row >= 0);
804 Q_ASSERT(count > 0);
806 if (!parent)
807 parent = rootItem;
808 // now update the iterators
809 for (int i = 0; i < iterators.size(); ++i) {
810 for (int j = 0; j < count; j++) {
811 QTreeWidgetItem *c = parent->child(row + j);
812 iterators[i]->d_func()->ensureValidIterator(c);
813 }
814 }
815}
816
818{
820}
821
823{
824 // see QTreeViewItem::operator<
826 if (isChanging())
827 return;
828
829 // store the original order of indexes
831 for (int i = 0; i < sorting.size(); ++i) {
832 sorting[i].first = items->at(i);
833 sorting[i].second = i;
834 }
835
836 // do the sorting
838 std::stable_sort(sorting.begin(), sorting.end(), compare);
839
840 QModelIndexList fromList;
842 int colCount = columnCount();
843 for (int r = 0; r < sorting.size(); ++r) {
844 int oldRow = sorting.at(r).second;
845 if (oldRow == r)
846 continue;
847 QTreeWidgetItem *item = sorting.at(r).first;
848 items->replace(r, item);
849 for (int c = 0; c < colCount; ++c) {
850 QModelIndex from = createIndex(oldRow, c, item);
851 if (static_cast<QAbstractItemModelPrivate *>(d_ptr.data())->persistent.indexes.contains(from)) {
853 fromList << from;
854 toList << to;
855 }
856 }
857 }
859}
860
862{
863 if (ev->timerId() == sortPendingTimer.timerId()) {
864 executePendingSort();
865 } else {
867 }
868}
869
980{
981 const QTreeModel *model = treeModel();
982 if (!model || !view->selectionModel())
983 return;
984 const QModelIndex index = model->index(this, 0);
988 d->selected = select;
989}
990
1000{
1001 return d->selected;
1002}
1003
1017{
1018 const QTreeModel *model = treeModel();
1019 if (!model)
1020 return;
1021 if (this == model->headerItem) {
1022 view->header()->setHidden(hide);
1023 } else {
1024 const QModelIndex index = view->d_func()->index(this);
1025 view->setRowHidden(index.row(), index.parent(), hide);
1026 }
1027 d->hidden = hide;
1028}
1029
1040{
1041 const QTreeModel *model = treeModel();
1042 if (!model)
1043 return false;
1044 if (this == model->headerItem)
1045 return view->header()->isHidden();
1046 if (view->d_func()->hiddenIndexes.isEmpty())
1047 return false;
1048 QTreeModel::SkipSorting skipSorting(model);
1049 return view->d_func()->isRowHidden(view->d_func()->index(this));
1050}
1051
1062{
1063 const QTreeModel *model = treeModel();
1064 if (!model)
1065 return;
1066 QTreeModel::SkipSorting skipSorting(model);
1067 view->setExpanded(view->d_func()->index(this), expand);
1068}
1069
1079{
1080 const QTreeModel *model = treeModel();
1081 if (!model)
1082 return false;
1083 QTreeModel::SkipSorting skipSorting(model);
1084 return view->isExpanded(view->d_func()->index(this));
1085}
1086
1097{
1098 const QTreeModel *model = treeModel();
1099 if (!model || this == model->headerItem)
1100 return; // We can't set the header items to spanning
1101 const QModelIndex index = model->index(this, 0);
1102 view->setFirstColumnSpanned(index.row(), index.parent(), span);
1103}
1104
1114{
1115 const QTreeModel *model = treeModel();
1116 if (!model || this == model->headerItem)
1117 return false;
1118 const QModelIndex index = model->index(this, 0);
1119 return view->isFirstColumnSpanned(index.row(), index.parent());
1120}
1121
1387
1397 : rtti(type), d(new QTreeWidgetItemPrivate(this))
1398{
1399 for (int i = 0; i < strings.size(); ++i)
1400 setText(i, strings.at(i));
1401}
1402
1413 : rtti(type), d(new QTreeWidgetItemPrivate(this))
1414{
1415 // do not set this->view here otherwise insertChild() will fail
1416 if (QTreeModel *model = treeModel(treeview)) {
1417 model->rootItem->addChild(this);
1418 values.reserve(model->headerItem->columnCount());
1419 }
1420}
1421
1433 : rtti(type), d(new QTreeWidgetItemPrivate(this))
1434{
1435 for (int i = 0; i < strings.size(); ++i)
1436 setText(i, strings.at(i));
1437 // do not set this->view here otherwise insertChild() will fail
1438 if (QTreeModel *model = treeModel(treeview)) {
1439 model->rootItem->addChild(this);
1440 values.reserve(model->headerItem->columnCount());
1441 }
1442}
1443
1453 : rtti(type), d(new QTreeWidgetItemPrivate(this))
1454{
1455 // do not set this->view here otherwise insertChild() will fail
1456 if (QTreeModel *model = treeModel(treeview)) {
1457 int i = model->rootItem->children.indexOf(after) + 1;
1458 model->rootItem->insertChild(i, this);
1459 values.reserve(model->headerItem->columnCount());
1460 }
1461}
1462
1469 : rtti(type), d(new QTreeWidgetItemPrivate(this))
1470{
1471 if (parent)
1472 parent->addChild(this);
1473}
1474
1482 : rtti(type), d(new QTreeWidgetItemPrivate(this))
1483{
1484 for (int i = 0; i < strings.size(); ++i)
1485 setText(i, strings.at(i));
1486 if (parent)
1487 parent->addChild(this);
1488}
1489
1499 : rtti(type), d(new QTreeWidgetItemPrivate(this))
1500{
1501 if (parent) {
1502 int i = parent->children.indexOf(after) + 1;
1503 parent->insertChild(i, this);
1504 }
1505}
1506
1516{
1517 QTreeModel *model = treeModel();
1518 QTreeModel::SkipSorting skipSorting(model);
1519
1520 if (par) {
1521 int i = par->children.indexOf(this);
1522 if (i >= 0) {
1523 if (model) model->beginRemoveItems(par, i, 1);
1524 // users _could_ do changes when connected to rowsAboutToBeRemoved,
1525 // so we check again to make sure 'i' is valid
1526 if (!par->children.isEmpty() && par->children.at(i) == this)
1527 par->children.takeAt(i);
1528 if (model) model->endRemoveItems();
1529 }
1530 } else if (model) {
1531 if (this == model->headerItem) {
1532 model->headerItem = nullptr;
1533 } else {
1534 int i = model->rootItem->children.indexOf(this);
1535 if (i >= 0) {
1536 model->beginRemoveItems(nullptr, i, 1);
1537 // users _could_ do changes when connected to rowsAboutToBeRemoved,
1538 // so we check again to make sure 'i' is valid
1539 if (!model->rootItem->children.isEmpty() && model->rootItem->children.at(i) == this)
1540 model->rootItem->children.takeAt(i);
1541 model->endRemoveItems();
1542 }
1543 }
1544 }
1545 // at this point the persistent indexes for the children should also be invalidated
1546 // since we invalidated the parent
1547 for (int i = 0; i < children.size(); ++i) {
1548 QTreeWidgetItem *child = children.at(i);
1549 // make sure the child does not try to remove itself from our children list
1550 child->par = nullptr;
1551 // make sure the child does not try to remove itself from the top level list
1552 child->view = nullptr;
1553 delete child;
1554 }
1555
1556 children.clear();
1557 delete d;
1558}
1559
1564{
1565 QTreeWidgetItem *copy = nullptr;
1566
1568 QStack<QTreeWidgetItem*> parentStack;
1569 stack.push(this);
1570 parentStack.push(0);
1571
1572 QTreeWidgetItem *root = nullptr;
1573 const QTreeWidgetItem *item = nullptr;
1574 QTreeWidgetItem *parent = nullptr;
1575 while (!stack.isEmpty()) {
1576 // get current item, and copied parent
1577 item = stack.pop();
1578 parent = parentStack.pop();
1579
1580 // copy item
1581 copy = new QTreeWidgetItem(*item);
1582 if (!root)
1583 root = copy;
1584
1585 // set parent and add to parents children list
1586 if (parent) {
1587 copy->par = parent;
1588 parent->children.insert(0, copy);
1589 }
1590
1591 for (int i = 0; i < item->childCount(); ++i) {
1592 stack.push(item->child(i));
1593 parentStack.push(copy);
1594 }
1595 }
1596 return root;
1597}
1598
1607{
1608 if (d->policy == policy)
1609 return;
1610 d->policy = policy;
1611
1612 if (!view)
1613 return;
1614
1616}
1617
1625{
1626 return d->policy;
1627}
1628
1638{
1639 const bool enable = (flags & Qt::ItemIsEnabled);
1640 const bool changedState = bool(itemFlags & Qt::ItemIsEnabled) != enable;
1641 const bool changedExplicit = d->disabled != !enable;
1642
1643 d->disabled = !enable;
1644
1645 if (enable && par && !(par->itemFlags & Qt::ItemIsEnabled)) // inherit from parent
1646 itemFlags = flags & ~Qt::ItemIsEnabled;
1647 else // this item is explicitly disabled or has no parent
1648 itemFlags = flags;
1649
1650 if (changedState && changedExplicit) { // if the propagate the change to the children
1652 parents.push(this);
1653 while (!parents.isEmpty()) {
1654 QTreeWidgetItem *parent = parents.pop();
1655 for (int i = 0; i < parent->children.size(); ++i) {
1656 QTreeWidgetItem *child = parent->children.at(i);
1657 if (!child->d->disabled) { // if not explicitly disabled
1658 parents.push(child);
1659 if (enable)
1660 child->itemFlags = child->itemFlags | Qt::ItemIsEnabled;
1661 else
1662 child->itemFlags = child->itemFlags & ~Qt::ItemIsEnabled;
1663 child->itemChanged(); // ### we may want to optimize this
1664 }
1665 }
1666 }
1667 }
1668 itemChanged();
1669}
1670
1672{
1673 QTreeModel *model = item->treeModel();
1674 if (!model)
1675 return;
1677 parents.push(item);
1678 while (!parents.isEmpty()) {
1679 QTreeWidgetItem *parent = parents.pop();
1680 if (parent->d->hidden) {
1681 const QModelIndex index = model->index(parent, 0);
1682 item->view->setRowHidden(index.row(), index.parent(), inserting);
1683 }
1684 for (int i = 0; i < parent->children.size(); ++i) {
1685 QTreeWidgetItem *child = parent->children.at(i);
1686 parents.push(child);
1687 }
1688 }
1689}
1690
1692{
1693 Q_ASSERT(item);
1694 const bool enable = item->par ? (item->par->itemFlags.testFlag(Qt::ItemIsEnabled)) : true;
1695
1697 parents.push(item);
1698 while (!parents.isEmpty()) {
1699 QTreeWidgetItem *parent = parents.pop();
1700 if (!parent->d->disabled) { // if not explicitly disabled
1701 Qt::ItemFlags oldFlags = parent->itemFlags;
1702 if (enable)
1703 parent->itemFlags = parent->itemFlags | Qt::ItemIsEnabled;
1704 else
1705 parent->itemFlags = parent->itemFlags & ~Qt::ItemIsEnabled;
1706 if (parent->itemFlags != oldFlags)
1707 parent->itemChanged();
1708 }
1709
1710 for (int i = 0; i < parent->children.size(); ++i) {
1711 QTreeWidgetItem *child = parent->children.at(i);
1712 parents.push(child);
1713 }
1714 }
1715}
1728Qt::ItemFlags QTreeWidgetItem::flags() const
1729{
1730 return itemFlags;
1731}
1732
1744{
1745 if (column < 0)
1746 return;
1747
1748 QTreeModel *model = treeModel();
1749 switch (role) {
1750 case Qt::EditRole:
1751 case Qt::DisplayRole: {
1752 if (values.size() <= column) {
1753 if (model && this == model->headerItem)
1754 model->setColumnCount(column + 1);
1755 else
1756 values.resize(column + 1);
1757 }
1758 if (d->display.size() <= column) {
1759 for (int i = d->display.size() - 1; i < column - 1; ++i)
1760 d->display.append(QVariant());
1761 d->display.append(value);
1762 } else if (d->display[column] != value) {
1763 d->display[column] = value;
1764 } else {
1765 return; // value is unchanged
1766 }
1767 } break;
1768 case Qt::CheckStateRole:
1769 if ((itemFlags & Qt::ItemIsAutoTristate) && value != Qt::PartiallyChecked) {
1770 for (int i = 0; i < children.size(); ++i) {
1771 QTreeWidgetItem *child = children.at(i);
1772 if (child->data(column, role).isValid()) {// has a CheckState
1773 Qt::ItemFlags f = itemFlags; // a little hack to avoid multiple dataChanged signals
1774 itemFlags &= ~Qt::ItemIsAutoTristate;
1775 child->setData(column, role, value);
1776 itemFlags = f;
1777 }
1778 }
1779 }
1780 Q_FALLTHROUGH();
1781 default:
1782 if (column < values.size()) {
1783 bool found = false;
1784 const QList<QWidgetItemData> column_values = values.at(column);
1785 for (int i = 0; i < column_values.size(); ++i) {
1786 if (column_values.at(i).role == role) {
1787 if (column_values.at(i).value == value)
1788 return; // value is unchanged
1789 values[column][i].value = value;
1790 found = true;
1791 break;
1792 }
1793 }
1794 if (!found)
1795 values[column].append(QWidgetItemData(role, value));
1796 } else {
1797 if (model && this == model->headerItem)
1798 model->setColumnCount(column + 1);
1799 else
1800 values.resize(column + 1);
1801 values[column].append(QWidgetItemData(role, value));
1802 }
1803 }
1804
1805 if (model) {
1806 const QList<int> roles((role == Qt::DisplayRole || role == Qt::EditRole)
1808 : QList<int>({ role }));
1809 model->emitDataChanged(this, column, roles);
1810 if (role == Qt::CheckStateRole) {
1812 for (p = par; p && (p->itemFlags & Qt::ItemIsAutoTristate); p = p->par)
1813 model->emitDataChanged(p, column, roles);
1814 }
1815 }
1816}
1817
1822{
1823 switch (role) {
1824 case Qt::EditRole:
1825 case Qt::DisplayRole:
1826 if (column >= 0 && column < d->display.size())
1827 return d->display.at(column);
1828 break;
1829 case Qt::CheckStateRole:
1830 // special case for check state in tristate
1831 if (children.size() && (itemFlags & Qt::ItemIsAutoTristate))
1832 return childrenCheckState(column);
1833 Q_FALLTHROUGH();
1834 default:
1835 if (column >= 0 && column < values.size()) {
1836 const QList<QWidgetItemData> &column_values = values.at(column);
1837 for (const auto &column_value : column_values) {
1838 if (column_value.role == role)
1839 return column_value.value;
1840 }
1841 }
1842 }
1843 return QVariant();
1844}
1845
1852{
1853 int column = view ? view->sortColumn() : 0;
1855 const QVariant v2 = other.data(column, Qt::DisplayRole);
1857}
1858
1859#ifndef QT_NO_DATASTREAM
1860
1867{
1868 // convert from streams written before we introduced display (4.2.0)
1869 if (in.version() < QDataStream::Qt_4_2) {
1870 d->display.clear();
1871 in >> values;
1872 // move the display value over to the display string list
1873 for (int column = 0; column < values.size(); ++column) {
1874 d->display << QVariant();
1875 for (int i = 0; i < values.at(column).size(); ++i) {
1876 if (values.at(column).at(i).role == Qt::DisplayRole) {
1877 d->display[column] = values.at(column).at(i).value;
1878 values[column].remove(i--);
1879 }
1880 }
1881 }
1882 } else {
1883 in >> values >> d->display;
1884 }
1885}
1886
1893{
1894 out << values << d->display;
1895}
1896#endif // QT_NO_DATASTREAM
1897
1909 : rtti(Type),
1912 itemFlags(other.itemFlags)
1913{
1914 d->display = other.d->display;
1915}
1916
1926{
1927 values = other.values;
1928 d->display = other.d->display;
1929 d->policy = other.d->policy;
1930 itemFlags = other.itemFlags;
1931 return *this;
1932}
1933
1940{
1941 if (child) {
1942 insertChild(children.size(), child);
1943 child->d->rowGuess = children.size() - 1;
1944 }
1945}
1946
1953{
1954 if (index < 0 || index > children.size() || child == nullptr || child->view != nullptr || child->par != nullptr)
1955 return;
1956
1957 if (QTreeModel *model = treeModel()) {
1958 QTreeModel::SkipSorting skipSorting(model);
1959 if (model->rootItem == this)
1960 child->par = nullptr;
1961 else
1962 child->par = this;
1963 if (view->isSortingEnabled()) {
1964 // do a delayed sort instead
1965 if (!model->sortPendingTimer.isActive())
1966 model->sortPendingTimer.start(0, model);
1967 }
1968 model->beginInsertItems(this, index, 1);
1969 int cols = model->columnCount();
1971 stack.push(child);
1972 while (!stack.isEmpty()) {
1973 QTreeWidgetItem *i = stack.pop();
1974 i->view = view;
1975 i->values.reserve(cols);
1976 for (int c = 0; c < i->children.size(); ++c)
1977 stack.push(i->children.at(c));
1978 }
1979 children.insert(index, child);
1980 d->updateHiddenStatus(child, true);
1981 model->endInsertItems();
1982 } else {
1983 child->par = this;
1984 children.insert(index, child);
1985 }
1986 if (child->par)
1988}
1989
1995{
1996 (void)takeChild(children.indexOf(child));
1997}
1998
2003{
2004 // we move this outside the check of the index to allow executing
2005 // pending sorts from inline functions, using this function (hack)
2006 QTreeModel *model = treeModel();
2007 if (model) {
2008 // This will trigger a layoutChanged signal, thus we might want to optimize
2009 // this function by not emitting the rowsRemoved signal etc to the view.
2010 // On the other hand we also need to make sure that the selectionmodel
2011 // is updated in case we take an item that is selected.
2012 model->skipPendingSort = false;
2013 model->executePendingSort();
2014 }
2015 if (index >= 0 && index < children.size()) {
2016 if (model) model->beginRemoveItems(this, index, 1);
2017 d->updateHiddenStatus(children.at(index), false);
2018 QTreeWidgetItem *item = children.takeAt(index);
2019 item->par = nullptr;
2021 stack.push(item);
2022 while (!stack.isEmpty()) {
2023 QTreeWidgetItem *i = stack.pop();
2024 i->view = nullptr;
2025 for (int c = 0; c < i->children.size(); ++c)
2026 stack.push(i->children.at(c));
2027 }
2029 if (model) model->endRemoveRows();
2030 return item;
2031 }
2032 return nullptr;
2033}
2034
2043{
2044 insertChildren(this->children.size(), children);
2045}
2046
2055{
2056 if (index < 0 || index > this->children.size() || children.isEmpty())
2057 return;
2058
2059 if (view && view->isSortingEnabled()) {
2060 for (int n = 0; n < children.size(); ++n)
2061 insertChild(index, children.at(n));
2062 return;
2063 }
2064 QTreeModel *model = treeModel();
2066 QList<QTreeWidgetItem*> itemsToInsert;
2067 for (int n = 0; n < children.size(); ++n) {
2068 QTreeWidgetItem *child = children.at(n);
2069 if (child->view || child->par)
2070 continue;
2071 itemsToInsert.append(child);
2072 if (view && model) {
2073 if (child->childCount() == 0)
2074 child->view = view;
2075 else
2076 stack.push(child);
2077 }
2078 if (model && (model->rootItem == this))
2079 child->par = nullptr;
2080 else
2081 child->par = this;
2082 }
2083 if (!itemsToInsert.isEmpty()) {
2084 while (!stack.isEmpty()) {
2085 QTreeWidgetItem *i = stack.pop();
2086 i->view = view;
2087 for (int c = 0; c < i->children.size(); ++c)
2088 stack.push(i->children.at(c));
2089 }
2090 if (model) model->beginInsertItems(this, index, itemsToInsert.size());
2091 for (int n = 0; n < itemsToInsert.size(); ++n) {
2092 QTreeWidgetItem *child = itemsToInsert.at(n);
2093 this->children.insert(index + n, child);
2094 if (child->par)
2096 d->updateHiddenStatus(child, true);
2097 }
2098 if (model) model->endInsertItems();
2099 }
2100}
2101
2108{
2110 if (children.size() > 0) {
2111 QTreeModel *model = treeModel();
2112 if (model) {
2113 // This will trigger a layoutChanged signal, thus we might want to optimize
2114 // this function by not emitting the rowsRemoved signal etc to the view.
2115 // On the other hand we also need to make sure that the selectionmodel
2116 // is updated in case we take an item that is selected.
2117 model->executePendingSort();
2118 }
2119 if (model) model->beginRemoveItems(this, 0, children.size());
2120 for (int n = 0; n < children.size(); ++n) {
2121 QTreeWidgetItem *item = children.at(n);
2122 item->par = nullptr;
2124 stack.push(item);
2125 while (!stack.isEmpty()) {
2126 QTreeWidgetItem *i = stack.pop();
2127 i->view = nullptr;
2128 for (int c = 0; c < i->children.size(); ++c)
2129 stack.push(i->children.at(c));
2130 }
2132 }
2133 removed = children;
2134 children.clear(); // detach
2135 if (model) model->endRemoveItems();
2136 }
2137 return removed;
2138}
2139
2140
2142{
2143 QTreeModel *model = q->treeModel();
2144 if (!model)
2145 return;
2146 model->sortItems(&q->children, column, order);
2147 if (climb) {
2149 for (; it != q->children.end(); ++it) {
2150 //here we call the private object's method to avoid emitting
2151 //the layoutAboutToBeChanged and layoutChanged signals
2152 (*it)->d->sortChildren(column, order, climb);
2153 }
2154 }
2155}
2156
2165{
2166 QTreeModel *model = treeModel();
2167 if (!model)
2168 return;
2169 if (model->isChanging())
2170 return;
2171 QTreeModel::SkipSorting skipSorting(model);
2172 int oldSortColumn = view->d_func()->explicitSortColumn;
2173 view->d_func()->explicitSortColumn = column;
2175 d->sortChildren(column, order, climb);
2177 view->d_func()->explicitSortColumn = oldSortColumn;
2178}
2179
2188QVariant QTreeWidgetItem::childrenCheckState(int column) const
2189{
2190 if (column < 0)
2191 return QVariant();
2192 bool checkedChildren = false;
2193 bool uncheckedChildren = false;
2194 for (const auto *child : children) {
2196 if (!value.isValid())
2197 return QVariant();
2198
2199 switch (static_cast<Qt::CheckState>(value.toInt()))
2200 {
2201 case Qt::Unchecked:
2202 uncheckedChildren = true;
2203 break;
2204 case Qt::Checked:
2205 checkedChildren = true;
2206 break;
2208 default:
2209 return Qt::PartiallyChecked;
2210 }
2211
2212 if (uncheckedChildren && checkedChildren)
2213 return Qt::PartiallyChecked;
2214 }
2215
2216 if (uncheckedChildren)
2217 return Qt::Unchecked;
2218 else if (checkedChildren)
2219 return Qt::Checked;
2220 else
2221 return QVariant(); // value was not defined
2222}
2223
2237{
2238 itemChanged();
2239}
2240
2244void QTreeWidgetItem::itemChanged()
2245{
2246 if (QTreeModel *model = treeModel())
2247 model->itemChanged(this);
2248}
2249
2253void QTreeWidgetItem::executePendingSort() const
2254{
2255 if (QTreeModel *model = treeModel())
2256 model->executePendingSort();
2257}
2258
2263QTreeModel *QTreeWidgetItem::treeModel(QTreeWidget *v) const
2264{
2265 if (!v)
2266 v = view;
2267 return (v ? qobject_cast<QTreeModel*>(v->model()) : nullptr);
2268}
2269
2270
2271#ifndef QT_NO_DATASTREAM
2282{
2283 item.write(out);
2284 return out;
2285}
2286
2297{
2298 item.read(in);
2299 return in;
2300}
2301#endif // QT_NO_DATASTREAM
2302
2303
2305{
2306 Q_Q(QTreeWidget);
2307 emit q->itemPressed(item(index), index.column());
2308}
2309
2311{
2312 Q_Q(QTreeWidget);
2313 emit q->itemClicked(item(index), index.column());
2314}
2315
2317{
2318 Q_Q(QTreeWidget);
2319 emit q->itemDoubleClicked(item(index), index.column());
2320}
2321
2323{
2324 Q_Q(QTreeWidget);
2325 emit q->itemActivated(item(index), index.column());
2326}
2327
2329{
2330 Q_Q(QTreeWidget);
2331 emit q->itemEntered(item(index), index.column());
2332}
2333
2335{
2336 Q_Q(QTreeWidget);
2337 QTreeWidgetItem *indexItem = item(index);
2338 if (indexItem)
2339 emit q->itemChanged(indexItem, index.column());
2340}
2341
2343{
2344 Q_Q(QTreeWidget);
2345 emit q->itemExpanded(item(index));
2346}
2347
2349{
2350 Q_Q(QTreeWidget);
2351 emit q->itemCollapsed(item(index));
2352}
2353
2355 const QModelIndex &previous)
2356{
2357 Q_Q(QTreeWidget);
2358 QTreeWidgetItem *currentItem = item(current);
2359 QTreeWidgetItem *previousItem = item(previous);
2360 emit q->currentItemChanged(currentItem, previousItem);
2361}
2362
2364{
2365 if (sortingEnabled) {
2369 }
2370}
2371
2373{
2374 Q_Q(QTreeWidget);
2375 QModelIndexList indices = selected.indexes();
2376 int i;
2377 QTreeModel *m = treeModel();
2378 for (i = 0; i < indices.size(); ++i) {
2379 QTreeWidgetItem *item = m->item(indices.at(i));
2380 item->d->selected = true;
2381 }
2382
2383 indices = deselected.indexes();
2384 for (i = 0; i < indices.size(); ++i) {
2385 QTreeWidgetItem *item = m->item(indices.at(i));
2386 item->d->selected = false;
2387 }
2388
2389 emit q->itemSelectionChanged();
2390}
2391
2393 const QModelIndex &bottomRight)
2394{
2395 if (sortingEnabled && topLeft.isValid() && bottomRight.isValid()
2396 && !treeModel()->sortPendingTimer.isActive()) {
2398 if (column >= topLeft.column() && column <= bottomRight.column()) {
2400 treeModel()->ensureSorted(column, order, topLeft.row(),
2401 bottomRight.row(), topLeft.parent());
2402 }
2403 }
2404}
2405
2572{
2573 QTreeView::setModel(new QTreeModel(1, this));
2575 SLOT(_q_emitItemPressed(QModelIndex)));
2577 SLOT(_q_emitItemClicked(QModelIndex)));
2579 SLOT(_q_emitItemDoubleClicked(QModelIndex)));
2581 SLOT(_q_emitItemActivated(QModelIndex)));
2583 SLOT(_q_emitItemEntered(QModelIndex)));
2585 SLOT(_q_emitItemExpanded(QModelIndex)));
2587 SLOT(_q_emitItemCollapsed(QModelIndex)));
2589 this, SLOT(_q_emitCurrentItemChanged(QModelIndex,QModelIndex)));
2591 this, SLOT(_q_emitItemChanged(QModelIndex)));
2593 this, SLOT(_q_dataChanged(QModelIndex,QModelIndex)));
2594 connect(model(), SIGNAL(columnsRemoved(QModelIndex,int,int)),
2595 this, SLOT(_q_sort()));
2597 this, SLOT(_q_selectionChanged(QItemSelection,QItemSelection)));
2598 header()->setSectionsClickable(false);
2599}
2600
2606{
2607}
2608
2609/*
2610 Returns the number of header columns in the view.
2611
2612 \sa sortColumn(), currentColumn(), topLevelItemCount()
2613*/
2614
2616{
2617 Q_D(const QTreeWidget);
2618 return d->model->columnCount();
2619}
2620
2621/*
2622 Sets the number of header \a columns in the tree widget.
2623*/
2624
2626{
2627 Q_D(QTreeWidget);
2628 if (columns < 0)
2629 return;
2630 d->treeModel()->setColumnCount(columns);
2631}
2632
2645{
2646 Q_D(const QTreeWidget);
2647 return d->treeModel()->rootItem;
2648}
2649
2658{
2659 Q_D(const QTreeWidget);
2660 return d->treeModel()->rootItem->child(index);
2661}
2662
2673{
2674 Q_D(const QTreeWidget);
2675 return d->treeModel()->rootItem->childCount();
2676}
2677
2687{
2688 Q_D(QTreeWidget);
2689 d->treeModel()->rootItem->insertChild(index, item);
2690}
2691
2700{
2702}
2703
2712{
2713 Q_D(QTreeWidget);
2714 return d->treeModel()->rootItem->takeChild(index);
2715}
2716
2724{
2725 Q_D(const QTreeWidget);
2726 d->treeModel()->executePendingSort();
2727 return d->treeModel()->rootItem->children.indexOf(item);
2728}
2729
2740{
2741 Q_D(QTreeWidget);
2742 d->treeModel()->rootItem->insertChildren(index, items);
2743}
2744
2751{
2753}
2754
2762{
2763 Q_D(const QTreeWidget);
2764 return d->treeModel()->headerItem;
2765}
2766
2777{
2778 Q_D(QTreeWidget);
2779 if (!item)
2780 return;
2781 item->view = this;
2782
2783 int oldCount = columnCount();
2784 if (oldCount < item->columnCount())
2785 d->treeModel()->beginInsertColumns(QModelIndex(), oldCount, item->columnCount() - 1);
2786 else if (oldCount > item->columnCount())
2787 d->treeModel()->beginRemoveColumns(QModelIndex(), item->columnCount(), oldCount - 1);
2788 delete d->treeModel()->headerItem;
2789 d->treeModel()->headerItem = item;
2790 if (oldCount < item->columnCount())
2791 d->treeModel()->endInsertColumns();
2792 else if (oldCount > item->columnCount())
2793 d->treeModel()->endRemoveColumns();
2794 d->treeModel()->headerDataChanged(Qt::Horizontal, 0, oldCount);
2795}
2796
2797
2807{
2808 Q_D(QTreeWidget);
2809 if (columnCount() < labels.size())
2810 setColumnCount(labels.size());
2811 QTreeWidgetItem *item = d->treeModel()->headerItem;
2812 for (int i = 0; i < labels.size(); ++i)
2813 item->setText(i, labels.at(i));
2814}
2815
2829{
2830 Q_D(const QTreeWidget);
2831 return d->item(currentIndex());
2832}
2833
2841{
2842 return currentIndex().column();
2843}
2844
2854{
2855 setCurrentItem(item, 0);
2856}
2857
2865{
2866 Q_D(QTreeWidget);
2867 setCurrentIndex(d->index(item, column));
2868}
2869
2878 QItemSelectionModel::SelectionFlags command)
2879{
2880 Q_D(QTreeWidget);
2881 d->selectionModel->setCurrentIndex(d->index(item, column), command);
2882}
2883
2884
2892{
2893 Q_D(const QTreeWidget);
2894 return d->item(indexAt(p));
2895}
2896
2911{
2912 Q_D(const QTreeWidget);
2913 //the visual rect for an item is across all columns. So we need to determine
2914 //what is the first and last column and get their visual index rects
2915 const QModelIndex base = d->index(item);
2916 const int firstVisiblesection = header()->logicalIndexAt(- header()->offset());
2917 const int lastVisibleSection = header()->logicalIndexAt(header()->length() - header()->offset() - 1);
2918 const QModelIndex first = base.sibling(base.row(), firstVisiblesection);
2919 const QModelIndex last = base.sibling(base.row(), lastVisibleSection);
2920 return visualRect(first) | visualRect(last);
2921}
2922
2931{
2932 Q_D(const QTreeWidget);
2933 return (d->explicitSortColumn != -1
2934 ? d->explicitSortColumn
2936}
2937
2946{
2947 Q_D(QTreeWidget);
2949 d->model->sort(column, order);
2950}
2951
2957{
2958 Q_D(QTreeWidget);
2959 edit(d->index(item, column));
2960}
2961
2969{
2970 Q_D(QTreeWidget);
2972}
2973
2984{
2985 Q_D(QTreeWidget);
2987}
2988
2999{
3000 Q_D(const QTreeWidget);
3002}
3003
3011{
3012 Q_D(const QTreeWidget);
3014}
3015
3040{
3041 Q_D(QTreeWidget);
3043}
3044
3051{
3052 Q_D(const QTreeWidget);
3053 const QModelIndexList indexes = selectionModel()->selectedIndexes();
3055 items.reserve(indexes.size());
3057 for (const auto &index : indexes) {
3058 QTreeWidgetItem *item = d->item(index);
3059 if (item->isHidden() || seen.hasSeen(item))
3060 continue;
3061 items.append(item);
3062 }
3063 return items;
3064}
3065
3070{
3071 Q_D(const QTreeWidget);
3072 QModelIndexList indexes = d->model->match(model()->index(0, column, QModelIndex()),
3073 Qt::DisplayRole, text, -1, flags);
3075 const int indexesSize = indexes.size();
3076 items.reserve(indexesSize);
3077 for (int i = 0; i < indexesSize; ++i)
3078 items.append(d->item(indexes.at(i)));
3079 return items;
3080}
3081
3082
3089{
3090 Q_D(const QTreeWidget);
3091 if (item == d->treeModel()->headerItem)
3092 return nullptr;
3093 const QModelIndex index = d->index(item);
3094 const QModelIndex above = indexAbove(index);
3095 return d->item(above);
3096}
3097
3104{
3105 Q_D(const QTreeWidget);
3106 if (item == d->treeModel()->headerItem)
3107 return nullptr;
3108 const QModelIndex index = d->index(item);
3109 const QModelIndex below = indexBelow(index);
3110 return d->item(below);
3111}
3112
3117{
3118 Q_D(QTreeWidget);
3120 QItemSelection newSelection = selectionModel->selection();
3121 if (!newSelection.isEmpty())
3122 d->_q_selectionChanged(newSelection, QItemSelection());
3123}
3124
3132{
3133 Q_D(QTreeWidget);
3134 QTreeView::scrollTo(d->index(item), hint);
3135}
3136
3144{
3145 Q_D(QTreeWidget);
3146 QTreeModel::SkipSorting skipSorting(d->treeModel());
3147 expand(d->index(item));
3148}
3149
3157{
3158 Q_D(QTreeWidget);
3159 QTreeModel::SkipSorting skipSorting(d->treeModel());
3160 collapse(d->index(item));
3161}
3162
3173{
3174 Q_D(QTreeWidget);
3175 selectionModel()->clear();
3176 d->treeModel()->clear();
3177}
3178
3186{
3187 return model()->QAbstractItemModel::mimeTypes();
3188}
3189
3199{
3200 Q_D(const QTreeWidget);
3201 if (d->treeModel()->cachedIndexes.isEmpty()) {
3202 QList<QModelIndex> indexes;
3203 for (const auto *item : items) {
3204 if (Q_UNLIKELY(!item)) {
3205 qWarning("QTreeWidget::mimeData: Null-item passed");
3206 return nullptr;
3207 }
3208
3209 for (int c = 0; c < item->values.size(); ++c) {
3211 if (Q_UNLIKELY(!index.isValid())) {
3212 qWarning() << "QTreeWidget::mimeData: No index associated with item :" << item;
3213 return nullptr;
3214 }
3215 indexes << index;
3216 }
3217 }
3218 return d->model->QAbstractItemModel::mimeData(indexes);
3219 }
3220 return d->treeModel()->internalMimeData();
3221}
3222
3234 const QMimeData *data, Qt::DropAction action)
3235{
3236 QModelIndex idx;
3237 if (parent) idx = indexFromItem(parent);
3238 return model()->QAbstractItemModel::dropMimeData(data, action , index, 0, idx);
3239}
3240
3247{
3248 return model()->QAbstractItemModel::supportedDropActions() | Qt::MoveAction;
3249}
3250
3259{
3260 Q_D(const QTreeWidget);
3261 return d->index(item, column);
3262}
3263
3270{
3271 Q_D(const QTreeWidget);
3272 return d->item(index);
3273}
3274
3275#if QT_CONFIG(draganddrop)
3277void QTreeWidget::dropEvent(QDropEvent *event) {
3278 Q_D(QTreeWidget);
3279 if (event->source() == this && (event->dropAction() == Qt::MoveAction ||
3280 dragDropMode() == QAbstractItemView::InternalMove)) {
3281 QModelIndex topIndex;
3282 int col = -1;
3283 int row = -1;
3284 // check whether a subclass has already accepted the event, ie. moved the data
3285 if (!event->isAccepted() && d->dropOn(event, &row, &col, &topIndex)) {
3286 const QList<QModelIndex> idxs = selectedIndexes();
3288 const int indexesCount = idxs.size();
3289 indexes.reserve(indexesCount);
3290 for (const auto &idx : idxs)
3291 indexes.append(idx);
3292
3293 if (indexes.contains(topIndex))
3294 return;
3295
3296 // When removing items the drop location could shift
3297 QPersistentModelIndex dropRow = model()->index(row, col, topIndex);
3298
3299 // Remove the items
3301 for (const auto &index : indexes) {
3303 if (!parent || !parent->parent()) {
3304 taken.append(takeTopLevelItem(index.row()));
3305 } else {
3306 taken.append(parent->parent()->takeChild(index.row()));
3307 }
3308 }
3309
3310 // insert them back in at their new positions
3311 for (int i = 0; i < indexes.size(); ++i) {
3312 // Either at a specific point or appended
3313 if (row == -1) {
3314 if (topIndex.isValid()) {
3316 parent->insertChild(parent->childCount(), taken.takeFirst());
3317 } else {
3319 }
3320 } else {
3321 int r = dropRow.row() >= 0 ? dropRow.row() : row;
3322 if (topIndex.isValid()) {
3324 parent->insertChild(qMin(r, parent->childCount()), taken.takeFirst());
3325 } else {
3327 }
3328 }
3329 }
3330
3331 event->accept();
3332 }
3333 // either we or a subclass accepted the move event, so assume that the data was
3334 // moved and that QAbstractItemView shouldn't remove the source when QDrag::exec returns
3335 if (event->isAccepted())
3336 d->dropEventMoved = true;
3337 }
3338
3339 QTreeView::dropEvent(event);
3340}
3341#endif
3342
3348{
3349 Q_ASSERT(!"QTreeWidget::setModel() - Changing the model of the QTreeWidget is not allowed.");
3350}
3351
3356{
3357 Q_D(QTreeWidget);
3358 if (e->type() == QEvent::Polish)
3359 d->treeModel()->executePendingSort();
3360 return QTreeView::event(e);
3361}
3362
3367{
3368 q_func()->executePendingSort();
3369}
3370
3372
3373#include "moc_qtreewidget.cpp"
3374#include "moc_qtreewidget_p.cpp"
static bool variantLessThan(const QVariant &v1, const QVariant &v2)
struct QAbstractItemModelPrivate::Persistent persistent
Q_INVOKABLE int const QModelIndex & parent
Returns the parent of the model item with the given index.
void endResetModel()
Completes a model reset operation.
void endRemoveRows()
Ends a row removal operation.
QModelIndexList persistentIndexList() const
void beginRemoveColumns(const QModelIndex &parent, int first, int last)
Begins a column removal operation.
void changePersistentIndexList(const QModelIndexList &from, const QModelIndexList &to)
void layoutAboutToBeChanged(const QList< QPersistentModelIndex > &parents=QList< QPersistentModelIndex >(), QAbstractItemModel::LayoutChangeHint hint=QAbstractItemModel::NoLayoutChangeHint)
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QList< int > &roles=QList< int >())
This signal is emitted whenever the data in an existing item changes.
virtual QMimeData * mimeData(const QModelIndexList &indexes) const
Returns an object that contains serialized items of data corresponding to the list of indexes specifi...
void layoutChanged(const QList< QPersistentModelIndex > &parents=QList< QPersistentModelIndex >(), QAbstractItemModel::LayoutChangeHint hint=QAbstractItemModel::NoLayoutChangeHint)
bool checkIndex(const QModelIndex &index, CheckIndexOptions options=CheckIndexOption::NoOption) const
void headerDataChanged(Qt::Orientation orientation, int first, int last)
This signal is emitted whenever a header is changed.
void beginInsertColumns(const QModelIndex &parent, int first, int last)
Begins a column insertion operation.
void endInsertRows()
Ends a row insertion operation.
void beginResetModel()
Begins a model reset operation.
void endRemoveColumns()
Ends a column removal operation.
QModelIndex createIndex(int row, int column, const void *data=nullptr) const
Creates a model index for the given row and column with the internal pointer ptr.
void endInsertColumns()
Ends a column insertion operation.
void beginRemoveRows(const QModelIndex &parent, int first, int last)
Begins a row removal operation.
virtual Q_INVOKABLE QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const =0
Returns the index of the item in the model specified by the given row, column and parent index.
void beginInsertRows(const QModelIndex &parent, int first, int last)
Begins a row insertion operation.
QWidget * indexWidget(const QModelIndex &index) const
void activated(const QModelIndex &index)
This signal is emitted when the item specified by index is activated by the user.
QAbstractItemModel * model() const
Returns the model that this view is presenting.
void setCurrentIndex(const QModelIndex &index)
Sets the current item to be the item at index.
void doubleClicked(const QModelIndex &index)
This signal is emitted when a mouse button is double-clicked.
bool event(QEvent *event) override
\reimp
void entered(const QModelIndex &index)
This signal is emitted when the mouse cursor enters the item specified by index.
virtual void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
This slot is called when the selection is changed.
virtual void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QList< int > &roles=QList< int >())
This slot is called when items with the given roles are changed in the model.
QModelIndex currentIndex() const
Returns the model index of the current item.
bool isPersistentEditorOpen(const QModelIndex &index) const
void setIndexWidget(const QModelIndex &index, QWidget *widget)
virtual void currentChanged(const QModelIndex &current, const QModelIndex &previous)
This slot is called when a new item becomes the current item.
void scheduleDelayedItemsLayout()
Schedules a layout of the items in the view to be executed when the event processing starts.
void openPersistentEditor(const QModelIndex &index)
Opens a persistent editor on the item at the given index.
void pressed(const QModelIndex &index)
This signal is emitted when a mouse button is pressed.
ScrollHint
\value EnsureVisible Scroll to ensure that the item is visible.
void clicked(const QModelIndex &index)
This signal is emitted when a mouse button is left-clicked.
void edit(const QModelIndex &index)
Starts editing the item corresponding to the given index if it is editable.
QItemSelectionModel * selectionModel() const
Returns the current selection model.
void closePersistentEditor(const QModelIndex &index)
Closes the persistent editor for the item at the given index.
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
Returns the index of the data in row and column with parent.
int timerId() const noexcept
Returns the timer's ID.
Definition qbasictimer.h:35
void stop()
Stops the timer.
\inmodule QtCore\reentrant
Definition qdatastream.h:30
bool hasSeen(const T &s)
\inmodule QtCore
Definition qcoreevent.h:45
void setSectionsClickable(bool clickable)
void setSortIndicator(int logicalIndex, Qt::SortOrder order)
Sets the sort indicator for the section specified by the given logicalIndex in the direction specifie...
Qt::SortOrder sortIndicatorOrder() const
Returns the order for the sort indicator.
int logicalIndexAt(int position) const
Returns the section that covers the given position in the viewport.
int sortIndicatorSection() const
Returns the logical index of the section that has a sort indicator.
QModelIndexList selectedIndexes
virtual void select(const QModelIndex &index, QItemSelectionModel::SelectionFlags command)
Selects the model item index using the specified command, and emits selectionChanged().
virtual void clear()
Clears the selection model.
\inmodule QtCore
Q_CORE_EXPORT QModelIndexList indexes() const
Returns a list of model indexes that correspond to the selected items.
Definition qlist.h:74
qsizetype size() const noexcept
Definition qlist.h:386
bool isEmpty() const noexcept
Definition qlist.h:390
T & first()
Definition qlist.h:628
iterator erase(const_iterator begin, const_iterator end)
Definition qlist.h:882
iterator insert(qsizetype i, parameter_type t)
Definition qlist.h:471
iterator end()
Definition qlist.h:609
T takeAt(qsizetype i)
Definition qlist.h:592
const_reference at(qsizetype i) const noexcept
Definition qlist.h:429
value_type takeFirst()
Definition qlist.h:549
iterator begin()
Definition qlist.h:608
void reserve(qsizetype size)
Definition qlist.h:746
void replace(qsizetype i, parameter_type t)
Definition qlist.h:526
void resize(qsizetype size)
Definition qlist.h:392
const_iterator cend() const noexcept
Definition qlist.h:614
void append(parameter_type t)
Definition qlist.h:441
const_iterator cbegin() const noexcept
Definition qlist.h:613
void clear()
Definition qlist.h:417
Definition qmap.h:186
iterator insert(const Key &key, const T &value)
Definition qmap.h:687
\inmodule QtCore
Definition qmimedata.h:16
\inmodule QtCore
constexpr int row() const noexcept
Returns the row this model index refers to.
QModelIndex parent() const
Returns the parent of the model index, or QModelIndex() if it has no parent.
constexpr int column() const noexcept
Returns the column this model index refers to.
constexpr bool isValid() const noexcept
Returns {true} if this model index is valid; otherwise returns {false}.
bool contains(const Key &key) const noexcept
Definition qhash.h:1567
const QObjectList & children() const
Returns a list of child objects.
Definition qobject.h:171
virtual void timerEvent(QTimerEvent *event)
This event handler can be reimplemented in a subclass to receive timer events for the object.
Definition qobject.cpp:1433
bool signalsBlocked() const noexcept
Returns true if signals are blocked; otherwise returns false.
Definition qobject.h:122
QScopedPointer< QObjectData > d_ptr
Definition qobject.h:338
int row() const
Returns the row this persistent model index refers to.
\inmodule QtCore\reentrant
Definition qpoint.h:23
\inmodule QtCore\reentrant
Definition qrect.h:30
T * data() const noexcept
Returns the value of the pointer referenced by this object.
iterator begin()
Definition qset.h:136
iterator end()
Definition qset.h:140
int columnCount(const QModelIndex &parent=QModelIndex()) const override
\reimp
\inmodule QtCore
Definition qstack.h:13
T pop()
Removes the top item from the stack and returns it.
Definition qstack.h:18
void push(const T &t)
Adds element t to the top of the stack.
Definition qstack.h:17
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:7822
\inmodule QtCore
Definition qcoreevent.h:359
int timerId() const
Returns the unique timer identifier, which is the same identifier as returned from QObject::startTime...
Definition qcoreevent.h:363
bool operator()(QTreeWidgetItem *i1, QTreeWidgetItem *i2) const
bool operator()(QTreeWidgetItem *i1, QTreeWidgetItem *i2) const
void executePendingOperations() const override
see QTBUG-94546
bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role) override
void ensureSorted(int column, Qt::SortOrder order, int start, int end, const QModelIndex &parent)
int rowCount(const QModelIndex &parent) const override
bool setData(const QModelIndex &index, const QVariant &value, int role) override
bool insertColumns(int column, int count, const QModelIndex &) override
QTreeWidget * view() const
void emitDataChanged(QTreeWidgetItem *item, int column, const QList< int > &roles)
bool removeRows(int row, int count, const QModelIndex &parent=QModelIndex()) override
void endInsertItems()
void itemChanged(QTreeWidgetItem *item)
void setColumnCount(int columns)
friend class QTreeWidgetItem
bool insertRows(int row, int count, const QModelIndex &) override
void sortItems(QList< QTreeWidgetItem * > *items, int column, Qt::SortOrder order)
QMimeData * internalMimeData() const
QTreeWidgetItem * item(const QModelIndex &index) const
Qt::DropActions supportedDropActions() const override
QMimeData * mimeData(const QModelIndexList &indexes) const override
Returns an object that contains serialized items of data corresponding to the list of indexes specifi...
QTreeModel(int columns=0, QTreeWidget *parent=nullptr)
int columnCount(const QModelIndex &parent=QModelIndex()) const override
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
void sort(int column, Qt::SortOrder order) override
static bool itemLessThan(const QPair< QTreeWidgetItem *, int > &left, const QPair< QTreeWidgetItem *, int > &right)
QVariant headerData(int section, Qt::Orientation orientation, int role) const override
Qt::ItemFlags flags(const QModelIndex &index) const override
\reimp
bool clearItemData(const QModelIndex &index) override
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override
Handles the data supplied by a drag and drop operation that ended with the given action.
static QList< QTreeWidgetItem * >::iterator sortedInsertionIterator(const QList< QTreeWidgetItem * >::iterator &begin, const QList< QTreeWidgetItem * >::iterator &end, Qt::SortOrder order, QTreeWidgetItem *item)
QStringList mimeTypes() const override
Returns the list of allowed MIME types.
QMap< int, QVariant > itemData(const QModelIndex &index) const override
Returns a map with values for all predefined roles in the model for the item at the given index.
QModelIndex index(const QTreeWidgetItem *item, int column) const
bool hasChildren(const QModelIndex &parent) const override
Returns {true} if parent has any children; otherwise returns {false}.
void timerEvent(QTimerEvent *) override
This event handler can be reimplemented in a subclass to receive timer events for the object.
void beginRemoveItems(QTreeWidgetItem *parent, int row, int count)
void beginInsertItems(QTreeWidgetItem *parent, int row, int count)
void endRemoveItems()
static bool itemGreaterThan(const QPair< QTreeWidgetItem *, int > &left, const QPair< QTreeWidgetItem *, int > &right)
QHeaderView * header
The QTreeView class provides a default model/view implementation of a tree view.
Definition qtreeview.h:20
bool isSortingEnabled() const
void expand(const QModelIndex &index)
Expands the model item specified by the index.
void setSelectionModel(QItemSelectionModel *selectionModel) override
\reimp
void collapse(const QModelIndex &index)
Collapses the model item specified by the index.
void setModel(QAbstractItemModel *model) override
\reimp
QModelIndex indexBelow(const QModelIndex &index) const
Returns the model index of the item below index.
bool isExpanded(const QModelIndex &index) const
Returns true if the model item index is expanded; otherwise returns false.
QHeaderView * header() const
Returns the header for the tree view.
void setExpanded(const QModelIndex &index, bool expand)
Sets the item referred to by index to either collapse or expanded, depending on the value of expanded...
QModelIndex indexAt(const QPoint &p) const override
\reimp
QModelIndex indexAbove(const QModelIndex &index) const
Returns the model index of the item above index.
void setFirstColumnSpanned(int row, const QModelIndex &parent, bool span)
QModelIndexList selectedIndexes() const override
\reimp
void collapsed(const QModelIndex &index)
This signal is emitted when the item specified by index is collapsed.
void scrollTo(const QModelIndex &index, ScrollHint hint=EnsureVisible) override
Scroll the contents of the tree view until the given model item index is visible.
void setRowHidden(int row, const QModelIndex &parent, bool hide)
If hide is true the row with the given parent is hidden, otherwise the row is shown.
bool isRowHidden(int row, const QModelIndex &parent) const
Returns true if the item in the given row of the parent is hidden; otherwise returns false.
QRect visualRect(const QModelIndex &index) const override
Returns the rectangle on the viewport occupied by the item at index.
bool isFirstColumnSpanned(int row, const QModelIndex &parent) const
void expanded(const QModelIndex &index)
This signal is emitted when the item specified by index is expanded.
void sortChildren(int column, Qt::SortOrder order, bool climb)
void updateHiddenStatus(QTreeWidgetItem *item, bool inserting)
QTreeWidgetItem::ChildIndicatorPolicy policy
void propagateDisabled(QTreeWidgetItem *item)
The QTreeWidgetItem class provides an item for use with the QTreeWidget convenience class.
Definition qtreewidget.h:23
void setChildIndicatorPolicy(QTreeWidgetItem::ChildIndicatorPolicy policy)
Sets the item indicator policy.
void insertChildren(int index, const QList< QTreeWidgetItem * > &children)
void setExpanded(bool expand)
void setHidden(bool hide)
void setText(int column, const QString &text)
Sets the text to be displayed in the given column to the given text.
QTreeWidgetItem & operator=(const QTreeWidgetItem &other)
Assigns other's data and flags to this item.
QTreeWidgetItem * child(int index) const
Returns the item at the given index in the list of the item's children.
bool isFirstColumnSpanned() const
bool isSelected() const
QTreeWidgetItem * takeChild(int index)
Removes the item at index and returns it, otherwise return 0.
virtual bool operator<(const QTreeWidgetItem &other) const
Returns true if the text in the item is less than the text in the other item, otherwise returns false...
virtual void setData(int column, int role, const QVariant &value)
Sets the value for the item's column and role to the given value.
void setFirstColumnSpanned(bool span)
QTreeWidgetItem(int type=Type)
Constructs a tree widget item of the specified type.
virtual void read(QDataStream &in)
Reads the item from stream in.
QTreeWidgetItem * parent() const
Returns the item's parent.
void insertChild(int index, QTreeWidgetItem *child)
Inserts the child item at index in the list of children.
void addChildren(const QList< QTreeWidgetItem * > &children)
void setFlags(Qt::ItemFlags flags)
Sets the flags for the item to the given flags.
QDataStream & operator<<(QDataStream &out, const QTreeWidgetItem &item)
Writes the tree widget item item to stream out.
bool isHidden() const
void sortChildren(int column, Qt::SortOrder order)
@ DontShowIndicatorWhenChildless
Definition qtreewidget.h:61
QDataStream & operator>>(QDataStream &in, QTreeWidgetItem &item)
Reads a tree widget item from stream in into item.
int childCount() const
Returns the number of child items.
virtual ~QTreeWidgetItem()
Destroys this tree widget item.
void setSelected(bool select)
Qt::ItemFlags flags() const
Returns the flags used to describe the item.
void removeChild(QTreeWidgetItem *child)
Removes the given item indicated by child.
QTreeWidgetItem::ChildIndicatorPolicy childIndicatorPolicy() const
Returns the item indicator policy.
bool isExpanded() const
int columnCount() const
Returns the number of columns in the item.
void addChild(QTreeWidgetItem *child)
Appends the child item to the list of children.
virtual QVariant data(int column, int role) const
Returns the value for the item's column and role.
virtual void write(QDataStream &out) const
Writes the item to stream out.
virtual QTreeWidgetItem * clone() const
Creates a deep copy of the item and of its children.
QList< QTreeWidgetItem * > takeChildren()
QTreeModel * treeModel() const
void _q_emitItemChanged(const QModelIndex &index)
void _q_emitItemCollapsed(const QModelIndex &index)
void _q_emitItemDoubleClicked(const QModelIndex &index)
void _q_emitItemEntered(const QModelIndex &index)
void _q_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
void _q_emitItemClicked(const QModelIndex &index)
void _q_emitItemActivated(const QModelIndex &index)
void _q_selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
void _q_emitCurrentItemChanged(const QModelIndex &previous, const QModelIndex &index)
void _q_emitItemPressed(const QModelIndex &index)
void _q_emitItemExpanded(const QModelIndex &index)
The QTreeWidget class provides a tree view that uses a predefined tree model.
void expandItem(const QTreeWidgetItem *item)
Expands the item.
void addTopLevelItems(const QList< QTreeWidgetItem * > &items)
Appends the list of items as a top-level items in the widget.
QTreeWidgetItem * topLevelItem(int index) const
Returns the top level item at the given index, or \nullptr if the item does not exist.
~QTreeWidget()
Destroys the tree widget and all its items.
QModelIndex indexFromItem(const QTreeWidgetItem *item, int column=0) const
Returns the QModelIndex associated with the given item in the given column.
void sortItems(int column, Qt::SortOrder order)
Sorts the items in the widget in the specified order by the values in the given column.
void closePersistentEditor(QTreeWidgetItem *item, int column=0)
Closes the persistent editor for the item in the given column.
QTreeWidgetItem * invisibleRootItem() const
QList< QTreeWidgetItem * > findItems(const QString &text, Qt::MatchFlags flags, int column=0) const
Returns a list of items that match the given text, using the given flags, in the given column.
QRect visualItemRect(const QTreeWidgetItem *item) const
Returns the rectangle on the viewport occupied by the item at item.
virtual bool dropMimeData(QTreeWidgetItem *parent, int index, const QMimeData *data, Qt::DropAction action)
Handles the data supplied by a drag and drop operation that ended with the given action in the index ...
void addTopLevelItem(QTreeWidgetItem *item)
bool event(QEvent *e) override
\reimp
QWidget * itemWidget(QTreeWidgetItem *item, int column) const
void collapseItem(const QTreeWidgetItem *item)
Closes the item.
QTreeWidgetItem * takeTopLevelItem(int index)
Removes the top-level item at the given index in the tree and returns it, otherwise returns \nullptr;...
virtual QMimeData * mimeData(const QList< QTreeWidgetItem * > &items) const
Returns an object that contains a serialized description of the specified items.
friend class QTreeModel
void clear()
Clears the tree widget by removing all of its items and selections.
void openPersistentEditor(QTreeWidgetItem *item, int column=0)
Opens a persistent editor for the item in the given column.
QTreeWidget(QWidget *parent=nullptr)
Constructs a tree widget with the given parent.
virtual QStringList mimeTypes() const
Returns a list of MIME types that can be used to describe a list of treewidget items.
QTreeWidgetItem * itemAbove(const QTreeWidgetItem *item) const
void insertTopLevelItems(int index, const QList< QTreeWidgetItem * > &items)
void setSelectionModel(QItemSelectionModel *selectionModel) override
\reimp
void setItemWidget(QTreeWidgetItem *item, int column, QWidget *widget)
QList< QTreeWidgetItem * > selectedItems() const
Returns a list of all selected non-hidden items.
void editItem(QTreeWidgetItem *item, int column=0)
Starts editing the item in the given column if it is editable.
QTreeWidgetItem * itemAt(const QPoint &p) const
Returns a pointer to the item at the coordinates p.
int columnCount
the number of columns displayed in the tree widget
void setCurrentItem(QTreeWidgetItem *item)
Sets the current item in the tree widget.
void insertTopLevelItem(int index, QTreeWidgetItem *item)
Inserts the item at index in the top level in the view.
QTreeWidgetItem * headerItem() const
Returns the item used for the tree widget's header.
void setModel(QAbstractItemModel *model) override
\reimp
void setHeaderItem(QTreeWidgetItem *item)
Sets the header item for the tree widget.
int sortColumn() const
int indexOfTopLevelItem(QTreeWidgetItem *item) const
Returns the index of the given top-level item, or -1 if the item cannot be found.
QTreeWidgetItem * itemFromIndex(const QModelIndex &index) const
Returns a pointer to the QTreeWidgetItem associated with the given index.
QTreeWidgetItem * itemBelow(const QTreeWidgetItem *item) const
QTreeWidgetItem * currentItem() const
Returns the current item in the tree widget.
virtual Qt::DropActions supportedDropActions() const
Returns the drop actions supported by this view.
void scrollToItem(const QTreeWidgetItem *item, QAbstractItemView::ScrollHint hint=EnsureVisible)
Ensures that the item is visible, scrolling the view if necessary using the specified hint.
int topLevelItemCount
the number of top-level items
bool isPersistentEditorOpen(QTreeWidgetItem *item, int column=0) const
void setColumnCount(int columns)
void setHeaderLabels(const QStringList &labels)
Adds a column in the header for each item in the labels list, and sets the label for each column.
int currentColumn() const
\inmodule QtCore
Definition qvariant.h:64
T value() const &
Definition qvariant.h:511
bool isValid() const
Returns true if the storage type of this variant is not QMetaType::UnknownType; otherwise returns fal...
Definition qvariant.h:707
The QWidget class is the base class of all user interface objects.
Definition qwidget.h:99
#define this
Definition dialogs.cpp:9
QOpenGLWidget * widget
[1]
QString text
double pi
[0]
list append(new Employee("Blackpool", "Stephen"))
double e
QSet< QString >::iterator it
struct wl_display * display
Definition linuxdmabuf.h:41
Combined button and popup list for selecting options.
CheckState
@ Unchecked
@ Checked
@ PartiallyChecked
Orientation
Definition qnamespace.h:97
@ Horizontal
Definition qnamespace.h:98
@ EditRole
@ CheckStateRole
@ DisplayRole
SortOrder
Definition qnamespace.h:120
@ AscendingOrder
Definition qnamespace.h:121
DropAction
@ MoveAction
@ ItemIsEnabled
@ ItemIsDropEnabled
@ ItemIsAutoTristate
static jboolean copy(JNIEnv *, jobject)
#define Q_FALLTHROUGH()
#define Q_UNLIKELY(x)
std::pair< T1, T2 > QPair
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define qWarning
Definition qlogging.h:162
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
constexpr const T & qBound(const T &min, const T &val, const T &max)
Definition qminmax.h:44
#define SLOT(a)
Definition qobjectdefs.h:51
#define SIGNAL(a)
Definition qobjectdefs.h:52
GLint GLfloat GLfloat GLfloat v2
GLenum GLsizei GLsizei GLint * values
[15]
GLsizei const GLfloat * v
[13]
const GLfloat * m
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint index
[2]
GLboolean r
[2]
GLuint GLuint end
GLsizei const GLchar ** strings
[1]
GLenum GLuint GLenum GLsizei length
GLenum GLenum GLsizei count
GLdouble GLdouble right
GLfloat GLfloat f
GLint left
GLenum type
GLbitfield flags
GLint GLfloat GLfloat v1
GLboolean enable
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLuint start
GLenum GLuint GLintptr offset
GLint first
GLfloat n
GLsizei GLenum const void * indices
GLenum GLenum GLsizei void GLsizei void * column
struct _cl_event * event
const GLubyte * c
GLuint in
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLenum GLenum GLsizei void * row
GLenum GLenum GLsizei void GLsizei void void * span
GLfloat GLfloat p
[1]
GLfixed GLfixed GLint GLint order
const QQuickItem * rootItem(const I &item)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator begin(const QRegularExpressionMatchIterator &iterator)
static QList< QVariant > toList(char **buf, int count)
static QT_BEGIN_NAMESPACE QVariant hint(QPlatformIntegration::StyleHint h)
#define emit
#define Q_UNUSED(x)
static int compare(quint64 a, quint64 b)
QSqlQueryModel * model
[16]
QTextStream out(stdout)
[7]
connect(quitButton, &QPushButton::clicked, &app, &QCoreApplication::quit, Qt::QueuedConnection)
QMimeData * mimeData
QObject::connect nullptr
QSharedPointer< T > other(t)
[5]
QGraphicsItem * item
edit hide()
selection select(topLeft, bottomRight)
QList< QTreeWidgetItem * > items
QLayoutItem * child
[0]
QSizePolicy policy
QMultiHash< QModelIndex, QPersistentModelIndexData * > indexes
qsizetype indexOf(const AT &t, qsizetype from=0) const noexcept
Definition qlist.h:955
bool contains(const AT &t) const noexcept
Definition qlist.h:44
qsizetype lastIndexOf(const AT &t, qsizetype from=-1) const noexcept
Definition qlist.h:962
Definition moc.h:24
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent