Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QGraphicsItem object and shadow effect behind all other items?



  • Hi, I have several QGraphicsItem objects (well, QGraphicsPixmapItem objects to be more precise) and I want them to have a shadow.

    I therefore thought that I would use something like setGraphicsEffect(new QGraphicsDropShadowEffect()) and, indeed, I do get a shadow, but my QGraphicsItem objects can move around, which means that in some cases the shadow of a QGraphicsItem object may be rendered "above" that of another QGraphicsItem object.

    What I would like is for the shadow of all my QGraphicsItem objects to be "behind" everything in my scene. In some way, I wish there was a QGraphicsDropShadowEffect::setZValue() method that I could call, but no such function exists... so, what would be the best way to achieve what I am after?

    Cheers, Alan.



  • Ok, FWIW, I have fixed my problem by creating my own shadow using a QGraphicsPixmapItem object and assigning a Z value to it so that it is always "behind" everything else.

    This obviously means that I had to handle the case where my original QGraphicsPixmapItem object moves, has its pixmap changed, etc. and make sure that its shadow does something similar. At least, now, it all works fine, i.e. no shadows gets "above" a QGraphicsPixmapItem object.

    Just in case, here is the code that I have come up with to get a shadow for a QGraphicsPixmapItem object:

    QPixmap Item::shadow(const QPixmap &pPixmap)
    {
        static const int Depth = sizeof(QRgb);
    
        QPixmap res;
        QString cacheKey = QString::number(pPixmap.cacheKey());
    
        if (!QPixmapCache::find(cacheKey, &res)) {
            QImage shadow = pPixmap.toImage();
    
            for (int j = 0, jMax = shadow.height(); j < jMax; ++j) {
                uchar *pixels = shadow.scanLine(j);
    
                for (int i = 0, iMax = shadow.width(); i < iMax; ++i) {
                    QRgb *rgb = reinterpret_cast<QRgb *>(pixels+i*Depth);
    
                    if (*rgb)
                        *rgb = QColor(0, 0, 0, 96).rgba();
                }
            }
    
            res = QPixmap::fromImage(shadow);
    
            QPixmapCache::insert(cacheKey, res);
        }
    
        return res;
    }
    

Log in to reply