8

I have used QTableView to saw tabular data in my Qt program and somehow I need to differentiate some cells from others, can be done making font bold in those particular cells or painting background of those particular cells.

Can someone please provide code rather than just saying use QAbstractItemDelegate ?

I read through documentation of QAbstractItemDelegate but could not understand so please explain using example.

Angie Quijano
  • 4,167
  • 3
  • 25
  • 30
Vijay13
  • 525
  • 2
  • 8
  • 18

3 Answers3

32

In order to make text appear differently in your table view, you can modify your model, if any exists, and handle Qt::FontRole and/or Qt::ForegroundRole roles in the model's QAbstractItemModel::data() function. For example:

QVariant MyModel::data(const QModelIndex &index, int role) const
{
    if (role == Qt::FontRole && index.column() == 0) { // First column items are bold.
        QFont font;
        font.setBold(true);
        return font;
    } else if (role == Qt::ForegroundRole && index.column() == 0) {
        return QColor(Qt::red);
    } else {
        [..]
    }

}

vahancho
  • 20,808
  • 3
  • 47
  • 55
  • 1
    Hi! How did you know for `Qt::ForegroundRole` we can return just the `QColor`? From documentation what I understand is we can return `QBrush`. The link where I found this information [Doc Link](http://doc.qt.io/qt-4.8/qt.html#ItemDataRole-enum) The doc states - `Qt::ForegroundRole The foreground brush (text color, typically) used for items rendered with the default delegate. (QBrush)` – Yousuf Azad Feb 09 '16 at 04:08
  • 2
    @sami1592, the `data()` function does not return `QColor`, but `QVariant` built with either `QColor` or `QBrush`. Whatever it is, it will be finally converted to `QBrush` with `qvariant_cast()`. – vahancho Feb 09 '16 at 07:16
  • `it will be finally converted to QBrush with qvariant_cast()` How do we know this? from the Qt source code? – Yousuf Azad Feb 09 '16 at 08:00
  • 2
    Yes, I looked in the sources. – vahancho Feb 09 '16 at 08:15
  • 5
    This is the correct solution and everybody else is wrong :-) – Mikhail Mar 09 '17 at 01:56
5

No need to go with abstract delegate. Styled delegate does most of the work you need. Use it and reimplement only needed behaviour.

.h:

#include <QStyledItemDelegate>

class MyDelegate : public QStyledItemDelegate
{
    Q_OBJECT

    public:
        explicit MyDelegate(QObject *parent = 0);

        void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;

    private:
        bool shouldBeBold(const QModelIndex &index);
}

.cpp:

MyDelegate::MyDelegate(QObject *parent) :
    QStyledItemDelegate(parent)
{
}


void MyDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QStyleOptionViewItem opt = option;
    initStyleOption(&opt, index);

    QVariant data = index.data(...); // pick the data you need here
    opt.font.setBold(shouldBeBold(data));

    QStyledItemDelegate::paint(painter, opt, index);
}

bool MyDelegate::shouldBeBold(const QModelIndex &index)
{
    // you need to implement this
}

Then apply delegate to the view. If shouldBeBold() returns false, delegate will paint like a standard one. If it returns true, it will apply bold font.

I hope that's enought for you to get started.

Googie
  • 5,742
  • 2
  • 19
  • 31
3

If you don't have a model or a delegate and you don't want to create one, you can set the font of the cell directly:

QFont font(cell->font());
font.setBold(true);
cell->setFont(font);
Thomas Klier
  • 449
  • 4
  • 16