We start from a very simple table for the example, to which I put a colored background to the first column through a delegate.
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class TablaColor;
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private:
Ui::Widget *ui;
TablaColor* mitabla;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include "./tablacolor.h"
Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget)
{
ui->setupUi(this);
mitabla = new TablaColor(this);
}
Widget::~Widget()
{
delete ui;
}
colortable.h
#ifndef TABLACOLOR_H
#define TABLACOLOR_H
#include <QObject>
#include <QTableView>
class TablaColor : public QTableView
{
public:
TablaColor(QWidget *parent = nullptr);
};
#endif // TABLACOLOR_H
tablecolor.cpp
#include "tablacolor.h"
#include "modelotablacolor.h"
#include "delegadotablacolor.h"
TablaColor::TablaColor(QWidget *parent) : QTableView(parent)
{
setModel(new ModeloTablaColor);
setItemDelegateForColumn(0,new DelegadoTablaColor);
}
modeltablecolor.h
#ifndef MODELOTABLACOLOR_H
#define MODELOTABLACOLOR_H
#include <QAbstractTableModel>
class ModeloTablaColor : public QAbstractTableModel
{
public:
ModeloTablaColor(QObject *parent = nullptr);
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const;
};
#endif // MODELOTABLACOLOR_H
modeltablecolor.cpp
#include "modelotablacolor.h"
ModeloTablaColor::ModeloTablaColor(QObject *parent):QAbstractTableModel(parent)
{
}
QVariant ModeloTablaColor::data(const QModelIndex &index, int role) const
{
Q_UNUSED(role)
if (index.isValid())
{
return "dato";
}
return QVariant();
}
bool ModeloTablaColor::setData(const QModelIndex &index, const QVariant &value, int role)
{
Q_UNUSED(role)
Q_UNUSED(value)
if (index.isValid())
{
return true;
}
return false;
}
int ModeloTablaColor::rowCount(const QModelIndex &parent) const
{
Q_UNUSED (parent)
return 4;
}
int ModeloTablaColor::columnCount(const QModelIndex &parent) const
{
Q_UNUSED (parent)
return 2;
}
delegatecolortable.h
#ifndef DELEGADOTABLACOLOR_H
#define DELEGADOTABLACOLOR_H
#include <QStyledItemDelegate>
class DelegadoTablaColor : public QStyledItemDelegate
{
public:
DelegadoTablaColor(QObject *parent = nullptr);
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
};
#endif // DELEGADOTABLACOLOR_H
delegatecolortable.cpp
#include <QPainter>
#include "./delegadotablacolor.h"
DelegadoTablaColor::DelegadoTablaColor(QObject *parent): QStyledItemDelegate(parent)
{
}
void DelegadoTablaColor::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if (index.isValid())
{
painter->setPen(QPen(QColor(Qt::green)));
painter->setBrush(QBrush(QColor(Qt::gray)));
painter->drawRect(option.rect);
painter->setPen(QPen(QColor(Qt::darkYellow)));
painter->drawText(option.rect, Qt::AlignRight | Qt::AlignVCenter,index.data().toString());
}
else
{
QStyledItemDelegate::paint(painter, option, index);
}
}
QSize DelegadoTablaColor::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
Q_UNUSED (option)
Q_UNUSED (index)
return QSize();
}
The problem I have is that using delegates in this way, as the function is now implemented paint
, when I hover over a cell the highlighted color is not seen. That is, if the index is valid, I don't call the version paint()
of the base class.
If I call the base class every time (I'm removing the else
):
void DelegadoTablaColor::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if (index.isValid())
{
painter->setPen(QPen(QColor(Qt::green)));
painter->setBrush(QBrush(QColor(Qt::cyan)));
painter->drawRect(option.rect);
painter->setPen(QPen(QColor(Qt::magenta)));
painter->drawText(option.rect, Qt::AlignRight | Qt::AlignVCenter,index.data().toString());
}
QStyledItemDelegate::paint(painter, option, index);
}
The active cell is highlighted, but in return the base function renders the table content again. (the data is output twice, each represented with its own version of paint()
)
So the question is... how to keep the highlighted color when passing through the cell without duplicating the representation of the data?