Qt: ombre autour de la fenêtre

Je peux append une ombre au widget:

QGraphicsDropShadowEffect *bodyShadow = new QGraphicsDropShadowEffect; bodyShadow->setBlurRadius(9.0); bodyShadow->setColor(QColor(0, 0, 0, 160)); bodyShadow->setOffset(4.0); ui->widget->setGraphicsEffect(bodyShadow); 

Mais cette ombre sera seulement à gauche et en bas. J’ai besoin d’ombre autour du widget. Comment append ceci?

Vous pouvez créer votre effet personnalisé. Je vais partager une implémentation qui fonctionne.

customshadoweffect.h

 #ifndef CUSTOMSHADOWEFFECT_H #define CUSTOMSHADOWEFFECT_H #include  #include  class CustomShadowEffect : public QGraphicsEffect { Q_OBJECT public: explicit CustomShadowEffect(QObject *parent = 0); void draw(QPainter* painter); QRectF boundingRectFor(const QRectF& rect) const; inline void setDistance(qreal distance) { _distance = distance; updateBoundingRect(); } inline qreal distance() const { return _distance; } inline void setBlurRadius(qreal blurRadius) { _blurRadius = blurRadius; updateBoundingRect(); } inline qreal blurRadius() const { return _blurRadius; } inline void setColor(const QColor& color) { _color = color; } inline QColor color() const { return _color; } private: qreal _distance; qreal _blurRadius; QColor _color; }; #endif // CUSTOMSHADOWEFFECT_H 

customshadoweffect.cpp

 #include "customshadoweffect.h" #include  // #include  CustomShadowEffect::CustomShadowEffect(QObject *parent) : QGraphicsEffect(parent), _distance(4.0f), _blurRadius(10.0f), _color(0, 0, 0, 80) { } QT_BEGIN_NAMESPACE extern Q_WIDGETS_EXPORT void qt_blurImage(QPainter *p, QImage &blurImage, qreal radius, bool quality, bool alphaOnly, int transposed = 0 ); QT_END_NAMESPACE void CustomShadowEffect::draw(QPainter* painter) { // if nothing to show outside the item, just draw source if ((blurRadius() + distance()) <= 0) { drawSource(painter); return; } PixmapPadMode mode = QGraphicsEffect::PadToEffectiveBoundingRect; QPoint offset; const QPixmap px = sourcePixmap(Qt::DeviceCoordinates, &offset, mode); // return if no source if (px.isNull()) return; // save world transform QTransform restoreTransform = painter->worldTransform(); painter->setWorldTransform(QTransform()); // Calculate size for the background image QSize szi(px.size().width() + 2 * distance(), px.size().height() + 2 * distance()); QImage tmp(szi, QImage::Format_ARGB32_Premultiplied); QPixmap scaled = px.scaled(szi); tmp.fill(0); QPainter tmpPainter(&tmp); tmpPainter.setCompositionMode(QPainter::CompositionMode_Source); tmpPainter.drawPixmap(QPointF(-distance(), -distance()), scaled); tmpPainter.end(); // blur the alpha channel QImage blurred(tmp.size(), QImage::Format_ARGB32_Premultiplied); blurred.fill(0); QPainter blurPainter(&blurred); qt_blurImage(&blurPainter, tmp, blurRadius(), false, true); blurPainter.end(); tmp = blurred; // blacken the image... tmpPainter.begin(&tmp); tmpPainter.setCompositionMode(QPainter::CompositionMode_SourceIn); tmpPainter.fillRect(tmp.rect(), color()); tmpPainter.end(); // draw the blurred shadow... painter->drawImage(offset, tmp); // draw the actual pixmap... painter->drawPixmap(offset, px, QRectF()); // restore world transform painter->setWorldTransform(restoreTransform); } QRectF CustomShadowEffect::boundingRectFor(const QRectF& rect) const { qreal delta = blurRadius() + distance(); return rect.united(rect.adjusted(-delta, -delta, delta, delta)); } 

Application (à un élément graphique):

 // ... CustomShadowEffect *bodyShadow = new CustomShadowEffect(); bodyShadow->setBlurRadius(20.0); bodyShadow->setDistance(6.0); bodyShadow->setColor(QColor(0, 0, 0, 80)); item->setGraphicsEffect(bodyShadow); // ... 

Application (à un widget enfant):

 //... CustomShadowEffect *bodyShadow = new CustomShadowEffect(); bodyShadow->setBlurRadius(20.0); bodyShadow->setDistance(6.0); bodyShadow->setColor(QColor(0, 0, 0, 80)); ui->widget->setAutoFillBackground(true); ui->widget->setGraphicsEffect(bodyShadow); // ... 

Résultat: Effet appliqué à un widget enfant dans une fenêtre QMainWindow

J’aime l’exemple de mhcuervo sur la mise en œuvre d’un effet personnalisé. Cela dit, je pouvais obtenir une ombre autour du widget enfant en utilisant votre code, un décalage de 0 et un rayon de flou suffisant pour le diffuser autour du widget enfant. (ceci, en utilisant Qt 5.4).