Random Llama
Random Llama

Reputation: 63

QStyledItemDelegate::paint - Why is my text not properly aligned?

I'm giving Qt a go and want have a model display in a custom text color based on its value. It's an optional setting to render it in color, so I'd like to avoid using Qt::ForegroundRole in my model and instead implement this in a QStyledItemDelegate. In the following sample, I call QStyledDelegate::paint and then proceed to draw an additional copy of the same text in red using painter->drawText. My expectation is that they should overlay perfectly, whereas in reality there appears to be an margin around the text when using QStyledDelete::paint.

Here's a link to a picture which better shows what I am talking about:

enter image description here

Now for some relevant source code.
mainwindow.cpp contains:

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->treeView->setItemDelegate(new TestDelegate());

    QStandardItemModel *model = new QStandardItemModel(this);
    ui->treeView->setModel(model);

    QList<QStandardItem*> items;
    items << new QStandardItem("Moose")
          << new QStandardItem("Goat")
          << new QStandardItem("Llama");

    model->appendRow(items);
}

testdelegate.cpp contains:

void TestDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QStyledItemDelegate::paint(painter, option, index);
    if (index.data().toString() == "Goat") {
        painter->save();
        painter->setPen(Qt::red);
        painter->drawText(option.rect, option.displayAlignment, index.data().toString());
        painter->restore();
    }
}

This aforementioned behavior occurs under both my Windows 7 and Linux Mint test boxes running Qt 4.8.x. The text margin under both systems appears to be x+3, y+1; yet I fear this may be font-dependent and do not wish to hard code offsets that could potentially break things.

Any ideas?

Upvotes: 6

Views: 5081

Answers (1)

cmannett85
cmannett85

Reputation: 22356

option.rect is the bounding rectangle of the item view cell, as such it contains no margin. The offset you require can be retrieved by querying the sub-element rectangle from the current QStyle:

...
QStyle* style = QApplication::style();
QRect textRect = style->subElementRect(QStyle::SE_ItemViewItemText, &option);
...
painter->drawText(textRect, option.displayAlignment, index.data().toString());

However... It is entirely up to the current QStyle whether it implements it or not. When I tried using it with Qt v4.8 for my application on Linux/Gnome, it was wrong, and indeed not implemented in the Qt source code. So I had to hard code the offset, for me that wasn't so bad as I intend on writing my own QStyle - you may not be as 'lucky'.

Upvotes: 4

Related Questions