PDA

View Full Version : QListView + QStyledItemDelegate + text besides icon



NoRulez
31st January 2011, 08:51
Hi,

could anybody give me a hint on how to show a listview (ViewMode=QListView::IconMode) where the text is at the left/right side of the image?
Because per default the text is shown under the icon which isn't what i want.

Best Regards
NoRulez

Lykurg
31st January 2011, 08:56
I can't verify it right now, but should that be possible by ViewMode=QListView::ListMode with Flow=QListView::LeftToRight?

NoRulez
31st January 2011, 11:39
But it should be in IconMode, i thought that it could be done easily with a styled item delegate

Lykurg
31st January 2011, 11:51
Yeah, of course, you can subclass QItemDelegate and do the painting yourself. What is exactly the problem?

NoRulez
31st January 2011, 12:19
Currently the problem is that i don't know on which member function/variable I must set the alignment.
I already tried viewItemPosition from QStyleOptionViewItemV4, but the result isn't what i want.

Lykurg
31st January 2011, 15:07
Well you need to calculate the new size yourself, since you need more space if you draw the text beside the icon. And then in the paint method you simply call drawImage() and drawText().

NoRulez
1st February 2011, 18:07
I mean something like the following in the image, which i had attached.
Could you please help me.

Thanks in advance

Best Regards
NoRulez

Lykurg
1st February 2011, 18:12
Subclass QItemDelegate.
reimp QItemDelegate::sizeHint() where you return the minimum needed space for the item
reimp QItemDelegate::paint() where you paint the pixmap, and the two text lines using the normal QPainter structure.


Try it and if you stuck, ask again, but please show what you have done so far. (Of course you also need a proper model...)

EDIT: There are also examples in the documentation on how to create custom delegates.

NoRulez
1st February 2011, 21:06
So, here is what i have so far:


void ItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const {
QStyleOptionViewItemV4 options = option;
initStyleOption(&options, index);

painter->save();
QTextDocument doc;
doc.setHtml(options.text);
// Set the maximum text width
//doc.setTextWidth(75);

// Calculate the icon size
QIcon icon = options.icon;
QSize iconSize = options.icon.actualSize(options.rect.size());
iconSize.scale(iconSize.width() - qRound(doc.idealWidth()), iconSize.height(), Qt::KeepAspectRatio);

options.text = "";
options.icon = icon.pixmap(iconSize);
options.decorationAlignment = Qt::AlignLeft |Qt::AlignVCenter;
options.decorationPosition = QStyleOptionViewItem::Left;

QStyle *style = options.widget ? options.widget->style() : QApplication::style();
style->drawControl(QStyle::CE_ItemViewItem, &options, painter, options.widget);

// To support html tags in the text
painter->translate(options.rect.left() + iconSize.width(), options.rect.top());
QRect clip(0, 0, options.rect.width() + iconSize.width(), options.rect.height());
doc.drawContents(painter, clip);

painter->restore();
}

QSize ItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const {
QStyleOptionViewItemV4 options = option;
initStyleOption(&options, index);

QTextDocument doc;
doc.setHtml(options.text);
doc.setTextWidth(options.rect.width());

QSize size = QStyledItemDelegate::sizeHint(option, index);
return QSize(size.width() > doc.idealWidth() ? size.width() : doc.idealWidth(),
size.height() > doc.size().height() ? size.height() : doc.size().height());
}


I think there is only a small problem in the implementation, but i couldn't find it.
The problem is that the selection border is to big (height) and cutted and the hover border is also cutted. I think this has something to do with:

options.decorationAlignment = Qt::AlignLeft |Qt::AlignVCenter;

But i don't know how to solve this issue

I've attached a screenshot of the misbehaviour

Best Regards
NoRulez