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