QListView или QListWidget
Что использовать QListView, или QListWidget если я хочу добавлять в список виджеты? Например, у меня есть QWidget и внутри него еще элементы, как его добавить в QListWidget понятно, но как его добавить в QListView?Возможно ли это вообще? Нужно ли вообще использовать QListView в такой ситуации? Почитав посты, я так понял, что QListView более производителен.
Ответы (1 шт):
Да, QListView больше подходит если у вас большое количество статических и, особенно, динамических данных. В нем реализован алгоритм отображения/отрисовки по необходимости (при прокрутке), что существенно ускоряет отображение и обработку табличных данных. QListWidget, несмотря на то, что он является наследником QListView, больше подходит для небольшого количества и, в большей степени, статических данных.
Отрисовать QWidget (и его наследников) в QListView относительно не сложно, для этого вам понадобится наследник класса QStyledItemDelegate. Пример:
// Наш кастомный виджет
class MyWidget {
Q_OBJECT
//...
}
// Наш делегат
class MyStyledDelegate: public QStyledItemDelegate {
MyStyledDelegate(QObject* parent = nullptr): QStyledItemDelegate(parent) {
myWidget = MyWidget();
}
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override {
if (!index.isValid()) {
return;
}
// пример настройки объекта
myWidget.setValue(...);
// подгоняем размеры виджета под размеры ячейки
myWidget.setGeometry(0, 0, option.rect.width(), option.rect.height());
// устанавливаем размер холста на котором будем отрисовывать наш виджет
QPixmap pixmap = QPixmap(option.rect.size());
// рендерим виджет на холст
myWidget.render(&pixmap);
// Отображаем холст в ячейку таблицы
painter->drawPixmap(option.rect.topLeft(), &pixmap);
}
}
Чтобы не создавать для каждого вызова paint новый экземпляр MyWidget, мы создаем его один раз в конструкторе класса, а в paint просто инициализируем данными (также можно поступить и с QPixmap)
дальше, как обычно
// Чей-то конструктор
{
ui->listView->setItemDelegate(new MyStyledDelegate());
ui->listView->setModel(new MyModel());
}