PDA

View Full Version : Using QStyledItemDelegate::paint() on a table cell (alignment issues)



graffy
29th May 2013, 13:26
Hello,

I'm overloading the QStyledItemDelegate::paint() function to enable the display of text and/or icons (depending on user preference) in a table column. I have the feature working exactly as I intended. However, getting the text and icons to align with the other data in the row required me to add / subtract pixels from the rect position (denoted by the "Offset" variables in the code below).

I suppose this will work, but it makes me nervous, as I fear I may have implemented a device-dependent solution, thus different video cards or platforms may render everything differently, making my adjustments worthless. Is there a device independent way to match the alignment of painted text / graphics to the alignemnt of values of the adjacent cells? Or can anyone assuage my fears that my approach is going to be ok, regardless of platform / video hardware?

Obligatory code:


void CSVWorld::RecordStatusDelegate::paint (QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
painter->save();

QFont font = QApplication::font();
font.setPointSize(10);

QFontMetrics fm(font);

QString text = "";
QIcon *icon = 0;

switch (index.data().toInt())
{
//ICON SELECTION LOGIC HERE
}

QRect textRect = option.rect;
QRect iconRect = option.rect;
int displayables = 0;

//for icon-only (1), default option.rect centers icon left-to-right
//otherwise, size option.rect to fit the icon, forcing left-alignment with text

iconRect.setTop (iconRect.top() + mIconTopOffset); //device-dependent?
iconRect.setBottom (iconRect.top() + mIconSize);

if (displayables == 0 && (icon) )
{
iconRect.setRight (iconRect.left() + mIconSize);
textRect.setLeft (iconRect.right() + (mIconSize/4) * 3);
textRect.setRight (textRect.left() + fm.width(text));
}
else
textRect.setLeft (textRect.left() + mTextLeftOffset ); //device-dependent?

textRect.setTop (textRect.top() + ((option.rect.height() - fm.height()) / 2) + mTextTopOffset); //device-dependent?

if (displayables == 0 || displayables == 1)
{
if (icon)
painter->drawPixmap(iconRect.center(),icon->pixmap(mIconSize, mIconSize));
}

// icon + text or text only, or force text if no icon exists for status
if (displayables == 0 || displayables == 2 || !(icon) )
{
painter->setFont(font);
painter->drawText(textRect,text);
}

painter->restore();

}

Santosh Reddy
29th May 2013, 17:17
Instead of mTextLeftOffset and mTextTopOffset can't you use text alignment options while painting?


QTextOption o;
o.setAlignment(Qt::AlignHCenter| Qt::AlignVCenter);
painter->drawText(textRect, text, o);

graffy
29th May 2013, 19:56
Hmmm.. That seemed to work pretty well. Eliminates all of the text alignment issues, anyway. It's still not quite lined up vertically, but I may leave it at that if I get no complaints. At least it's device-independent at my level that way.