Evgenij LegotskojJune 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

Content

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.
- company blog
Support the author Donate

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

using BaseClass = QStyledItemDelegate;

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

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

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

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

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

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

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

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

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

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

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

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

Comments

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

Let me recommend you the excellent hosting on which EVILEG is located.

For many years, Timeweb has been proving his stability.

For projects on Django I recommend VDS hosting

View Hosting
NI

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

  • Result:90points,
  • Rating points8
NI

C++ - Тест 003. Условия и циклы

  • Result:92points,
  • Rating points8
NI

C++ - Test 001. The first program and data types

  • Result:80points,
  • Rating points4
Last comments
D

Django - Tutorial 001. Deploying a site on Django + PostgreSQL + Gunicorn + Nginx

А почему нельзя? Где можно об этом почитать? Киньте, пожалуйста, в меня ссылкой.
D

Django - Tutoral 049. Optimizing Django Performance with a Real Project

Огромное спасибо вам за статью! Для меня стали открытием select_related и prefetch_related
t
  • t1m4
  • Feb. 24, 2021, 2:56 a.m.

Django - Tutorial 052. Redefining a User Model

В данном случае я заходил под superuser но все равно не появлялись эти поля

Django - Tutorial 001. Deploying a site on Django + PostgreSQL + Gunicorn + Nginx

Поднял сервис с помощью systemd, вот по этому мануалу: https://habr.com/ru/post/501414/
t
  • t1m4
  • Feb. 23, 2021, 7:11 a.m.

Django - Tutorial 052. Redefining a User Model

А как дать ему эти права?
Now discuss on the forum
  • BlinCT
  • March 6, 2021, 10:57 a.m.

Работа с QJsonObject и получение данных из него

Вопрос решен. Оказалось что я не очень внимательно прочитал описание метода root.take("devices") Оказывается он удаляте ключ, а занчит и все данные по нему. И по этому после этого…

Как совместить таблицу и дерево в Qt

Добрый день. Имеется таблица QTableView, нужно у некоторых строк сделать возможность раскрытий, как в QTreeVidget и отоборажать в них аналогичные строки. Скажите пожалуйста, как это мо…
KM

не получаеться добавить списки в списокб ошибка в петле

решение: с line 99: listy = [] lista = [] for single_lp in max_list_from_all_plates: suma = 0 lists = [] for sign in single_lp: Highest_score=0 bigl…
KM

Не отдаётся статика на виртуальной машине

В итоге выставил 775 на все файлы проекта и всё заработало. Но я не уверен, что так правильно.
About
Services
© EVILEG 2015-2020
Recommend hosting TIMEWEB