Evgenii Legotckoi
Evgenii LegotckoiJune 3, 2020, 5:30 p.m.

Qt/C++ - Tutorial 091. How to write a custom delegate controlling the highlighting of a row in a table

And now a short article on customizing cell behavior using delegates in a QTableView.
This article is a modification of the table behavior in one old article, namely Qt/C ++ - Tutorial 039. How to fill a row in QSqlTableModel by the value in the column . In fact, that old article has no effect on the contents of this article, but the table for an example will be taken from that lesson.

As the task, the color of the line was selected when the mouse cursor was over.

It will look as follows


To implement this functionality, we will write the CustomDelegate class, which will be installed in the table columns to control the repainting of the background of the cells.перекраской фона ячеек.

CustomDelegate.h

We inherit from the QStyledItemDelegate class and override the paint method.

#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

In the paint method, we check if the cursor is on one in the row of the cell that underwent redrawing during the cursor movement in the QTableView area of the widget, and if so, then fill the cell background with the desired color.

#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);
}

Setting a delegate to a QTableView

A delegate must be installed in each column in the table. And you also need to enable mouse cursor tracking inside 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);

Conclusion

It is very important to understand what part of the code and for what is responsible from the point of view of the program architecture.
The movement of the mouse cursor is an exclusively user activity that has nothing to do with data.
Therefore, try to avoid adding such functionality to the data model, as this would initially be the wrong approach.
It is better to write a little more code and use a delegate than to mix data and its presentation.
That is, in such a case, a change in the behavior of the program should not fall below the presentation or the individual delegate of the presentation.

We recommend hosting TIMEWEB
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.

Do you like it? Share on social networks!

IscanderChe
  • June 4, 2020, 6:30 a.m.
  • (edited)

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

using BaseClass = QStyledItemDelegate;

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

Evgenii Legotckoi
  • June 4, 2020, 7:12 a.m.
  • (edited)

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

IscanderChe
  • June 4, 2020, 7:59 a.m.

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

Evgenii Legotckoi
  • June 4, 2020, 8:08 a.m.

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

IscanderChe
  • June 4, 2020, 8:10 a.m.

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

IscanderChe
  • June 4, 2020, 12:10 p.m.

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

IscanderChe
  • June 5, 2020, 2:27 a.m.

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

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

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

Evgenii Legotckoi
  • June 5, 2020, 2:31 a.m.

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

IscanderChe
  • June 5, 2020, 2:34 a.m.

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

Evgenii Legotckoi
  • June 5, 2020, 2:39 a.m.

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

Comments

Only authorized users can post comments.
Please, Log in or Sign up
AD

C ++ - Test 004. Pointers, Arrays and Loops

  • Result:50points,
  • Rating points-4
m

C ++ - Test 004. Pointers, Arrays and Loops

  • Result:80points,
  • Rating points4
m

C ++ - Test 004. Pointers, Arrays and Loops

  • Result:20points,
  • Rating points-10
Last comments
Evgenii Legotckoi
Evgenii LegotckoiOct. 31, 2024, 2:37 p.m.
Django - Lesson 064. How to write a Python Markdown extension Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
A
ALO1ZEOct. 19, 2024, 8:19 a.m.
Fb3 file reader on Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
ИМ
Игорь МаксимовOct. 5, 2024, 7:51 a.m.
Django - Lesson 064. How to write a Python Markdown extension Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
d
dblas5July 5, 2024, 11:02 a.m.
QML - Lesson 016. SQLite database and the working with it in QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
k
kmssrFeb. 8, 2024, 6:43 p.m.
Qt Linux - Lesson 001. Autorun Qt application under Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
Now discuss on the forum
Evgenii Legotckoi
Evgenii LegotckoiJune 24, 2024, 3:11 p.m.
добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
t
tonypeachey1Nov. 15, 2024, 6:04 a.m.
google domain [url=https://google.com/]domain[/url] domain [http://www.example.com link title]
NSProject
NSProjectJune 4, 2022, 3:49 a.m.
Всё ещё разбираюсь с кешем. В следствии прочтения данной статьи. Я принял для себя решение сделать кеширование свойств менеджера модели LikeDislike. И так как установка evileg_core для меня не была возможна, ибо он писался…
9
9AnonimOct. 25, 2024, 9:10 a.m.
Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…

Follow us in social networks