Создаем делегат для QTableView - Работа с моделями в Qt для отображения данных в виджетах. Часть 8
В Qt5 ячейки таблицы могут содержать не только текст, но и другие виджеты.
Сегодня мы создадим простой делегат для QTableView, чтобы отобразить в столбце иконку. Для того чтобы сэкономить время, мы будем проект из прошлой статьи.
Так же нам понадобиться файлы из предыдущей статьи - скопируйте папку img и файл resource.qrc и добавьте в проект.
Откроем главную форму и сделаем её немного шире - нам понадобиться дополнительное место.
Добавим новый класс Делегата - TableItemDelegate:
Заголовок:
#ifndef TableITEMDELEGATE_H
#define TableITEMDELEGATE_H
#include <QItemDelegate>
#include <QPolygonF>
#include <QPointF>
class TableItemDelegate : public QItemDelegate
{
Q_OBJECT
public:
TableItemDelegate();
QSize sizeHint(const QStyleOptionViewItem &option,
const QModelIndex &index) const override;
void paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const override;
};
#endif // TableITEMDELEGATE_H
Реализация
#include "tableitemdelegate.h"
#include "math.h"
#include <QPainter>
#include <QDebug>
TableItemDelegate::TableItemDelegate()
{
}
QSize TableItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
return QItemDelegate::sizeHint(option, index);
}
void TableItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QStyleOptionViewItem myOption = option;
if (index.column()==2)
{
QString data = index.model()->data(index, Qt::DisplayRole).toString();
myOption.displayAlignment = Qt::AlignCenter | Qt::AlignVCenter;
QString icon = ":/img/" + index.model()->data(index, Qt::DisplayRole).toString();
qDebug() << icon;
QPixmap pixmap2(icon);
painter->drawPixmap(myOption.rect.x()+30,myOption.rect.y(),32,32, pixmap2);
}
else
{
drawDisplay(painter, option, option.rect, index.model()->data(index, Qt::DisplayRole).toString());
}
drawFocus(painter, myOption, myOption.rect);
}
Запустим:
В третьем столбце у нас появились иконки.
Код делегата не сильно поменялся, по сравнению с тем, что мы использовали для QComboBox. Единственное отличие – мы проверяем номер столбца. Если это третий столбец – то рисуем иконку, если любой другой - вызываем метод рисования по умолчанию – drawDisplay.
И в любом случае отрисовываем рамку фокуса drawFocus
Предположим, что нам необходимо отображать так же и имя файла, в добавок к самой иконке.
Внесем изменения в модель - изменим количество столбцов:
int QTableViewModel::columnCount(const QModelIndex &) const
{
return 4;
}
Изменим метод data()
QVariant QTableViewModel::data( const QModelIndex &index, int role ) const
{
QVariant value;
switch ( role )
{
case Qt::DisplayRole: //string
{
switch (index.column()) {
case 0: {
value = this->values->at(index.row()).getId();
break;
}
case 1: {
value = this->values->at(index.row()).getName();
break;
}
case 2: {
value = this->values->at(index.row()).getIcon();
break;
}
case 3: {
value = this->values->at(index.row()).getIcon();
break;
}
}
}
break;
case Qt::UserRole: //data
{
value = this->values->at(index.row()).getId();
}
break;
default:
break;
}
return value;
}
Здесь мы просто увеличили количество столбцов, возвращаемых методом columnCount() и в метод data() добавили возврат данных для столбца 4.
Запустим:
Чего-то не хватает - мы забыли про заголовок столбца:
QVariant QTableViewModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
switch (section) {
case 0:
return QString("ID");
case 1:
return QString("Name");
case 2:
return QString("Icon");
case 2:
return QString("Icon file");
}
}
return QVariant();
}
Запустим:
Вот мы и добавили новый столбец, с добавлением дополнительных столбцов не должно возникнуть проблем - всё что нужно увеличить количество столбцов и добавить возврат значения в метод data().
Заключение
Сегодня мы написали простой Делегат модель для QTableView, при этом нам даже не пришлось менять нашу модель.
Так же мы добавили новый столбец в таблицу, для отображения имени файла иконки.
В следующей статье мы рассмотрим создание Делегата для правки значений в ячейках таблицы.
Исходный код вы можете найти на GitFlic.
Добавить комментарий