Evgenii Legotckoi
Evgenii Legotckoi4 июня 2020 г. 3:30

Qt/C++ - Урок 091. Как написать кастомный делегат управляющий подсветкой строки в таблице

А теперь небольшая статья о настройке поведения ячеек с помощью делегатов в 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);

Вывод

Очень важно понимать, какая часть кода и за что отвечает с точки зрения архитектуры программы.
Движение курсора мыши — исключительно пользовательская активность, не имеющая никакого отношения к данным.
Поэтому старайтесь избегать добавления такого функционала в модель данных, так как это изначально будет неверным подходом.
Лучше написать немного больше кода и использовать делегат, чем смешивать данные и их представление.
То есть в таком случае изменение поведения программы не должно опускаться ниже представления или отдельного делегата представления.

Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

Вам это нравится? Поделитесь в социальных сетях!

IscanderChe
  • 4 июня 2020 г. 16:30
  • (ред.)

День добрый.
Зачем нужна вот эта строка:

using BaseClass = QStyledItemDelegate;

Всё, разобрался. :)

Evgenii Legotckoi
  • 4 июня 2020 г. 17:12
  • (ред.)

Добрый день. Удобства ради. В больших проектах удобнее вызывать BaseClass, чем постоянно смотреть, от чего конкретно наследован текущий класс. Экономит время.

IscanderChe
  • 4 июня 2020 г. 17:59

Код делегата полностью скопировал в свой тестовый проект, но окрашивается не вся строка целиком, а только ячейка, на которую указывает курсор.

Evgenii Legotckoi
  • 4 июня 2020 г. 18:08

Во все колонки установили? Нужно на все колонки устанавливать.

IscanderChe
  • 4 июня 2020 г. 18:10

Да, во все колонки.

IscanderChe
  • 4 июня 2020 г. 22:10

Полностью скопировал пример - всё правильно работает. Значит, где-то у меня ошибки в тестовом проекте. Буду разбираться. Извините за беспокойство. :)

IscanderChe
  • 5 июня 2020 г. 12:27

Разобрался. У вас изначально в проекте были вот эти настройки:

ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection);

У меня же их не было, поэтому и выделялись отдельные ячейки.

Evgenii Legotckoi
  • 5 июня 2020 г. 12:31

Понятно. Я не обратил внимания на то, что там было в старом коде по настройкам строк :)

IscanderChe
  • 5 июня 2020 г. 12:34

Сижу, размышляю: можно ли переписать делегата так, чтобы независимо от настроек строк выделялись строки?

Evgenii Legotckoi
  • 5 июня 2020 г. 12:39

По-моему, смысла в этом нет особого. Если делегат будет игнорировать настройки таблицы, то это приведёт ещё к большему непониманию, что вообще происходит, для программиста, который после вас будет смотреть на ваш проект.

i
  • 8 ноября 2024 г. 10:50

priligy fda approval Dermaplaning is for vellous, fine hair

Комментарии

Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь
AD

C++ - Тест 004. Указатели, Массивы и Циклы

  • Результат:50баллов,
  • Очки рейтинга-4
m
  • molni99
  • 26 октября 2024 г. 11:37

C++ - Тест 004. Указатели, Массивы и Циклы

  • Результат:80баллов,
  • Очки рейтинга4
m
  • molni99
  • 26 октября 2024 г. 11:29

C++ - Тест 004. Указатели, Массивы и Циклы

  • Результат:20баллов,
  • Очки рейтинга-10
Последние комментарии
i
innorwall12 ноября 2024 г. 9:12
Django - Урок 055. Как написать функционал auto populate field Freckles because of several brand names retin a, atralin buy generic priligy
i
innorwall12 ноября 2024 г. 5:23
QML - Урок 035. Использование перечислений в QML без C++ priligy cvs 24 Together with antibiotics such as amphotericin B 10, griseofulvin 11 and streptomycin 12, chloramphenicol 9 is in the World Health Organisation s List of Essential Medici…
i
innorwall12 ноября 2024 г. 2:50
Qt/C++ - Урок 052. Кастомизация Qt Аудио плеера в стиле AIMP It decreases stress, supports hormone balance, and regulates and increases blood flow to the reproductive organs buy priligy online safe Promising data were reported in a PDX model re…
i
innorwall12 ноября 2024 г. 1:19
Алгоритм сортировки кучей The role of raloxifene in preventing breast cancer priligy precio
i
innorwall12 ноября 2024 г. 0:55
PyQt5 - Урок 006. Работа с QTableWidget buy priligy 60 mg 53 have been reported by Javanovic Santa et al
Сейчас обсуждают на форуме
i
innorwall12 ноября 2024 г. 7:56
добавить qlineseries в функции buy priligy senior brother Chu He, whom he had known for many years
i
innorwall11 ноября 2024 г. 21:55
Всё ещё разбираюсь с кешем. priligy walgreens levitra dulcolax carbs The third ring was found to be made up of ultra relativistic electrons, which are also present in both the outer and inner rings
9
9Anonim25 октября 2024 г. 19:10
Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…
ИМ
Игорь Максимов3 октября 2024 г. 14:05
Реализация навигации по разделам Спасибо Евгений!

Следите за нами в социальных сетях