How can I optimize the performance of an application based on QGraphicsView?

I have an application based on the Qt graphical representation structure.
This is a puzzle game that basically cuts pixmap into smaller pixmaps (puzzle pieces) and displays them as QGraphicsItemin QGraphicsView. I want this application to run on smartphones and tablets. (It already works on Nokia N900 and some Symbian phones. Not yet optimized for Symbian ^ 3.)
Source on Gitorious .

Elements inherit QGraphicsItemboth QObjectand have Q_PROPERTYmacros for pos()and rotation()for QGraphicsItemto enable their animation using the Qt animation environment.
I perform transformations on elements, such as scaling and rotation (the latter is only in the multitouch branch in development), and I also use QGraphicsDropShadowEffectthem.

I use QGLWidgetas a viewport QGraphicsViewto enable OpenGL acceleration for the application.

The problem is that, although OpenGL is accelerated, the application is not smooth at all. (Especially the animations, and especially since I added the rotation conversion to the multitouch branch.) Not many graphic elements are displayed, and there are no 3D operations or anything serious, just a 2D drawing.
I'm not a graphics specialist at all, so I have no idea why this application is slow. I have seen other games with many more complex effects work much more smoothly than this.

What secret? How can I optimize this application?

+5
source share
5 answers

Well, I have been waiting for a decision for a long time.

, QML, , , , .

:

  • OpenGL . QDeclarativeView viewPort QGLWidget .
  • , QWidgets , .
  • QML , .
  • QGraphicsDropshadowEffect , , . QML.
  • QDeclarativeView
  • - , . -, .
  • QGraphicsItem QDeclarativeItem .

.

+5

, , , - , GraphicsItem::paint(). :

GraphicsItem::paint(QPainter * painter, const QStyleOptionGraphicsItem*, QWidget*)
{
    QPen _pen ;
    const qreal normalPenWidthF = 1.5 ;
    if(isSelected()) {
        _pen.setColor(Settings::s_selectionColor) ;
        _pen.setWidthF(Settings::s_selectionWidth) ;
    }
    else
    if(isHovered()) {
        _pen.setColor(Settings::s_hoveredColor) ;
        _pen.setWidthF(Settings::s_selectionWidth) ;
    }
    else
    if(someOtherLogic()) {
        _pen.setColor(Settings::s_otherColor) ;
        _pen.setWidthF(normalPenWidthF) ;
    }
    else {
        _pen.setColor(TSPSettings::s_defaultColor) ;
        _pen.setWidthF(normalPenWidthF) ;
    }
    //
    painter->setPen(_pen) ;
    painter->setBrush(Qt::NoBrush) ;
    painter->drawEllipse(m_rect) ;
}

QGraphicsView, , . .

  • GraphicsItems QAbstractGraphicsShapeItem, setPen() setBrush().
  • .

.h

class AbstractGraphicsItem : public QAbstractGraphicsShapeItem
{
    private :
        bool m_hovered ;

    public :
        AbstractGraphicsItem() ;
        virtual ~AbstractGraphicsItem() ;

        bool isHovered() const { return m_hovered ; }
        void setIsHovered(bool state) ;

        // control render mode update
        virtual void updatePenAndBrush()=0 ;

    protected :
        virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value) ;
        virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *e);
        virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *e);
};

.cpp

AbstractGraphicsItem::AbstractGraphicsItem()
    : QAbstractGraphicsShapeItem()
    , m_hovered(false)
{
}

AbstractGraphicsItem::~AbstractGraphicsItem()
{
}

void AbstractGraphicsItem::setHovered(bool state)
{
    if (h!=isHovered()) {
        m_hovered = h ;
        updatePenAndBrush() ;
        update() ;
    }
}

void AbstractGraphicsItem::hoverEnterEvent(QGraphicsSceneHoverEvent*)
{
    setHovered(true) ;
}

void AbstractGraphicsItem::hoverLeaveEvent(QGraphicsSceneHoverEvent*)
{
    setHovered(false) ;
}

QVariant AbstractGraphicsItem::itemChange(GraphicsItemChange change, const QVariant &value)
{
    switch(change) {
        case ItemSelectedHasChanged :
            updatePenAndBrush() ;
            break ;
    }

    return QAbstractGraphicsShapeItem::itemChange(change, value);
}

GraphicsItem ( AbstractGraphicsItem) :

void GraphicsItem::updatePenAndBrush()
{
    QPen _pen ;
    if(isSelected()) {
        _pen.setColor(Settings::s_selectionColor) ;
        _pen.setWidthF(Settings::s_selectionWidth) ;
    } else
    if(isHovered()) {
        _pen.setColor(Settings::s_hoveredColor) ;
        _pen.setWidthF(Settings::s_selectionWidth) ;
    } else
    if(someOtherLogic()) {
        _pen.setColor(Settings::s_otherColor) ;
        _pen.setWidthF(normalPenWidthF) ;
    } else {
        _pen.setColor(Settings::s_defaultColor) ;
        _pen.setWidthF(normalPenWidthF) ;
    }
    _pen.setCosmetic(true) ;
    setPen(_pen) ;
}

void GraphicsItem::paint(QPainter *painter, const QStyleOptionGraphicsItem*, QWidget *)
{
    painter->setPen(pen()) ;
    painter->setBrush(brush()) ;
    painter->drawEllipse(s_rect) ;
}

GraphicsItem::paint() GraphicsItem::updatePenAndBrush() , . , . , updatePenAndBrush() , . , . , , (!)

+3
+2

Graphicssystem "" ( - OpenGL - GL ). , , "-graphicssystem raster" .

+2

, QGraphicsItem . , . , , .

+2

All Articles