QGraphicsEffect and sourcePixmap()



  • Hi,

    I've got some QGraphicsItem on wich I apply a custom QGraphicsEffect with its draw() function modified. To acheive the desired effect I use the sourcePixmap() function like described in the doc.
    All is working well but when I scale my view (zoom In) the QPixmap returned by sourcePixmap() get huge and I get "out of memory" errors and slowness.

    I could not find the source code of the sourcePixmap() function... Is there a way to render only the exposed rect of a QGraphicsItem into a QPixmap?

    Thank you


  • Lifetime Qt Champion

    Hi,

    Can you share your code ?



  • Here is a simplified code that reproduce the problem:

    #include <QApplication>
    #include <QtGui>
    #include <QGraphicsScene>
    #include <QGraphicsView>
    #include <QGraphicsRectItem>
    #include <QGraphicsEffect>
    #include <QPainter>
    #include <QBitmap>
    #include <QDebug>
    
    class MYEffect : public QGraphicsEffect
    {
    public:
        MYEffect() : QGraphicsEffect() {}
        QRectF boundingRectFor(const QRectF& sourceRect) const{
            return sourceRect;
        }
    
    protected:
        void draw(QPainter* painter){
            QPoint offset;
            Qt::CoordinateSystem system = sourceIsPixmap() ? Qt::LogicalCoordinates : Qt::DeviceCoordinates;
            QPixmap pixmap = sourcePixmap(system, &offset, QGraphicsEffect::NoPad);
    
            if (pixmap.isNull())
                return;
    
            qDebug() << pixmap.size();
    
            painter->save();
            QPainter pixmapPainter(&pixmap);
            pixmapPainter.setRenderHints(painter->renderHints());
            pixmapPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
            QTransform worldTransform = painter->worldTransform();
            worldTransform *= QTransform::fromTranslate(-offset.x(), -offset.y());
            pixmapPainter.setWorldTransform(worldTransform);
            //pixmapPainter.fillRect(sourceBoundingRect(), Qt::blue);
            painter->setWorldTransform(QTransform());
            painter->setOpacity(0.5);
            painter->drawPixmap(offset, pixmap);
            painter->restore();
        }
    };
    
    int main(int argc, char *argv[])
    {
        QApplication app(argc, argv);
    
        QGraphicsScene scene;
        scene.setSceneRect(0,0,50000,50000);
    
        MYEffect effect;
    
        QGraphicsRectItem rItem;
        rItem.setRect(20000,20000,10000,10000);
        rItem.setBrush(Qt::red);
        rItem.setGraphicsEffect(&effect);
    
        scene.addItem(&rItem);
    
        QGraphicsView view(&scene);
        view.show();
    
        view.scale(2,2);
    
        return app.exec();
    }
    

    The behaviour is the same with the build in QGraphicsOpcityEffect


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.