QListView или QListWidget

Что использовать QListView, или QListWidget если я хочу добавлять в список виджеты? Например, у меня есть QWidget и внутри него еще элементы, как его добавить в QListWidget понятно, но как его добавить в QListView?Возможно ли это вообще? Нужно ли вообще использовать QListView в такой ситуации? Почитав посты, я так понял, что QListView более производителен.


Ответы (1 шт):

Автор решения: Alexander Chernin

Да, 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());
    }
→ Ссылка