Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qlistwidget.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5#include "qlistwidget.h"
6
7#include <private/qlistview_p.h>
8#include <private/qwidgetitemdata_p.h>
9#include <private/qlistwidget_p.h>
10
11#include <algorithm>
12
13QT_BEGIN_NAMESPACE
14
15class QListWidgetMimeData : public QMimeData
16{
17 Q_OBJECT
18public:
19 QList<QListWidgetItem*> items;
20};
21
22QT_BEGIN_INCLUDE_NAMESPACE
23#include "qlistwidget.moc"
24QT_END_INCLUDE_NAMESPACE
25
26QListModel::QListModel(QListWidget *parent)
27 : QAbstractListModel(parent)
28{
29}
30
31QListModel::~QListModel()
32{
33 clear();
34}
35
36void QListModel::clear()
37{
38 beginResetModel();
39 for (int i = 0; i < items.size(); ++i) {
40 if (items.at(i)) {
41 items.at(i)->d->theid = -1;
42 items.at(i)->view = nullptr;
43 delete items.at(i);
44 }
45 }
46 items.clear();
47 endResetModel();
48}
49
50QListWidgetItem *QListModel::at(int row) const
51{
52 return items.value(row);
53}
54
55void QListModel::remove(QListWidgetItem *item)
56{
57 if (!item)
58 return;
59 int row = items.indexOf(item); // ### use index(item) - it's faster
60 Q_ASSERT(row != -1);
61 beginRemoveRows(QModelIndex(), row, row);
62 items.at(row)->d->theid = -1;
63 items.at(row)->view = nullptr;
64 items.removeAt(row);
65 endRemoveRows();
66}
67
68void QListModel::insert(int row, QListWidgetItem *item)
69{
70 if (!item)
71 return;
72
73 item->view = this->view();
74 if (item->view && item->view->isSortingEnabled()) {
75 // sorted insertion
76 QList<QListWidgetItem*>::iterator it;
77 it = sortedInsertionIterator(items.begin(), items.end(),
78 item->view->sortOrder(), item);
79 row = qMax<qsizetype>(it - items.begin(), 0);
80 } else {
81 if (row < 0)
82 row = 0;
83 else if (row > items.size())
84 row = items.size();
85 }
86 beginInsertRows(QModelIndex(), row, row);
87 items.insert(row, item);
88 item->d->theid = row;
89 endInsertRows();
90}
91
92void QListModel::insert(int row, const QStringList &labels)
93{
94 const int count = labels.size();
95 if (count <= 0)
96 return;
97 QListWidget *view = this->view();
98 if (view && view->isSortingEnabled()) {
99 // sorted insertion
100 for (int i = 0; i < count; ++i) {
101 QListWidgetItem *item = new QListWidgetItem(labels.at(i));
102 insert(row, item);
103 }
104 } else {
105 if (row < 0)
106 row = 0;
107 else if (row > items.size())
108 row = items.size();
109 beginInsertRows(QModelIndex(), row, row + count - 1);
110 for (int i = 0; i < count; ++i) {
111 QListWidgetItem *item = new QListWidgetItem(labels.at(i));
112 item->d->theid = row;
113 item->view = this->view();
114 items.insert(row++, item);
115 }
116 endInsertRows();
117 }
118}
119
120QListWidgetItem *QListModel::take(int row)
121{
122 if (row < 0 || row >= items.size())
123 return nullptr;
124
125 beginRemoveRows(QModelIndex(), row, row);
126 items.at(row)->d->theid = -1;
127 items.at(row)->view = nullptr;
128 QListWidgetItem *item = items.takeAt(row);
129 endRemoveRows();
130 return item;
131}
132
133void QListModel::move(int srcRow, int dstRow)
134{
135 if (srcRow == dstRow
136 || srcRow < 0 || srcRow >= items.size()
137 || dstRow < 0 || dstRow > items.size())
138 return;
139
140 if (!beginMoveRows(QModelIndex(), srcRow, srcRow, QModelIndex(), dstRow))
141 return;
142 if (srcRow < dstRow)
143 --dstRow;
144 items.move(srcRow, dstRow);
145 endMoveRows();
146}
147
148int QListModel::rowCount(const QModelIndex &parent) const
149{
150 return parent.isValid() ? 0 : items.size();
151}
152
153QModelIndex QListModel::index(const QListWidgetItem *item_) const
154{
155 QListWidgetItem *item = const_cast<QListWidgetItem *>(item_);
156 if (!item || !item->view || static_cast<const QListModel *>(item->view->model()) != this
157 || items.isEmpty())
158 return QModelIndex();
159 int row;
160 const int theid = item->d->theid;
161 if (theid >= 0 && theid < items.size() && items.at(theid) == item) {
162 row = theid;
163 } else { // we need to search for the item
164 row = items.lastIndexOf(item); // lastIndexOf is an optimization in favor of indexOf
165 if (row == -1) // not found
166 return QModelIndex();
167 item->d->theid = row;
168 }
169 return createIndex(row, 0, item);
170}
171
172QModelIndex QListModel::index(int row, int column, const QModelIndex &parent) const
173{
174 if (hasIndex(row, column, parent))
175 return createIndex(row, column, items.at(row));
176 return QModelIndex();
177}
178
179QVariant QListModel::data(const QModelIndex &index, int role) const
180{
181 if (!index.isValid() || index.row() >= items.size())
182 return QVariant();
183 return items.at(index.row())->data(role);
184}
185
186bool QListModel::setData(const QModelIndex &index, const QVariant &value, int role)
187{
188 if (!index.isValid() || index.row() >= items.size())
189 return false;
190 items.at(index.row())->setData(role, value);
191 return true;
192}
193
194bool QListModel::clearItemData(const QModelIndex &index)
195{
196 if (!checkIndex(index, CheckIndexOption::IndexIsValid))
197 return false;
198 QListWidgetItem *item = items.at(index.row());
199 const auto beginIter = item->d->values.cbegin();
200 const auto endIter = item->d->values.cend();
201 if (std::all_of(beginIter, endIter, [](const QWidgetItemData& data) -> bool { return !data.value.isValid(); }))
202 return true; //it's already cleared
203 item->d->values.clear();
204 emit dataChanged(index, index, QList<int> {});
205 return true;
206}
207
208QMap<int, QVariant> QListModel::itemData(const QModelIndex &index) const
209{
210 QMap<int, QVariant> roles;
211 if (!index.isValid() || index.row() >= items.size())
212 return roles;
213 QListWidgetItem *itm = items.at(index.row());
214 for (int i = 0; i < itm->d->values.size(); ++i) {
215 roles.insert(itm->d->values.at(i).role,
216 itm->d->values.at(i).value);
217 }
218 return roles;
219}
220
221bool QListModel::insertRows(int row, int count, const QModelIndex &parent)
222{
223 if (count < 1 || row < 0 || row > rowCount() || parent.isValid())
224 return false;
225
226 beginInsertRows(QModelIndex(), row, row + count - 1);
227 QListWidget *view = this->view();
228 QListWidgetItem *itm = nullptr;
229
230 for (int r = row; r < row + count; ++r) {
231 itm = new QListWidgetItem;
232 itm->view = view;
233 itm->d->theid = r;
234 items.insert(r, itm);
235 }
236
237 endInsertRows();
238 return true;
239}
240
241bool QListModel::removeRows(int row, int count, const QModelIndex &parent)
242{
243 if (count < 1 || row < 0 || (row + count) > rowCount() || parent.isValid())
244 return false;
245
246 beginRemoveRows(QModelIndex(), row, row + count - 1);
247 QListWidgetItem *itm = nullptr;
248 for (int r = row; r < row + count; ++r) {
249 itm = items.takeAt(row);
250 itm->view = nullptr;
251 itm->d->theid = -1;
252 delete itm;
253 }
254 endRemoveRows();
255 return true;
256}
257
258/*!
259 \since 5.13
260 \reimp
261*/
262bool QListModel::moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild)
263{
264 if (sourceRow < 0
265 || sourceRow + count - 1 >= rowCount(sourceParent)
266 || destinationChild < 0
267 || destinationChild > rowCount(destinationParent)
268 || sourceRow == destinationChild
269 || sourceRow == destinationChild - 1
270 || count <= 0
271 || sourceParent.isValid()
272 || destinationParent.isValid()) {
273 return false;
274 }
275 if (!beginMoveRows(QModelIndex(), sourceRow, sourceRow + count - 1, QModelIndex(), destinationChild))
276 return false;
277
278 int fromRow = sourceRow;
279 if (destinationChild < sourceRow)
280 fromRow += count - 1;
281 else
282 destinationChild--;
283 while (count--)
284 items.move(fromRow, destinationChild);
285 endMoveRows();
286 return true;
287}
288
289Qt::ItemFlags QListModel::flags(const QModelIndex &index) const
290{
291 if (!index.isValid() || index.row() >= items.size() || index.model() != this)
292 return Qt::ItemIsDropEnabled; // we allow drops outside the items
293 return items.at(index.row())->flags();
294}
295
296void QListModel::sort(int column, Qt::SortOrder order)
297{
298 if (column != 0)
299 return;
300
301 emit layoutAboutToBeChanged({}, QAbstractItemModel::VerticalSortHint);
302
303 QList<std::pair<QListWidgetItem *, int>> sorting(items.size());
304 for (int i = 0; i < items.size(); ++i) {
305 QListWidgetItem *item = items.at(i);
306 sorting[i].first = item;
307 sorting[i].second = i;
308 }
309
310 const auto compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan);
311 std::stable_sort(sorting.begin(), sorting.end(), compare);
312 QModelIndexList fromIndexes;
313 QModelIndexList toIndexes;
314 const int sortingCount = sorting.size();
315 fromIndexes.reserve(sortingCount);
316 toIndexes.reserve(sortingCount);
317 for (int r = 0; r < sortingCount; ++r) {
318 QListWidgetItem *item = sorting.at(r).first;
319 toIndexes.append(createIndex(r, 0, item));
320 fromIndexes.append(createIndex(sorting.at(r).second, 0, sorting.at(r).first));
321 items[r] = sorting.at(r).first;
322 }
323 changePersistentIndexList(fromIndexes, toIndexes);
324
325 emit layoutChanged({}, QAbstractItemModel::VerticalSortHint);
326}
327
328/**
329 * This function assumes that all items in the model except the items that are between
330 * (inclusive) start and end are sorted.
331 */
332void QListModel::ensureSorted(int column, Qt::SortOrder order, int start, int end)
333{
334 if (column != 0)
335 return;
336
337 const auto compareLt = [](const QListWidgetItem *left, const QListWidgetItem *right) -> bool {
338 return *left < *right;
339 };
340
341 const auto compareGt = [](const QListWidgetItem *left, const QListWidgetItem *right) -> bool {
342 return *right < *left;
343 };
344
345 /** Check if range [start,end] is already in sorted position in list.
346 * Take for this the assumption, that outside [start,end] the list
347 * is already sorted. Therefore the sorted check has to be extended
348 * to the first element that is known to be sorted before the range
349 * [start, end], which is (start-1) and the first element after the
350 * range [start, end], which is (end+2) due to end being included.
351 */
352 const auto beginChangedIterator = items.constBegin() + qMax(start - 1, 0);
353 const auto endChangedIterator = items.constBegin() + qMin(end + 2, items.size());
354 const bool needsSorting = !std::is_sorted(beginChangedIterator, endChangedIterator,
355 order == Qt::AscendingOrder ? compareLt : compareGt);
356
357 if (needsSorting)
358 sort(column, order);
359}
360
361bool QListModel::itemLessThan(const std::pair<QListWidgetItem*,int> &left,
362 const std::pair<QListWidgetItem*,int> &right)
363{
364 return (*left.first) < (*right.first);
365}
366
367bool QListModel::itemGreaterThan(const std::pair<QListWidgetItem*,int> &left,
368 const std::pair<QListWidgetItem*,int> &right)
369{
370 return (*right.first) < (*left.first);
371}
372
373QList<QListWidgetItem*>::iterator QListModel::sortedInsertionIterator(
374 const QList<QListWidgetItem*>::iterator &begin,
375 const QList<QListWidgetItem*>::iterator &end,
376 Qt::SortOrder order, QListWidgetItem *item)
377{
378 if (order == Qt::AscendingOrder)
379 return std::lower_bound(begin, end, item, QListModelLessThan());
380 return std::lower_bound(begin, end, item, QListModelGreaterThan());
381}
382
383void QListModel::itemChanged(QListWidgetItem *item, const QList<int> &roles)
384{
385 const QModelIndex idx = index(item);
386 emit dataChanged(idx, idx, roles);
387}
388
389QStringList QListModel::mimeTypes() const
390{
391 const QListWidget *view = this->view();
392 if (view)
393 return view->mimeTypes();
394 return {};
395}
396
397QMimeData *QListModel::internalMimeData() const
398{
399 return QAbstractItemModel::mimeData(cachedIndexes);
400}
401
402QMimeData *QListModel::mimeData(const QModelIndexList &indexes) const
403{
404 QList<QListWidgetItem*> itemlist;
405 const int indexesCount = indexes.size();
406 itemlist.reserve(indexesCount);
407 for (int i = 0; i < indexesCount; ++i)
408 itemlist << at(indexes.at(i).row());
409
410 cachedIndexes = indexes;
411 QMimeData *mimeData = view()->mimeData(itemlist);
412 cachedIndexes.clear();
413 return mimeData;
414}
415
416#if QT_CONFIG(draganddrop)
417bool QListModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
418 int row, int column, const QModelIndex &index)
419{
420 Q_UNUSED(column);
421 if (index.isValid())
422 row = index.row();
423 else if (row == -1)
424 row = items.size();
425
426 return view()->dropMimeData(row, data, action);
427}
428
429Qt::DropActions QListModel::supportedDropActions() const
430{
431 return view()->supportedDropActions();
432}
433
434Qt::DropActions QListModel::supportedDragActions() const
435{
436 return view()->supportedDragActions();
437}
438
439#endif // QT_CONFIG(draganddrop)
440
441/*!
442 \class QListWidgetItem
443 \brief The QListWidgetItem class provides an item for use with the
444 QListWidget item view class.
445
446 \ingroup model-view
447 \inmodule QtWidgets
448
449 A QListWidgetItem represents a single item in a QListWidget. Each item can
450 hold several pieces of information, and will display them appropriately.
451
452 The item view convenience classes use a classic item-based interface rather
453 than a pure model/view approach. For a more flexible list view widget,
454 consider using the QListView class with a standard model.
455
456 List items can be inserted automatically into a list, when they are
457 constructed, by specifying the list widget:
458
459 \snippet qlistwidget-using/mainwindow.cpp 2
460
461 Alternatively, list items can also be created without a parent widget, and
462 later inserted into a list using QListWidget::insertItem().
463
464 List items are typically used to display text() and an icon(). These are
465 set with the setText() and setIcon() functions. The appearance of the text
466 can be customized with setFont(), setForeground(), and setBackground().
467 Text in list items can be aligned using the setTextAlignment() function.
468 Tooltips, status tips and "What's This?" help can be added to list items
469 with setToolTip(), setStatusTip(), and setWhatsThis().
470
471 By default, items are enabled, selectable, checkable, and can be the source
472 of drag and drop operations.
473
474 Each item's flags can be changed by calling setFlags() with the appropriate
475 value (see Qt::ItemFlags). Checkable items can be checked, unchecked and
476 partially checked with the setCheckState() function. The corresponding
477 checkState() function indicates the item's current check state.
478
479 The isHidden() function can be used to determine whether the item is
480 hidden. To hide an item, use setHidden().
481
482
483 \section1 Subclassing
484
485 When subclassing QListWidgetItem to provide custom items, it is possible to
486 define new types for them enabling them to be distinguished from standard
487 items. For subclasses that require this feature, ensure that you call the
488 base class constructor with a new type value equal to or greater than
489 \l UserType, within \e your constructor.
490
491 \sa QListWidget, {Model/View Programming}, QTreeWidgetItem, QTableWidgetItem
492*/
493
494/*!
495 \enum QListWidgetItem::ItemType
496
497 This enum describes the types that are used to describe list widget items.
498
499 \value Type The default type for list widget items.
500 \value UserType The minimum value for custom types. Values below UserType are
501 reserved by Qt.
502
503 You can define new user types in QListWidgetItem subclasses to ensure that
504 custom items are treated specially.
505
506 \sa type()
507*/
508
509/*!
510 \fn int QListWidgetItem::type() const
511
512 Returns the type passed to the QListWidgetItem constructor.
513*/
514
515/*!
516 \fn QListWidget *QListWidgetItem::listWidget() const
517
518 Returns the list widget containing the item.
519*/
520
521/*!
522 \fn void QListWidgetItem::setHidden(bool hide)
523
524 Hides the item if \a hide is true; otherwise shows the item.
525
526 \sa isHidden()
527*/
528
529/*!
530 \fn bool QListWidgetItem::isHidden() const
531
532 Returns \c true if the item is hidden; otherwise returns \c false.
533
534 \sa setHidden()
535*/
536
537/*!
538 \fn QListWidgetItem::QListWidgetItem(QListWidget *parent, int type)
539
540 Constructs an empty list widget item of the specified \a type with the
541 given \a parent. If \a parent is not specified, the item will need to be
542 inserted into a list widget with QListWidget::insertItem().
543
544 This constructor inserts the item into the model of the parent that is
545 passed to the constructor. If the model is sorted then the behavior of the
546 insert is undetermined since the model will call the \c '<' operator method
547 on the item which, at this point, is not yet constructed. To avoid the
548 undetermined behavior, we recommend not to specify the parent and use
549 QListWidget::insertItem() instead.
550
551 \sa type()
552*/
553QListWidgetItem::QListWidgetItem(QListWidget *listview, int type)
554 : rtti(type), view(listview), d(new QListWidgetItemPrivate(this)),
555 itemFlags(Qt::ItemIsSelectable
556 |Qt::ItemIsUserCheckable
557 |Qt::ItemIsEnabled
558 |Qt::ItemIsDragEnabled)
559{
560 if (QListModel *model = listModel())
561 model->insert(model->rowCount(), this);
562}
563
564/*!
565 \fn QListWidgetItem::QListWidgetItem(const QString &text, QListWidget *parent, int type)
566
567 Constructs an empty list widget item of the specified \a type with the
568 given \a text and \a parent. If the parent is not specified, the item will
569 need to be inserted into a list widget with QListWidget::insertItem().
570
571 This constructor inserts the item into the model of the parent that is
572 passed to the constructor. If the model is sorted then the behavior of the
573 insert is undetermined since the model will call the \c '<' operator method
574 on the item which, at this point, is not yet constructed. To avoid the
575 undetermined behavior, we recommend not to specify the parent and use
576 QListWidget::insertItem() instead.
577
578 \sa type()
579*/
580QListWidgetItem::QListWidgetItem(const QString &text, QListWidget *listview, int type)
581 : rtti(type), view(listview), d(new QListWidgetItemPrivate(this)),
582 itemFlags(Qt::ItemIsSelectable
583 |Qt::ItemIsUserCheckable
584 |Qt::ItemIsEnabled
585 |Qt::ItemIsDragEnabled)
586{
587 QListModel *model = listModel();
588 {
589 QSignalBlocker b(view);
590 QSignalBlocker bm(model);
591 setData(Qt::DisplayRole, text);
592 }
593 if (model)
594 model->insert(model->rowCount(), this);
595}
596
597/*!
598 \fn QListWidgetItem::QListWidgetItem(const QIcon &icon, const QString &text, QListWidget *parent, int type)
599
600 Constructs an empty list widget item of the specified \a type with the
601 given \a icon, \a text and \a parent. If the parent is not specified, the
602 item will need to be inserted into a list widget with
603 QListWidget::insertItem().
604
605 This constructor inserts the item into the model of the parent that is
606 passed to the constructor. If the model is sorted then the behavior of the
607 insert is undetermined since the model will call the \c '<' operator method
608 on the item which, at this point, is not yet constructed. To avoid the
609 undetermined behavior, we recommend not to specify the parent and use
610 QListWidget::insertItem() instead.
611
612 \sa type()
613*/
614QListWidgetItem::QListWidgetItem(const QIcon &icon,const QString &text,
615 QListWidget *listview, int type)
616 : rtti(type), view(listview), d(new QListWidgetItemPrivate(this)),
617 itemFlags(Qt::ItemIsSelectable
618 |Qt::ItemIsUserCheckable
619 |Qt::ItemIsEnabled
620 |Qt::ItemIsDragEnabled)
621{
622 QListModel *model = listModel();
623 {
624 QSignalBlocker b(view);
625 QSignalBlocker bm(model);
626 setData(Qt::DisplayRole, text);
627 setData(Qt::DecorationRole, icon);
628 }
629 if (model)
630 model->insert(model->rowCount(), this);
631}
632
633/*!
634 Destroys the list item.
635*/
636QListWidgetItem::~QListWidgetItem()
637{
638 if (QListModel *model = listModel())
639 model->remove(this);
640 delete d;
641}
642
643/*!
644 Creates an exact copy of the item.
645*/
646QListWidgetItem *QListWidgetItem::clone() const
647{
648 return new QListWidgetItem(*this);
649}
650
651/*!
652 Sets the data for a given \a role to the given \a value. Reimplement this
653 function if you need extra roles or special behavior for certain roles.
654
655 \note The default implementation treats Qt::EditRole and Qt::DisplayRole as
656 referring to the same data.
657
658 \sa Qt::ItemDataRole, data()
659*/
660void QListWidgetItem::setData(int role, const QVariant &value)
661{
662 bool found = false;
663 role = (role == Qt::EditRole ? Qt::DisplayRole : role);
664 for (int i = 0; i < d->values.size(); ++i) {
665 if (d->values.at(i).role == role) {
666 if (d->values.at(i).value == value)
667 return;
668 d->values[i].value = value;
669 found = true;
670 break;
671 }
672 }
673 if (!found)
674 d->values.append(QWidgetItemData(role, value));
675 if (QListModel *model = listModel()) {
676 const QList<int> roles((role == Qt::DisplayRole)
677 ? QList<int>({ Qt::DisplayRole, Qt::EditRole })
678 : QList<int>({ role }));
679 model->itemChanged(this, roles);
680 }
681}
682
683/*!
684 Returns the item's data for a given \a role. Reimplement this function if
685 you need extra roles or special behavior for certain roles.
686
687 \sa Qt::ItemDataRole, setData()
688*/
689QVariant QListWidgetItem::data(int role) const
690{
691 role = (role == Qt::EditRole ? Qt::DisplayRole : role);
692 for (int i = 0; i < d->values.size(); ++i)
693 if (d->values.at(i).role == role)
694 return d->values.at(i).value;
695 return QVariant();
696}
697
698/*!
699 Returns \c true if this item's text is less then \a other item's text;
700 otherwise returns \c false.
701*/
702bool QListWidgetItem::operator<(const QListWidgetItem &other) const
703{
704 const QVariant v1 = data(Qt::DisplayRole), v2 = other.data(Qt::DisplayRole);
705 return QAbstractItemModelPrivate::variantLessThan(v1, v2);
706}
707
708#ifndef QT_NO_DATASTREAM
709
710/*!
711 Reads the item from stream \a in.
712
713 \sa write()
714*/
715void QListWidgetItem::read(QDataStream &in)
716{
717 in >> d->values;
718}
719
720/*!
721 Writes the item to stream \a out.
722
723 \sa read()
724*/
725void QListWidgetItem::write(QDataStream &out) const
726{
727 out << d->values;
728}
729#endif // QT_NO_DATASTREAM
730
731/*!
732 Constructs a copy of \a other. Note that type() and listWidget() are not
733 copied.
734
735 This function is useful when reimplementing clone().
736
737 \sa data(), flags()
738*/
739QListWidgetItem::QListWidgetItem(const QListWidgetItem &other)
740 : rtti(Type), view(nullptr),
741 d(new QListWidgetItemPrivate(this)),
742 itemFlags(other.itemFlags)
743{
744 d->values = other.d->values;
745}
746
747/*!
748 Assigns \a other's data and flags to this item. Note that type() and
749 listWidget() are not copied.
750
751 This function is useful when reimplementing clone().
752
753 \sa data(), flags()
754*/
755QListWidgetItem &QListWidgetItem::operator=(const QListWidgetItem &other)
756{
757 d->values = other.d->values;
758 itemFlags = other.itemFlags;
759 return *this;
760}
761
762/*!
763 \internal
764 returns the QListModel if a view is set
765 */
766QListModel *QListWidgetItem::listModel() const
767{
768 return (view ? qobject_cast<QListModel*>(view->model()) : nullptr);
769}
770
771#ifndef QT_NO_DATASTREAM
772
773/*!
774 \relates QListWidgetItem
775
776 Writes the list widget item \a item to stream \a out.
777
778 This operator uses QListWidgetItem::write().
779
780 \sa {Serializing Qt Data Types}
781*/
782QDataStream &operator<<(QDataStream &out, const QListWidgetItem &item)
783{
784 item.write(out);
785 return out;
786}
787
788/*!
789 \relates QListWidgetItem
790
791 Reads a list widget item from stream \a in into \a item.
792
793 This operator uses QListWidgetItem::read().
794
795 \sa {Serializing Qt Data Types}
796*/
797QDataStream &operator>>(QDataStream &in, QListWidgetItem &item)
798{
799 item.read(in);
800 return in;
801}
802
803#endif // QT_NO_DATASTREAM
804
805/*!
806 \fn Qt::ItemFlags QListWidgetItem::flags() const
807
808 Returns the item flags for this item (see \l{Qt::ItemFlags}).
809*/
810
811/*!
812 \fn QString QListWidgetItem::text() const
813
814 Returns the list item's text.
815
816 \sa setText()
817*/
818
819/*!
820 \fn QIcon QListWidgetItem::icon() const
821
822 Returns the list item's icon.
823
824 \sa setIcon(), {QAbstractItemView::iconSize}{iconSize}
825*/
826
827/*!
828 \fn QString QListWidgetItem::statusTip() const
829
830 Returns the list item's status tip.
831
832 \sa setStatusTip()
833*/
834
835/*!
836 \fn QString QListWidgetItem::toolTip() const
837
838 Returns the list item's tooltip.
839
840 \sa setToolTip(), statusTip(), whatsThis()
841*/
842
843/*!
844 \fn QString QListWidgetItem::whatsThis() const
845
846 Returns the list item's "What's This?" help text.
847
848 \sa setWhatsThis(), statusTip(), toolTip()
849*/
850
851/*!
852 \fn QFont QListWidgetItem::font() const
853
854 Returns the font used to display this list item's text.
855*/
856
857/*!
858 \if defined(qt7)
859
860 \fn Qt::Alignment QListWidgetItem::textAlignment() const
861
862 Returns the text alignment for the list item.
863
864 \else
865
866 \fn int QListWidgetItem::textAlignment() const
867
868 Returns the text alignment for the list item.
869
870 \note This function returns an int for historical reasons. It will
871 be corrected to return Qt::Alignment in Qt 7.
872
873 \sa Qt::Alignment
874
875 \endif
876*/
877
878/*!
879 \fn QBrush QListWidgetItem::background() const
880
881 Returns the brush used to display the list item's background.
882
883 \sa setBackground(), foreground()
884*/
885
886/*!
887 \fn QBrush QListWidgetItem::foreground() const
888
889 Returns the brush used to display the list item's foreground (e.g. text).
890
891 \sa setForeground(), background()
892*/
893
894/*!
895 \fn Qt::CheckState QListWidgetItem::checkState() const
896
897 Returns the checked state of the list item (see \l{Qt::CheckState}).
898
899 \sa flags()
900*/
901
902/*!
903 \fn QSize QListWidgetItem::sizeHint() const
904
905 Returns the size hint set for the list item.
906*/
907
908/*!
909 \fn void QListWidgetItem::setSizeHint(const QSize &size)
910
911 Sets the size hint for the list item to be \a size.
912 If no size hint is set or \a size is invalid, the item
913 delegate will compute the size hint based on the item data.
914*/
915
916/*!
917 \fn void QListWidgetItem::setSelected(bool select)
918
919 Sets the selected state of the item to \a select.
920
921 \sa isSelected()
922*/
923void QListWidgetItem::setSelected(bool select)
924{
925 const QListModel *model = listModel();
926 if (!model || !view->selectionModel())
927 return;
928 const QAbstractItemView::SelectionMode selectionMode = view->selectionMode();
929 if (selectionMode == QAbstractItemView::NoSelection)
930 return;
931 const QModelIndex index = model->index(this);
932 if (selectionMode == QAbstractItemView::SingleSelection)
933 view->selectionModel()->select(index, select
934 ? QItemSelectionModel::ClearAndSelect
935 : QItemSelectionModel::Deselect);
936 else
937 view->selectionModel()->select(index, select
938 ? QItemSelectionModel::Select
939 : QItemSelectionModel::Deselect);
940}
941
942/*!
943 \fn bool QListWidgetItem::isSelected() const
944
945 Returns \c true if the item is selected; otherwise returns \c false.
946
947 \sa setSelected()
948*/
949bool QListWidgetItem::isSelected() const
950{
951 const QListModel *model = listModel();
952 if (!model || !view->selectionModel())
953 return false;
954 const QModelIndex index = model->index(this);
955 return view->selectionModel()->isSelected(index);
956}
957
958/*!
959 \fn void QListWidgetItem::setFlags(Qt::ItemFlags flags)
960
961 Sets the item flags for the list item to \a flags.
962
963 \sa Qt::ItemFlags
964*/
965void QListWidgetItem::setFlags(Qt::ItemFlags aflags)
966{
967 itemFlags = aflags;
968 if (QListModel *model = listModel())
969 model->itemChanged(this);
970}
971
972
973/*!
974 \fn void QListWidgetItem::setText(const QString &text)
975
976 Sets the text for the list widget item's to the given \a text.
977
978 \sa text()
979*/
980
981/*!
982 \fn void QListWidgetItem::setIcon(const QIcon &icon)
983
984 Sets the icon for the list item to the given \a icon.
985
986 \sa icon(), text(), {QAbstractItemView::iconSize}{iconSize}
987*/
988
989/*!
990 \fn void QListWidgetItem::setStatusTip(const QString &statusTip)
991
992 Sets the status tip for the list item to the text specified by
993 \a statusTip. QListWidget mouseTracking needs to be enabled for this
994 feature to work.
995
996 \sa statusTip(), setToolTip(), setWhatsThis(), QWidget::setMouseTracking()
997*/
998
999/*!
1000 \fn void QListWidgetItem::setToolTip(const QString &toolTip)
1001
1002 Sets the tooltip for the list item to the text specified by \a toolTip.
1003
1004 \sa toolTip(), setStatusTip(), setWhatsThis()
1005*/
1006
1007/*!
1008 \fn void QListWidgetItem::setWhatsThis(const QString &whatsThis)
1009
1010 Sets the "What's This?" help for the list item to the text specified by
1011 \a whatsThis.
1012
1013 \sa whatsThis(), setStatusTip(), setToolTip()
1014*/
1015
1016/*!
1017 \fn void QListWidgetItem::setFont(const QFont &font)
1018
1019 Sets the font used when painting the item to the given \a font.
1020*/
1021
1022/*!
1023 \obsolete [6.4] Use the overload that takes a Qt::Alignment argument.
1024
1025 \fn void QListWidgetItem::setTextAlignment(int alignment)
1026
1027 Sets the list item's text alignment to \a alignment.
1028
1029 \sa Qt::Alignment
1030*/
1031
1032/*!
1033 \since 6.4
1034
1035 \fn void QListWidgetItem::setTextAlignment(Qt::Alignment alignment)
1036
1037 Sets the list item's text alignment to \a alignment.
1038*/
1039
1040/*!
1041 \fn void QListWidgetItem::setTextAlignment(Qt::AlignmentFlag alignment)
1042 \internal
1043*/
1044
1045/*!
1046 \fn void QListWidgetItem::setBackground(const QBrush &brush)
1047
1048 Sets the background brush of the list item to the given \a brush.
1049 Setting a default-constructed brush will let the view use the
1050 default color from the style.
1051
1052 \sa background(), setForeground()
1053*/
1054
1055/*!
1056 \fn void QListWidgetItem::setForeground(const QBrush &brush)
1057
1058 Sets the foreground brush of the list item to the given \a brush.
1059 Setting a default-constructed brush will let the view use the
1060 default color from the style.
1061
1062 \sa foreground(), setBackground()
1063*/
1064
1065/*!
1066 \fn void QListWidgetItem::setCheckState(Qt::CheckState state)
1067
1068 Sets the check state of the list item to \a state.
1069
1070 \sa checkState()
1071*/
1072
1073void QListWidgetPrivate::setup()
1074{
1075 Q_Q(QListWidget);
1076 q->QListView::setModel(new QListModel(q));
1077 // view signals
1078 connections = {
1079 QObjectPrivate::connect(q, &QListWidget::pressed,
1080 this, &QListWidgetPrivate::emitItemPressed),
1081 QObjectPrivate::connect(q, &QListWidget::clicked,
1082 this, &QListWidgetPrivate::emitItemClicked),
1083 QObjectPrivate::connect(q, &QListWidget::doubleClicked,
1084 this, &QListWidgetPrivate::emitItemDoubleClicked),
1085 QObjectPrivate::connect(q, &QListWidget::activated,
1086 this, &QListWidgetPrivate::emitItemActivated),
1087 QObjectPrivate::connect(q, &QListWidget::entered,
1088 this, &QListWidgetPrivate::emitItemEntered),
1089 QObjectPrivate::connect(model, &QAbstractItemModel::dataChanged,
1090 this, &QListWidgetPrivate::emitItemChanged),
1091 QObjectPrivate::connect(model, &QAbstractItemModel::dataChanged,
1092 this, &QListWidgetPrivate::dataChanged),
1093 QObjectPrivate::connect(model, &QAbstractItemModel::columnsRemoved,
1094 this, &QListWidgetPrivate::sort)
1095 };
1096}
1097
1098void QListWidgetPrivate::clearConnections()
1099{
1100 for (const QMetaObject::Connection &connection : connections)
1101 QObject::disconnect(connection);
1102 for (const QMetaObject::Connection &connection : selectionModelConnections)
1103 QObject::disconnect(connection);
1104}
1105
1106void QListWidgetPrivate::emitItemPressed(const QModelIndex &index)
1107{
1108 Q_Q(QListWidget);
1109 emit q->itemPressed(listModel()->at(index.row()));
1110}
1111
1112void QListWidgetPrivate::emitItemClicked(const QModelIndex &index)
1113{
1114 Q_Q(QListWidget);
1115 emit q->itemClicked(listModel()->at(index.row()));
1116}
1117
1118void QListWidgetPrivate::emitItemDoubleClicked(const QModelIndex &index)
1119{
1120 Q_Q(QListWidget);
1121 emit q->itemDoubleClicked(listModel()->at(index.row()));
1122}
1123
1124void QListWidgetPrivate::emitItemActivated(const QModelIndex &index)
1125{
1126 Q_Q(QListWidget);
1127 emit q->itemActivated(listModel()->at(index.row()));
1128}
1129
1130void QListWidgetPrivate::emitItemEntered(const QModelIndex &index)
1131{
1132 Q_Q(QListWidget);
1133 emit q->itemEntered(listModel()->at(index.row()));
1134}
1135
1136void QListWidgetPrivate::emitItemChanged(const QModelIndex &index)
1137{
1138 Q_Q(QListWidget);
1139 emit q->itemChanged(listModel()->at(index.row()));
1140}
1141
1142void QListWidgetPrivate::emitCurrentItemChanged(const QModelIndex &current,
1143 const QModelIndex &previous)
1144{
1145 Q_Q(QListWidget);
1146 QPersistentModelIndex persistentCurrent = current;
1147 QListWidgetItem *currentItem = listModel()->at(persistentCurrent.row());
1148 emit q->currentItemChanged(currentItem, listModel()->at(previous.row()));
1149
1150 //persistentCurrent is invalid if something changed the model in response
1151 //to the currentItemChanged signal emission and the item was removed
1152 if (!persistentCurrent.isValid()) {
1153 currentItem = nullptr;
1154 }
1155
1156 emit q->currentTextChanged(currentItem ? currentItem->text() : QString());
1157 emit q->currentRowChanged(persistentCurrent.row());
1158}
1159
1160void QListWidgetPrivate::sort()
1161{
1162 if (sortingEnabled)
1163 model->sort(0, sortOrder);
1164}
1165
1166void QListWidgetPrivate::dataChanged(const QModelIndex &topLeft,
1167 const QModelIndex &bottomRight)
1168{
1169 if (sortingEnabled && topLeft.isValid() && bottomRight.isValid())
1170 listModel()->ensureSorted(topLeft.column(), sortOrder,
1171 topLeft.row(), bottomRight.row());
1172}
1173
1174/*!
1175 \class QListWidget
1176 \brief The QListWidget class provides an item-based list widget.
1177
1178 \ingroup model-view
1179 \inmodule QtWidgets
1180
1181 \image fusion-listview.png {List of weather icons}
1182
1183 QListWidget is a convenience class that provides a list view similar to the
1184 one supplied by QListView, but with a classic item-based interface for
1185 adding and removing items. QListWidget uses an internal model to manage
1186 each QListWidgetItem in the list.
1187
1188 For a more flexible list view widget, use the QListView class with a
1189 standard model.
1190
1191 List widgets are constructed in the same way as other widgets:
1192
1193 \snippet qlistwidget-using/mainwindow.cpp 0
1194
1195 The selectionMode() of a list widget determines how many of the items in
1196 the list can be selected at the same time, and whether complex selections
1197 of items can be created. This can be set with the setSelectionMode()
1198 function.
1199
1200 There are two ways to add items to the list: they can be constructed with
1201 the list widget as their parent widget, or they can be constructed with no
1202 parent widget and added to the list later. If a list widget already exists
1203 when the items are constructed, the first method is easier to use:
1204
1205 \snippet qlistwidget-using/mainwindow.cpp 1
1206
1207 If you need to insert a new item into the list at a particular position,
1208 then it should be constructed without a parent widget. The insertItem()
1209 function should then be used to place it within the list. The list widget
1210 will take ownership of the item.
1211
1212 \snippet qlistwidget-using/mainwindow.cpp 6
1213 \snippet qlistwidget-using/mainwindow.cpp 7
1214
1215 For multiple items, insertItems() can be used instead. The number of items
1216 in the list is found with the count() function. To remove items from the
1217 list, use takeItem().
1218
1219 The current item in the list can be found with currentItem(), and changed
1220 with setCurrentItem(). The user can also change the current item by
1221 navigating with the keyboard or clicking on a different item. When the
1222 current item changes, the currentItemChanged() signal is emitted with the
1223 new current item and the item that was previously current.
1224
1225 \sa QListWidgetItem, QListView, QTreeView, {Model/View Programming},
1226 {Tab Dialog Example}
1227*/
1228
1229/*!
1230 \fn void QListWidget::addItem(QListWidgetItem *item)
1231
1232 Inserts the \a item at the end of the list widget.
1233
1234 \warning A QListWidgetItem can only be added to a QListWidget once. Adding
1235 the same QListWidgetItem multiple times to a QListWidget will result in
1236 undefined behavior.
1237
1238 \sa insertItem()
1239*/
1240
1241/*!
1242 \fn void QListWidget::addItem(const QString &label)
1243
1244 Inserts an item with the text \a label at the end of the list widget.
1245*/
1246
1247/*!
1248 \fn void QListWidget::addItems(const QStringList &labels)
1249
1250 Inserts items with the text \a labels at the end of the list widget.
1251
1252 \sa insertItems()
1253*/
1254
1255/*!
1256 \fn void QListWidget::itemPressed(QListWidgetItem *item)
1257
1258 This signal is emitted with the specified \a item when a mouse button is
1259 pressed on an item in the widget.
1260
1261 \sa itemClicked(), itemDoubleClicked()
1262*/
1263
1264/*!
1265 \fn void QListWidget::itemClicked(QListWidgetItem *item)
1266
1267 This signal is emitted with the specified \a item when a mouse button is
1268 clicked on an item in the widget.
1269
1270 \sa itemPressed(), itemDoubleClicked()
1271*/
1272
1273/*!
1274 \fn void QListWidget::itemDoubleClicked(QListWidgetItem *item)
1275
1276 This signal is emitted with the specified \a item when a mouse button is
1277 double clicked on an item in the widget.
1278
1279 \sa itemClicked(), itemPressed()
1280*/
1281
1282/*!
1283 \fn void QListWidget::itemActivated(QListWidgetItem *item)
1284
1285 This signal is emitted when the \a item is activated. The \a item is
1286 activated when the user clicks or double clicks on it, depending on the
1287 system configuration. It is also activated when the user presses the
1288 activation key (on Windows and X11 this is the \uicontrol Return key, on Mac OS
1289 X it is \uicontrol{Command+O}).
1290*/
1291
1292/*!
1293 \fn void QListWidget::itemEntered(QListWidgetItem *item)
1294
1295 This signal is emitted when the mouse cursor enters an item. The \a item is
1296 the item entered. This signal is only emitted when mouseTracking is turned
1297 on, or when a mouse button is pressed while moving into an item.
1298
1299 \sa QWidget::setMouseTracking()
1300*/
1301
1302/*!
1303 \fn void QListWidget::itemChanged(QListWidgetItem *item)
1304
1305 This signal is emitted whenever the data of \a item has changed.
1306*/
1307
1308/*!
1309 \fn void QListWidget::currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
1310
1311 This signal is emitted whenever the current item changes.
1312
1313 \a previous is the item that previously had the focus; \a current is the
1314 new current item.
1315*/
1316
1317/*!
1318 \fn void QListWidget::currentTextChanged(const QString &currentText)
1319
1320 This signal is emitted whenever the current item changes.
1321
1322 \a currentText is the text data in the current item. If there is no current
1323 item, the \a currentText is invalid.
1324*/
1325
1326/*!
1327 \fn void QListWidget::currentRowChanged(int currentRow)
1328
1329 This signal is emitted whenever the current item changes.
1330
1331 \a currentRow is the row of the current item. If there is no current item,
1332 the \a currentRow is -1.
1333*/
1334
1335/*!
1336 \fn void QListWidget::itemSelectionChanged()
1337
1338 This signal is emitted whenever the selection changes.
1339
1340 \sa selectedItems(), QListWidgetItem::isSelected(), currentItemChanged()
1341*/
1342
1343/*!
1344 \fn void QListWidget::removeItemWidget(QListWidgetItem *item)
1345
1346 Removes the widget set on the given \a item.
1347
1348 To remove an item (row) from the list entirely, either delete the item or
1349 use takeItem().
1350
1351 \sa itemWidget(), setItemWidget()
1352*/
1353
1354/*!
1355 Constructs an empty QListWidget with the given \a parent.
1356*/
1357
1358QListWidget::QListWidget(QWidget *parent)
1359 : QListView(*new QListWidgetPrivate(), parent)
1360{
1361 Q_D(QListWidget);
1362 d->setup();
1363}
1364
1365/*!
1366 Destroys the list widget and all its items.
1367*/
1368
1369QListWidget::~QListWidget()
1370{
1371 Q_D(QListWidget);
1372 d->clearConnections();
1373}
1374
1375/*!
1376 \reimp
1377*/
1378
1379void QListWidget::setSelectionModel(QItemSelectionModel *selectionModel)
1380{
1381 Q_D(QListWidget);
1382
1383 for (const QMetaObject::Connection &connection : d->selectionModelConnections)
1384 disconnect(connection);
1385
1386 QListView::setSelectionModel(selectionModel);
1387
1388 if (d->selectionModel) {
1389 d->selectionModelConnections = {
1390 QObjectPrivate::connect(d->selectionModel, &QItemSelectionModel::currentChanged,
1391 d, &QListWidgetPrivate::emitCurrentItemChanged),
1392 QObject::connect(d->selectionModel, &QItemSelectionModel::selectionChanged,
1393 this, &QListWidget::itemSelectionChanged)
1394 };
1395 }
1396}
1397
1398/*!
1399 Returns the item that occupies the given \a row in the list if one has been
1400 set; otherwise returns \nullptr.
1401
1402 \sa row()
1403*/
1404
1405QListWidgetItem *QListWidget::item(int row) const
1406{
1407 Q_D(const QListWidget);
1408 if (row < 0 || row >= d->model->rowCount())
1409 return nullptr;
1410 return d->listModel()->at(row);
1411}
1412
1413/*!
1414 Returns the row containing the given \a item.
1415
1416 \sa item()
1417*/
1418
1419int QListWidget::row(const QListWidgetItem *item) const
1420{
1421 Q_D(const QListWidget);
1422 return d->listModel()->index(const_cast<QListWidgetItem*>(item)).row();
1423}
1424
1425
1426/*!
1427 Inserts the \a item at the position in the list given by \a row.
1428
1429 \sa addItem()
1430*/
1431
1432void QListWidget::insertItem(int row, QListWidgetItem *item)
1433{
1434 Q_D(QListWidget);
1435 if (item && !item->view)
1436 d->listModel()->insert(row, item);
1437}
1438
1439/*!
1440 Inserts an item with the text \a label in the list widget at the position
1441 given by \a row.
1442
1443 \sa addItem()
1444*/
1445
1446void QListWidget::insertItem(int row, const QString &label)
1447{
1448 Q_D(QListWidget);
1449 d->listModel()->insert(row, new QListWidgetItem(label));
1450}
1451
1452/*!
1453 Inserts items from the list of \a labels into the list, starting at the
1454 given \a row.
1455
1456 \sa insertItem(), addItem()
1457*/
1458
1459void QListWidget::insertItems(int row, const QStringList &labels)
1460{
1461 Q_D(QListWidget);
1462 d->listModel()->insert(row, labels);
1463}
1464
1465/*!
1466 Removes and returns the item from the given \a row in the list widget;
1467 otherwise returns \nullptr.
1468
1469 Items removed from a list widget will not be managed by Qt, and will need
1470 to be deleted manually.
1471
1472 \sa insertItem(), addItem()
1473*/
1474
1475QListWidgetItem *QListWidget::takeItem(int row)
1476{
1477 Q_D(QListWidget);
1478 if (row < 0 || row >= d->model->rowCount())
1479 return nullptr;
1480 return d->listModel()->take(row);
1481}
1482
1483/*!
1484 \property QListWidget::count
1485 \brief the number of items in the list including any hidden items.
1486*/
1487
1488int QListWidget::count() const
1489{
1490 Q_D(const QListWidget);
1491 return d->model->rowCount();
1492}
1493
1494/*!
1495 Returns the current item.
1496*/
1497QListWidgetItem *QListWidget::currentItem() const
1498{
1499 Q_D(const QListWidget);
1500 return d->listModel()->at(currentIndex().row());
1501}
1502
1503
1504/*!
1505 Sets the current item to \a item.
1506
1507 Unless the selection mode is \l{QAbstractItemView::}{NoSelection},
1508 the item is also selected.
1509*/
1510void QListWidget::setCurrentItem(QListWidgetItem *item)
1511{
1512 setCurrentRow(row(item));
1513}
1514
1515/*!
1516 Set the current item to \a item, using the given \a command.
1517*/
1518void QListWidget::setCurrentItem(QListWidgetItem *item, QItemSelectionModel::SelectionFlags command)
1519{
1520 setCurrentRow(row(item), command);
1521}
1522
1523/*!
1524 \property QListWidget::currentRow
1525 \brief the row of the current item.
1526
1527 Depending on the current selection mode, the row may also be selected.
1528*/
1529
1530int QListWidget::currentRow() const
1531{
1532 return currentIndex().row();
1533}
1534
1535void QListWidget::setCurrentRow(int row)
1536{
1537 Q_D(QListWidget);
1538 QModelIndex index = d->listModel()->index(row);
1539 if (d->selectionMode == SingleSelection)
1540 selectionModel()->setCurrentIndex(index, QItemSelectionModel::ClearAndSelect);
1541 else if (d->selectionMode == NoSelection)
1542 selectionModel()->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
1543 else
1544 selectionModel()->setCurrentIndex(index, QItemSelectionModel::SelectCurrent);
1545}
1546
1547/*!
1548 Sets the current row to be the given \a row, using the given \a command,
1549*/
1550void QListWidget::setCurrentRow(int row, QItemSelectionModel::SelectionFlags command)
1551{
1552 Q_D(QListWidget);
1553 d->selectionModel->setCurrentIndex(d->listModel()->index(row), command);
1554}
1555
1556/*!
1557 Returns a pointer to the item at the coordinates \a p. The coordinates
1558 are relative to the list widget's \l{QAbstractScrollArea::}{viewport()}.
1559
1560*/
1561QListWidgetItem *QListWidget::itemAt(const QPoint &p) const
1562{
1563 Q_D(const QListWidget);
1564 return d->listModel()->at(indexAt(p).row());
1565
1566}
1567
1568/*!
1569 \fn QListWidgetItem *QListWidget::itemAt(int x, int y) const
1570 \overload
1571
1572 Returns a pointer to the item at the coordinates (\a x, \a y).
1573 The coordinates are relative to the list widget's
1574 \l{QAbstractScrollArea::}{viewport()}.
1575
1576*/
1577
1578
1579/*!
1580 Returns the rectangle on the viewport occupied by the item at \a item.
1581*/
1582QRect QListWidget::visualItemRect(const QListWidgetItem *item) const
1583{
1584 Q_D(const QListWidget);
1585 QModelIndex index = d->listModel()->index(const_cast<QListWidgetItem*>(item));
1586 return visualRect(index);
1587}
1588
1589/*!
1590 Sorts all the items in the list widget according to the specified \a order.
1591*/
1592void QListWidget::sortItems(Qt::SortOrder order)
1593{
1594 Q_D(QListWidget);
1595 d->sortOrder = order;
1596 d->listModel()->sort(0, order);
1597}
1598
1599/*!
1600 \property QListWidget::sortingEnabled
1601 \brief whether sorting is enabled
1602
1603 If this property is \c true, sorting is enabled for the list; if the property
1604 is false, sorting is not enabled.
1605
1606 The default value is false.
1607*/
1608void QListWidget::setSortingEnabled(bool enable)
1609{
1610 Q_D(QListWidget);
1611 d->sortingEnabled = enable;
1612}
1613
1614bool QListWidget::isSortingEnabled() const
1615{
1616 Q_D(const QListWidget);
1617 return d->sortingEnabled;
1618}
1619
1620/*!
1621 \internal
1622*/
1623Qt::SortOrder QListWidget::sortOrder() const
1624{
1625 Q_D(const QListWidget);
1626 return d->sortOrder;
1627}
1628
1629/*!
1630 Starts editing the \a item if it is editable.
1631*/
1632
1633void QListWidget::editItem(QListWidgetItem *item)
1634{
1635 Q_D(QListWidget);
1636 edit(d->listModel()->index(item));
1637}
1638
1639/*!
1640 Opens an editor for the given \a item. The editor remains open after
1641 editing.
1642
1643 \sa closePersistentEditor(), isPersistentEditorOpen()
1644*/
1645void QListWidget::openPersistentEditor(QListWidgetItem *item)
1646{
1647 Q_D(QListWidget);
1648 QModelIndex index = d->listModel()->index(item);
1649 QAbstractItemView::openPersistentEditor(index);
1650}
1651
1652/*!
1653 Closes the persistent editor for the given \a item.
1654
1655 \sa openPersistentEditor(), isPersistentEditorOpen()
1656*/
1657void QListWidget::closePersistentEditor(QListWidgetItem *item)
1658{
1659 Q_D(QListWidget);
1660 QModelIndex index = d->listModel()->index(item);
1661 QAbstractItemView::closePersistentEditor(index);
1662}
1663
1664/*!
1665 \since 5.10
1666
1667 Returns whether a persistent editor is open for item \a item.
1668
1669 \sa openPersistentEditor(), closePersistentEditor()
1670*/
1671bool QListWidget::isPersistentEditorOpen(QListWidgetItem *item) const
1672{
1673 Q_D(const QListWidget);
1674 const QModelIndex index = d->listModel()->index(item);
1675 return QAbstractItemView::isPersistentEditorOpen(index);
1676}
1677
1678/*!
1679 Returns the widget displayed in the given \a item.
1680
1681 \sa setItemWidget(), removeItemWidget()
1682*/
1683QWidget *QListWidget::itemWidget(QListWidgetItem *item) const
1684{
1685 Q_D(const QListWidget);
1686 QModelIndex index = d->listModel()->index(item);
1687 return QAbstractItemView::indexWidget(index);
1688}
1689
1690/*!
1691 Sets the \a widget to be displayed in the given \a item.
1692
1693 This function should only be used to display static content in the place of
1694 a list widget item. If you want to display custom dynamic content or
1695 implement a custom editor widget, use QListView and subclass QStyledItemDelegate
1696 instead.
1697
1698 \note The list takes ownership of the \a widget.
1699
1700 \sa itemWidget(), removeItemWidget(), {Delegate Classes}
1701*/
1702void QListWidget::setItemWidget(QListWidgetItem *item, QWidget *widget)
1703{
1704 Q_D(QListWidget);
1705 QModelIndex index = d->listModel()->index(item);
1706 QAbstractItemView::setIndexWidget(index, widget);
1707}
1708
1709/*!
1710 Returns a list of all selected items in the list widget.
1711*/
1712
1713QList<QListWidgetItem*> QListWidget::selectedItems() const
1714{
1715 Q_D(const QListWidget);
1716 QModelIndexList indexes = selectionModel()->selectedIndexes();
1717 QList<QListWidgetItem*> items;
1718 const int numIndexes = indexes.size();
1719 items.reserve(numIndexes);
1720 for (int i = 0; i < numIndexes; ++i)
1721 items.append(d->listModel()->at(indexes.at(i).row()));
1722 return items;
1723}
1724
1725/*!
1726 Finds items with the text that matches the string \a text using the given
1727 \a flags.
1728*/
1729
1730QList<QListWidgetItem*> QListWidget::findItems(const QString &text, Qt::MatchFlags flags) const
1731{
1732 Q_D(const QListWidget);
1733 QModelIndexList indexes = d->listModel()->match(model()->index(0, 0, QModelIndex()),
1734 Qt::DisplayRole, text, -1, flags);
1735 QList<QListWidgetItem*> items;
1736 const int indexesSize = indexes.size();
1737 items.reserve(indexesSize);
1738 for (int i = 0; i < indexesSize; ++i)
1739 items.append(d->listModel()->at(indexes.at(i).row()));
1740 return items;
1741}
1742
1743/*!
1744 Scrolls the view if necessary to ensure that the \a item is visible.
1745
1746 \a hint specifies where the \a item should be located after the operation.
1747*/
1748
1749void QListWidget::scrollToItem(const QListWidgetItem *item, QAbstractItemView::ScrollHint hint)
1750{
1751 Q_D(QListWidget);
1752 QModelIndex index = d->listModel()->index(const_cast<QListWidgetItem*>(item));
1753 QListView::scrollTo(index, hint);
1754}
1755
1756/*!
1757 Removes all items and selections in the view.
1758
1759 \warning All items will be permanently deleted.
1760*/
1761void QListWidget::clear()
1762{
1763 Q_D(QListWidget);
1764 selectionModel()->clear();
1765 d->listModel()->clear();
1766}
1767
1768/*!
1769 Returns a list of MIME types that can be used to describe a list of
1770 listwidget items.
1771
1772 \sa mimeData()
1773*/
1774QStringList QListWidget::mimeTypes() const
1775{
1776 return d_func()->listModel()->QAbstractListModel::mimeTypes();
1777}
1778
1779/*!
1780 Returns an object that contains a serialized description of the specified
1781 \a items. The format used to describe the items is obtained from the
1782 mimeTypes() function.
1783
1784 If the list of items is empty, \nullptr is returned instead of a
1785 serialized empty list.
1786*/
1787QMimeData *QListWidget::mimeData(const QList<QListWidgetItem *> &items) const
1788{
1789 Q_D(const QListWidget);
1790
1791 QModelIndexList &cachedIndexes = d->listModel()->cachedIndexes;
1792
1793 // if non empty, it's called from the model's own mimeData
1794 if (cachedIndexes.isEmpty()) {
1795 cachedIndexes.reserve(items.size());
1796 for (QListWidgetItem *item : items)
1797 cachedIndexes << indexFromItem(item);
1798
1799 QMimeData *result = d->listModel()->internalMimeData();
1800
1801 cachedIndexes.clear();
1802 return result;
1803 }
1804
1805 return d->listModel()->internalMimeData();
1806}
1807
1808#if QT_CONFIG(draganddrop)
1809
1810/*!
1811 Handles \a data supplied by an external drag and drop operation that ended
1812 with the given \a action in the given \a index. Returns \c true if \a data and
1813 \a action can be handled by the model; otherwise returns \c false.
1814
1815 \sa supportedDropActions(), supportedDragActions
1816*/
1817bool QListWidget::dropMimeData(int index, const QMimeData *data, Qt::DropAction action)
1818{
1819 QModelIndex idx;
1820 int row = index;
1821 int column = 0;
1822 if (dropIndicatorPosition() == QAbstractItemView::OnItem) {
1823 // QAbstractListModel::dropMimeData will overwrite on the index if row == -1 and column == -1
1824 idx = model()->index(row, column);
1825 row = -1;
1826 column = -1;
1827 }
1828 return d_func()->listModel()->QAbstractListModel::dropMimeData(data, action , row, column, idx);
1829}
1830
1831/*! \reimp */
1832void QListWidget::dropEvent(QDropEvent *event)
1833{
1834 QListView::dropEvent(event);
1835}
1836
1837/*!
1838 Returns the drop actions supported by this view.
1839
1840 \sa Qt::DropActions, supportedDragActions, dropMimeData()
1841*/
1842Qt::DropActions QListWidget::supportedDropActions() const
1843{
1844 Q_D(const QListWidget);
1845 return d->listModel()->QAbstractListModel::supportedDropActions() | Qt::MoveAction;
1846}
1847
1848/*!
1849 \property QListWidget::supportedDragActions
1850 \brief the drag actions supported by this view
1851
1852 \since 6.10
1853 \sa Qt::DropActions, supportedDropActions()
1854*/
1855Qt::DropActions QListWidget::supportedDragActions() const
1856{
1857 Q_D(const QListWidget);
1858 return d->supportedDragActions.value_or(supportedDropActions());
1859}
1860
1861void QListWidget::setSupportedDragActions(Qt::DropActions actions)
1862{
1863 Q_D(QListWidget);
1864 d->supportedDragActions = actions;
1865}
1866
1867#endif // QT_CONFIG(draganddrop)
1868
1869/*!
1870 Returns a list of pointers to the items contained in the \a data object. If
1871 the object was not created by a QListWidget in the same process, the list
1872 is empty.
1873*/
1874QList<QListWidgetItem*> QListWidget::items(const QMimeData *data) const
1875{
1876 const QListWidgetMimeData *lwd = qobject_cast<const QListWidgetMimeData*>(data);
1877 if (lwd)
1878 return lwd->items;
1879 return QList<QListWidgetItem*>();
1880}
1881
1882/*!
1883 Returns the QModelIndex associated with the given \a item.
1884
1885 \note In Qt versions prior to 5.10, this function took a non-\c{const} \a item.
1886*/
1887
1888QModelIndex QListWidget::indexFromItem(const QListWidgetItem *item) const
1889{
1890 Q_D(const QListWidget);
1891 return d->listModel()->index(item);
1892}
1893
1894/*!
1895 Returns a pointer to the QListWidgetItem associated with the given \a index.
1896*/
1897
1898QListWidgetItem *QListWidget::itemFromIndex(const QModelIndex &index) const
1899{
1900 Q_D(const QListWidget);
1901 if (d->isIndexValid(index))
1902 return d->listModel()->at(index.row());
1903 return nullptr;
1904}
1905
1906/*!
1907 \internal
1908*/
1909void QListWidget::setModel(QAbstractItemModel * /*model*/)
1910{
1911 Q_ASSERT(!"QListWidget::setModel() - Changing the model of the QListWidget is not allowed.");
1912}
1913
1914/*!
1915 \reimp
1916*/
1917bool QListWidget::event(QEvent *e)
1918{
1919 return QListView::event(e);
1920}
1921
1922QT_END_NAMESPACE
1923
1924#include "moc_qlistwidget.cpp"
1925#include "moc_qlistwidget_p.cpp"
QDataStream & operator<<(QDataStream &stream, const QImage &image)
[0]
Definition qimage.cpp:4006
QDataStream & operator>>(QDataStream &stream, QImage &image)
Definition qimage.cpp:4032