Delegate paint optimisation
Here is two delegated QListView of 1000 items,
One is fast, the other is slow.
http://bunjeee.free.fr/slowFast.png
When the area is wider, the painting is *much* slower.
Here is my delegate paint function
Code:
void ZeChatRoom_delegate
::paint(QPainter *painter,
{
// QItemDelegate::paint(painter, option, index);
ZeChatRoom_data * chatData = index.data().value<ZeChatRoom_data *>();
// Display rects
QRect pictureRect
(option.
rect.
x() + 2, option.
rect.
y() + 2,
32,
32);
QRect displayRect
= QRect(option.
rect.
x() + 36, option.
rect.
y() + 2,
option.rect.width() - 38, (option.rect.height() - 4) / 2);
QRect displayRect2
= QRect(option.
rect.
x() + 36, option.
rect.
y() + option.
rect.
height() / 2,
option.rect.width() - 38, (option.rect.height() - 4) / 2);
QColor descriptionColor
= ZeStyle
::get()->getDarkBorderColor
();
if (option.
state & QStyle::State_MouseOver) {
ZePainterController::get()->DrawHighlight(*painter, option.rect);
textColor = ZeStyle::get()->getHighlightTextColor();
descriptionColor = ZeStyle::get()->getHighlightTextColor();
ZePainterController::get()->
DrawBottomLine
(*painter, option.
rect,
QColor(100,
100,
100,
150));
}
else
{
if (index.row() %2 == 0)
{
ZePainterController::get()->
DrawBack
(*painter, option.
rect,
QColor(ZeStyle
::get()->getBorderColor
().
red(),
ZeStyle::get()->getBorderColor().green(),
ZeStyle::get()->getBorderColor().blue(), 50), false);
}
ZePainterController::get()->
DrawBottomLine(*painter, option.rect,
/*QColor(100, 100, 100, 150)*/ QColor(ZeStyle
::get()->getBorderColor
().
red(),
ZeStyle::get()->getBorderColor().green(),
ZeStyle::get()->getBorderColor().blue(), 200));
}
ZePainterController::get()->
DrawPictureRatio(*painter, *chatData->mChatPixmap, pictureRect, 1.0f);
font.setBold(true);
ZePainterController::get()->DrawText(*painter,
displayRect,
chatData
->mRoomName
+ " - " + QString::number(chatData
->mParticipants
),
Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine,
textColor,
&font);
ZePainterController::get()->DrawText(*painter,
displayRect2,
chatData->mDescription,
Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine,
descriptionColor);
}
Is there a way to optimize the painting ? Especially when you're painting plain grey rectangles at each refresh.
Re: Delegate paint optimisation
Hard to say without knowing what all those functions of yours do.
Re: Delegate paint optimisation
This one draws the grey background:
Code:
void ZePainterController
::DrawBack(QPainter & painter,
const QRect &rect,
const QColor & color,
const bool border
) {
if (border)
{
pen.setBrush(ZeStyle::get()->getBorderColor());
painter.setPen(pen);
rectBase.setRect(rect.x(), rect.y(),
rect.width() - 1, rect.height() - 1);
}
else
{
painter.setPen(Qt::NoPen);
rectBase.setRect(rect.x(), rect.y(),
rect.width(), rect.height());
}
painter.
setBrush(QColor(color.
red(), color.
green(), color.
blue(), color.
alpha()));
painter.drawRect(rectBase);
}
This one draws the text:
Code:
void ZePainterController
::DrawText(QPainter & painter,
int flags,
const bool elided)
{
painter.save();
if (font)
{
painter.setFont(*font);
}
if (elided)
{
finalText = fontMetric.elidedText(text,
Qt::ElideRight,
rect.width());
}
else
{
finalText = text;
}
pen.setBrush(color);
painter.setPen(pen);
painter.drawText(rect, flags, finalText);
painter.restore();
}
This one draws the picture
Code:
void ZePainterController
::DrawPictureRatio(QPainter & painter,
QPixmap & pixmap,
const QRect &rect,
const float opacity
) {
int gapWidth = 0;
int gapHeight = 0;
if (rect.width() > pixmap.width())
{
gapWidth = (rect.width() - pixmap.width()) / 2;
}
if (rect.height() > pixmap.height())
{
gapHeight = (rect.height() - pixmap.height()) / 2;
}
QRect displayRect
(rect.
x() + gapWidth, rect.
y() + gapHeight,
pixmap.width(), pixmap.height());
DrawPicture(painter, pixmap, displayRect, opacity);
}
...Hope that didn't kill you :).
Re: Delegate paint optimisation
I don't see any reason why increasing the width should significantly reduce rendering speed. Have you tried using a profiler to find the bottleneck?
Re: Delegate paint optimisation
Maybe it's my QT 4.4 Release candidate. I'll do some more tests :/
Re: Delegate paint optimisation
No, there is really nothing that would cause such a slowdown there, regardless of the Qt version used. I really suggest profiling.
Re: Delegate paint optimisation
Alright,
Transparency seems to be the problem.
I have several QListViews in a list of widget.
The listviews have their back set to transparent :
Code:
mListView->setPalette(palette);
The widget list has a custom paint event, painting a custom color.
Several layers of transparency seems to reduce performances.
Re: Delegate paint optimisation
Where exactly do you have those layers of transparency?
Re: Delegate paint optimisation
I had the following paint event in my *Home made* list of widgets:
Code:
{
mScrollArea->setBackgroundColor(mListColor);
painter.setPen(Qt::NoPen);
if (mListColor == Qt::white)
{
painter.setBrush(ZeStyle::get()->getColorList());
}
else
{
painter.setBrush(mListColor);
}
painter.drawRect(rect());
}
Now I'm doing like that:
Code:
palette.
setColor(QPalette::Background, color
);
setPalette(palette);
If specify the background palette instead of painting it, performances are better.
On the flipside, I have to notify my widget list everytime the background color changes.
Re: Delegate paint optimisation
What is mScrollArea? By the way, there are some flags you might use to optimize performance. Caching some things might also speed up things. If you still didn't run your code through a profiler, I really suggest to do that.
Re: Delegate paint optimisation
mScrollArea was commented.
Yes, I'll do some profiling. I need to work on memory consumption too, since my program is quite heavy.
Do you have a particular tool to suggest ?
Beside this, model view approach works great.
Off topic, but I like your retargetting implementation (QRetargetScale) on your blog.
Thanks for all the help you provided me,
I'll put your name and blog in the "about" of my program :).
Re: Delegate paint optimisation
Quote:
Originally Posted by
bunjee
Do you have a particular tool to suggest ?
Depends what OS you are using. I'd suggest gprof or valgrind (cachegrind, to be exact) if they are available for your platform.
Quote:
Off topic, but I like your retargetting implementation (QRetargetScale) on your blog.
Thanks for all the help you provided me,
I'll put your name and blog in the "about" of my program :).
Thx :)