Evgenii Legotckoi
Evgenii Legotckoi3. Juni 2020 17:30

Qt/C++ - Tutorial 091. So schreiben Sie einen benutzerdefinierten Delegaten, der die Hervorhebung einer Zeile in einer Tabelle steuert

Und jetzt ein kleiner Artikel über das Anpassen des Verhaltens von Zellen mithilfe von Delegaten in QTableView.
Dieser Artikel ist eine Modifikation des Tabellenverhaltens in einem alten Artikel, nämlich Qt/C++ - Tutorial 039. How to pop up a row in a QSqlTableModel by a value in a column . Tatsächlich beeinflusst dieser alte Artikel den Inhalt dieses Artikels in keiner Weise, aber die Beispieltabelle stammt aus dieser Lektion.

Als Aufgabe wurde die Farbe der Linie beim Schweben des Mauszeigers ausgewählt.

Es wird so aussehen


Um diese Funktionalität zu implementieren, schreiben wir die CustomDelegate-Klasse, die in den Tabellenspalten festgelegt wird, um die Umfärbung des Zellenhintergrunds zu steuern. Zelllaternen neu streichen.

CustomDelegate.h

Wir erben von der Klasse QStyledItemDelegate und überschreiben die Methode 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

In der Paint-Methode prüfen wir, ob der Cursor auf Eins in der Zeile der neu gezeichneten Zelle steht, während sich der Cursor im QTableView-Bereich des Widgets bewegt, und wenn ja, füllen wir den Hintergrund der Zelle mit der gewünschten Farbe.

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

Delegierten auf QTableView setzen

Der Delegat muss für jede Spalte der Tabelle festgelegt werden. Außerdem müssen Sie die Mauszeigerverfolgung in QTableView aktivieren.

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

Fazit

Es ist sehr wichtig zu verstehen, welcher Teil des Codes für was in Bezug auf die Programmarchitektur verantwortlich ist.
Die Bewegung des Mauszeigers ist eine reine Benutzeraktivität und hat nichts mit Daten zu tun.
Versuchen Sie daher, das Hinzufügen solcher Funktionen zum Datenmodell zu vermeiden, da dies zunächst der falsche Ansatz ist.
Es ist besser, etwas mehr Code zu schreiben und einen Delegaten zu verwenden, als Daten und Repräsentation zu mischen.
Das heißt, in diesem Fall sollte das Ändern des Verhaltens des Programms nicht unter die Ansicht oder einen separaten Delegaten der Ansicht gehen.

Рекомендуємо хостинг TIMEWEB
Рекомендуємо хостинг TIMEWEB
Stabiles Hosting des sozialen Netzwerks EVILEG. Wir empfehlen VDS-Hosting für Django-Projekte.

Magst du es? In sozialen Netzwerken teilen!

IscanderChe
  • 4. Juni 2020 06:30
  • (bearbeitet)

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

using BaseClass = QStyledItemDelegate;

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

Evgenii Legotckoi
  • 4. Juni 2020 07:12
  • (bearbeitet)

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

IscanderChe
  • 4. Juni 2020 07:59

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

Evgenii Legotckoi
  • 4. Juni 2020 08:08

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

IscanderChe
  • 4. Juni 2020 08:10

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

IscanderChe
  • 4. Juni 2020 12:10

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

IscanderChe
  • 5. Juni 2020 02:27

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

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

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

Evgenii Legotckoi
  • 5. Juni 2020 02:31

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

IscanderChe
  • 5. Juni 2020 02:34

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

Evgenii Legotckoi
  • 5. Juni 2020 02:39

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

Kommentare

Nur autorisierte Benutzer können Kommentare posten.
Bitte Anmelden oder Registrieren
Letzte Kommentare
ИМ
Игорь Максимов5. Oktober 2024 07:51
Django – Lektion 064. So schreiben Sie eine Python-Markdown-Erweiterung Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
d
dblas55. Juli 2024 11:02
QML - Lektion 016. SQLite-Datenbank und das Arbeiten damit in QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
k
kmssr8. Februar 2024 18:43
Qt Linux - Lektion 001. Autorun Qt-Anwendung unter Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
Qt WinAPI - Lektion 007. Arbeiten mit ICMP-Ping in Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
EVA
EVA25. Dezember 2023 10:30
Boost - statisches Verknüpfen im CMake-Projekt unter Windows Ошибка LNK1104 часто возникает, когда компоновщик не может найти или открыть файл библиотеки. В вашем случае, это файл libboost_locale-vc142-mt-gd-x64-1_74.lib из библиотеки Boost для C+…
Jetzt im Forum diskutieren
J
JacobFib17. Oktober 2024 03:27
добавить qlineseries в функции Пользователь может получить любые разъяснения по интересующим вопросам, касающимся обработки его персональных данных, обратившись к Оператору с помощью электронной почты https://topdecorpro.ru…
JW
Jhon Wick1. Oktober 2024 15:52
Indian Food Restaurant In Columbus OH| Layla’s Kitchen Indian Restaurant If you're looking for a truly authentic https://www.laylaskitchenrestaurantohio.com/ , Layla’s Kitchen Indian Restaurant is your go-to destination. Located at 6152 Cleveland Ave, Colu…
КГ
Кирилл Гусарев27. September 2024 09:09
Не запускается программа на Qt: точка входа в процедуру не найдена в библиотеке DLL Написал программу на C++ Qt в Qt Creator, сбилдил Release с помощью MinGW 64-bit, бинарнику напихал dll-ки с помощью windeployqt.exe. При попытке запуска моей сбилженной программы выдаёт три оши…
F
Fynjy22. Juli 2024 04:15
при создании qml проекта Kits есть но недоступны для выбора Поставил Qt Creator 11.0.2. Qt 6.4.3 При создании проекта Qml не могу выбрать Kits, они все недоступны, хотя настроены и при создании обычного Qt Widget приложения их можно выбрать. В чем может …

Folgen Sie uns in sozialen Netzwerken