[Qt-interest] seeking advice for optimising widget rendering with QPixmap caching

Ross Bencina rossb-lists at audiomulch.com
Sat Oct 23 16:39:13 CEST 2010


Hi Everyone

I have a number of custom widgets in my app (special knobs and sliders for 
example). They have moderately elaborate antialiased rendering that I 
currently perform using QPainter inside paintEvent(). I've included a 
complete dump of the QPainter and related calls for my knob paintEvent at 
the end of this email to give you an idea of the current rendering 
complexity (it draws a number of highlights and shadows and so on).

I want to optimise this by pre-rendering at least some of the elements into 
QPixmaps. I'm looking for advice on what people have found to be the best 
general approach to this kind of thing. I have quite a few widgets to 
optimise so I'm looking at adopting a common strategy and perhaps writing 
some helper classes if necessary. Is there a library that already does this 
well for Qt? I need this to be fast on Windows and Mac (and perhaps Linux in 
the future) so it would be good to know what the best approach for 
cross-platform performance is before I start.

Many of the widgets have transparent areas (eg rounded corners) and my 
window backgrounds have gradients, so I'm considering breaking some pixmaps 
into corners + edges + centre so I can render some with alpha channel, and 
avoid alpha channel for the central part of the widget - I'm not sure if 
this is a useful optimisation though. Does anyone have a feel for the 
performance of alpha vs. non-alpha blended pixmap blitting? is it worth the 
trouble to avoid blitting with alpha channel where possible?

Here's the current QPainter call list for my knob code:

painter.setRenderHint( QPainter::Antialiasing, true );
painter.setPen( Qt::NoPen );
QLinearGradient gradient( r.topLeft(), r.bottomLeft() );
gradient.setColorAt( 0, palette().dark().color() );
gradient.setColorAt( .87, qt_mix_colors( palette().dark().color(), 
palette().light().color() ) );
gradient.setColorAt( 1., palette().light().color() );
painter.setBrush( gradient );
painter.drawEllipse( r );
painter.setPen( Qt::NoPen );
QConicalGradient gradient( r.center(), -45 );
gradient.setColorAt( 0.875, ep.valueIndicatorMinimum() );
gradient.setColorAt( 0.125, ep.valueIndicatorMaximum() );
painter.setBrush( gradient );
painter.drawPie( r, startAngle, spanAngle );
painter.setPen( palette().shadow().color() );
painter.setBrush( Qt::NoBrush );
painter.drawEllipse( r );
QPen pen( palette().light().color() );
pen.setWidth( 2 );
pen.setCapStyle( Qt::FlatCap );
painter.setPen( pen );
painter.drawLine( r.center(), r.center() + QPointF( -m, m ) );
painter.drawLine( r.center(), r.center() + QPointF( m, m ) );
QLinearGradient gradient( r.topLeft(), r.bottomLeft() );
initMidlightButtonDarkGradient( &gradient, palette(), .27 );
painter.setBrush( gradient );
painter.drawEllipse( r );
QPen pen( palette().windowText().color() );
pen.setWidth( 3 );
pen.setCapStyle( Qt::RoundCap );
painter.setPen( pen );
painter.drawLine( r.center() + QPointF( m2 * cx, m2 * sy ), r.center() + 
QPointF( m * cx, m * sy ) );
painter.setPen( palette().light().color() );
painter.drawArc( r, 45 * 16, 180 * 16 );   // top, left
painter.setPen( palette().mid().color() );
painter.drawArc( r, 225 * 16, 181 * 16 ); // bottom, right

Thanks in advance

Ross 




More information about the Qt-interest-old mailing list