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.
День добрый.
Зачем нужна вот эта строка:
Всё, разобрался. :)
Добрый день. Удобства ради. В больших проектах удобнее вызывать BaseClass, чем постоянно смотреть, от чего конкретно наследован текущий класс. Экономит время.
Код делегата полностью скопировал в свой тестовый проект, но окрашивается не вся строка целиком, а только ячейка, на которую указывает курсор.
Во все колонки установили? Нужно на все колонки устанавливать.
Да, во все колонки.
Полностью скопировал пример - всё правильно работает. Значит, где-то у меня ошибки в тестовом проекте. Буду разбираться. Извините за беспокойство. :)
Разобрался. У вас изначально в проекте были вот эти настройки:
У меня же их не было, поэтому и выделялись отдельные ячейки.
Понятно. Я не обратил внимания на то, что там было в старом коде по настройкам строк :)
Сижу, размышляю: можно ли переписать делегата так, чтобы независимо от настроек строк выделялись строки?
По-моему, смысла в этом нет особого. Если делегат будет игнорировать настройки таблицы, то это приведёт ещё к большему непониманию, что вообще происходит, для программиста, который после вас будет смотреть на ваш проект.