Reputation: 63
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:
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
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