А теперь небольшая статья о настройке поведения ячеек с помощью делегатов в QTableView.
Эта статья является модификацией поведения таблицы в одной старой статье, а именно
Qt/C++ - Tutorial 039. Как заполнить строку в QSqlTableModel по значению в столбце
. На самом деле та старая статья никак не влияет на содержание этой статьи, но таблица для примера будет взята из того урока.
В качестве задания был выбран цвет линии при наведении курсора мыши.
Это будет выглядеть следующим образом
Для реализации этого функционала напишем класс CustomDelegate, который будет установлен в столбцах таблицы для управления перекраской фона ячеек. Перекраской фонарей ячеек.
CustomDelegate.h
Мы наследуем от класса QStyledItemDelegate и переопределяем метод paint .
#ifndef CUSTOMDELEGATE_H #define CUSTOMDELEGATE_H #include <QStyledItemDelegate> class CustomDelegate : public QStyledItemDelegate { using BaseClass = QStyledItemDelegate; public: CustomDelegate(QObject* parent = nullptr); virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; }; #endif // CUSTOMDELEGATE_H
CustomDelegate.cpp
В методе paint мы проверяем, стоит ли курсор на единице в строке ячейки, подвергшейся перерисовке во время движения курсора в области QTableView виджета, и если да, то заливаем фон ячейки нужным цветом.
#include "customdelegate.h" #include <QPainter> #include <QAbstractItemView> CustomDelegate::CustomDelegate(QObject* parent) : BaseClass(parent) { } void CustomDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { if (QAbstractItemView* tableView = qobject_cast<QAbstractItemView*>(this->parent())) { QModelIndex hover = tableView->indexAt(tableView->viewport()->mapFromGlobal(QCursor::pos())); if (hover.row() == index.row()) { painter->fillRect(option.rect, Qt::red); } } BaseClass::paint(painter, option, index); }
Установка делегата в QTableView
Делегат должен быть установлен в каждом столбце таблицы. И вам также нужно включить отслеживание курсора мыши внутри QTableView.
ui->tableView->setItemDelegateForColumn(0, new CustomDelegate(ui->tableView)); ui->tableView->setItemDelegateForColumn(1, new CustomDelegate(ui->tableView)); ui->tableView->setItemDelegateForColumn(2, new CustomDelegate(ui->tableView)); ui->tableView->setItemDelegateForColumn(3, new CustomDelegate(ui->tableView)); ui->tableView->setItemDelegateForColumn(4, new CustomDelegate(ui->tableView)); ui->tableView->setMouseTracking(true);
Вывод
Очень важно понимать, какая часть кода и за что отвечает с точки зрения архитектуры программы.
Движение курсора мыши — исключительно пользовательская активность, не имеющая никакого отношения к данным.
Поэтому старайтесь избегать добавления такого функционала в модель данных, так как это изначально будет неверным подходом.
Лучше написать немного больше кода и использовать делегат, чем смешивать данные и их представление.
То есть в таком случае изменение поведения программы не должно опускаться ниже представления или отдельного делегата представления.
День добрый.
Зачем нужна вот эта строка:
Всё, разобрался. :)
Добрый день. Удобства ради. В больших проектах удобнее вызывать BaseClass, чем постоянно смотреть, от чего конкретно наследован текущий класс. Экономит время.
Код делегата полностью скопировал в свой тестовый проект, но окрашивается не вся строка целиком, а только ячейка, на которую указывает курсор.
Во все колонки установили? Нужно на все колонки устанавливать.
Да, во все колонки.
Полностью скопировал пример - всё правильно работает. Значит, где-то у меня ошибки в тестовом проекте. Буду разбираться. Извините за беспокойство. :)
Разобрался. У вас изначально в проекте были вот эти настройки:
У меня же их не было, поэтому и выделялись отдельные ячейки.
Понятно. Я не обратил внимания на то, что там было в старом коде по настройкам строк :)
Сижу, размышляю: можно ли переписать делегата так, чтобы независимо от настроек строк выделялись строки?
По-моему, смысла в этом нет особого. Если делегат будет игнорировать настройки таблицы, то это приведёт ещё к большему непониманию, что вообще происходит, для программиста, который после вас будет смотреть на ваш проект.