Draw shadow around a top-level Framless QWidget with QLinearGradient ?
-
Hi.
I have created a top-levelQWidget
(Qt::FramelessWindowHint
) with resizing function.Now i want a shadow effect (Windows specific feature) around my widget without
QGraphicsDropShadowEffect
and affecting on child widget, instead viaQLinearGradient
on paintintg.I've tried this :
Shadow
but it is not what i want :
Native-ShadowPainting :
void Widget::paintEvent(QPaintEvent *) { QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); painter.setPen(Qt::NoPen); QLinearGradient gradient; QColor grey1(150, 150, 150, 125); QColor grey2(225, 225, 225, 125); gradient.setColorAt(0.0, grey1); gradient.setColorAt(1.0, grey2); painter.setBrush(QBrush(gradient)); QPointF topLeft(0, 0); QPointF bottomRight(width(), height()); QRectF rect(topLeft, bottomRight); painter.drawRoundRect(rect, 0.0, 0.0); QBrush brush2(QColor("#FFFFFF"), Qt::SolidPattern); painter.setBrush(brush2); QPointF topLeft2(5, 5); QPointF bottomRight2(width() - 5, height() - 5); QRectF rect2(topLeft2, bottomRight2); painter.drawRoundRect(rect2, 0.0, 0.0); }
What did i miss in code ?
-
Hi
Im slightly confused.
You cannot draw outside your widget so im not sure
how u be able to draw dropshadow as it sort of interacts with other windows outside
of the Widgets clientarea.Did I miss something?
-
Hi. @mrjj
No. It's not outside the widget. it's a little hack on widget.
If you look at thepaintEvent
first i drew the linergradient and then i drew the actual widget from(5,5)
to(width() -5, height() -5)
:QBrush brush2(QColor("#FFFFFF"), Qt::SolidPattern); painter.setBrush(brush2); QPointF topLeft2(5, 5); QPointF bottomRight2(width() - 5, height() - 5); QRectF rect2(topLeft2, bottomRight2); painter.drawRoundRect(rect2, 0.0, 0.0);
Now the problem is the linergradiant shadow is not desired.
-
Ok.
I made one :QPainter painter(this); painter.setPen(Qt::NoPen); int margin = 10; QColor start(151, 151, 151, 32); QColor end(255, 255, 255, 0); QPointF right0(width() - margin, height() / 2); QPointF right1(width(), height() / 2); QPointF left0(margin, height() / 2); QPointF left1(0, height() / 2); QPointF top0(width() / 2, margin); QPointF top1(width() / 2, 0); QPointF bottom0(width() / 2, height() - margin); QPointF bottom1(width() / 2, height()); QPointF bottomright0(width() - margin, height() - margin); QPointF bottomright1(width(), height()); QPointF bottomleft0(margin, height() - margin); QPointF bottomleft1(0, height()); QPointF topLeft0(margin, margin); QPointF topleft1(0, 0); QPointF topright0(width() - margin, margin); QPointF topright1(width(), 0); QLinearGradient gradient; gradient.setColorAt(0.0, start); gradient.setColorAt(1.0, end); // right gradient.setStart(right0); gradient.setFinalStop(right1); painter.setBrush(QBrush(gradient)); painter.drawRoundRect(QRectF(QPointF(margin, margin), QPointF(width(), height()-margin)), 0.0, 0.0); // left gradient.setStart(left0); gradient.setFinalStop(left1); painter.setBrush(QBrush(gradient)); painter.drawRoundRect(QRectF(QPointF(width() - margin, margin), QPointF(0, height()-margin)), 0.0, 0.0); // top gradient.setStart(top0); gradient.setFinalStop(top1); painter.setBrush(QBrush(gradient)); painter.drawRoundRect(QRectF(QPointF(width() - margin, 0), QPointF(margin, height()-margin)), 0.0, 0.0); // bottom gradient.setStart(bottom0); gradient.setFinalStop(bottom1); painter.setBrush(QBrush(gradient)); painter.drawRoundRect(QRectF(QPointF(margin, margin), QPointF(width() - margin, height() )), 0.0, 0.0); // bottom right gradient.setStart(bottomright0); gradient.setFinalStop(bottomright1); gradient.setColorAt(0.6, end); painter.setBrush(QBrush(gradient)); painter.drawRoundRect(QRectF(bottomright0, bottomright1), 0.0, 0.0); // bottom left gradient.setStart(bottomleft0); gradient.setFinalStop(bottomleft1); gradient.setColorAt(0.6, end); painter.setBrush(QBrush(gradient)); painter.drawRoundRect(QRectF(bottomleft0, bottomleft1), 0.0, 0.0); // top left gradient.setStart(topLeft0); gradient.setFinalStop(topleft1); painter.setBrush(QBrush(gradient)); gradient.setColorAt(0.6, end); painter.drawRoundRect(QRectF(topLeft0, topleft1), 0.0, 0.0); // top right gradient.setStart(topright0); gradient.setFinalStop(topright1); painter.setBrush(QBrush(gradient)); gradient.setColorAt(0.6, end); painter.drawRoundRect(QRectF(topright0, topright1), 0.0, 0.0); // actual widget painter.setBrush(QBrush("#FFFFFF")); painter.drawRoundRect(QRectF(QPointF(margin, margin), QPointF(width() - margin, height() - margin)), 0.0, 0.0);
But it doesn't seems realistic !
Could you guys tell me how could it be better ?
Thanks a lot. -
I think that one looks nice.
-
Ok.
It might get better in the future !If you wan to get ride of
QGraphicsDropShadowEffect
:void drawShadow(QPainter &_painter, qint16 _margin, qreal _radius, QColor _start, QColor _end, qreal _startPosition, qreal _endPosition0, qreal _endPosition1, qreal _width, qreal _height) { _painter.setPen(Qt::NoPen); QLinearGradient gradient; gradient.setColorAt(_startPosition, _start); gradient.setColorAt(_endPosition0, _end); // Right QPointF right0(_width - _margin, _height / 2); QPointF right1(_width, _height / 2); gradient.setStart(right0); gradient.setFinalStop(right1); _painter.setBrush(QBrush(gradient)); _painter.drawRoundRect(QRectF(QPointF(_width - _margin*_radius, _margin), QPointF(_width, _height - _margin)), 0.0, 0.0); // Left QPointF left0(_margin, _height / 2); QPointF left1(0, _height / 2); gradient.setStart(left0); gradient.setFinalStop(left1); _painter.setBrush(QBrush(gradient)); _painter.drawRoundRect(QRectF(QPointF(_margin *_radius, _margin), QPointF(0, _height - _margin)), 0.0, 0.0); // Top QPointF top0(_width / 2, _margin); QPointF top1(_width / 2, 0); gradient.setStart(top0); gradient.setFinalStop(top1); _painter.setBrush(QBrush(gradient)); _painter.drawRoundRect(QRectF(QPointF(_width - _margin, 0), QPointF(_margin, _margin)), 0.0, 0.0); // Bottom QPointF bottom0(_width / 2, _height - _margin); QPointF bottom1(_width / 2, _height); gradient.setStart(bottom0); gradient.setFinalStop(bottom1); _painter.setBrush(QBrush(gradient)); _painter.drawRoundRect(QRectF(QPointF(_margin, _height - _margin), QPointF(_width - _margin, _height)), 0.0, 0.0); // BottomRight QPointF bottomright0(_width - _margin, _height - _margin); QPointF bottomright1(_width, _height); gradient.setStart(bottomright0); gradient.setFinalStop(bottomright1); gradient.setColorAt(_endPosition1, _end); _painter.setBrush(QBrush(gradient)); _painter.drawRoundRect(QRectF(bottomright0, bottomright1), 0.0, 0.0); // BottomLeft QPointF bottomleft0(_margin, _height - _margin); QPointF bottomleft1(0, _height); gradient.setStart(bottomleft0); gradient.setFinalStop(bottomleft1); gradient.setColorAt(_endPosition1, _end); _painter.setBrush(QBrush(gradient)); _painter.drawRoundRect(QRectF(bottomleft0, bottomleft1), 0.0, 0.0); // TopLeft QPointF topleft0(_margin, _margin); QPointF topleft1(0, 0); gradient.setStart(topleft0); gradient.setFinalStop(topleft1); gradient.setColorAt(_endPosition1, _end); _painter.setBrush(QBrush(gradient)); _painter.drawRoundRect(QRectF(topleft0, topleft1), 0.0, 0.0); // TopRight QPointF topright0(_width - _margin, _margin); QPointF topright1(_width, 0); gradient.setStart(topright0); gradient.setFinalStop(topright1); gradient.setColorAt(_endPosition1, _end); _painter.setBrush(QBrush(gradient)); _painter.drawRoundRect(QRectF(topright0, topright1), 0.0, 0.0); // Widget _painter.setBrush(QBrush("#FFFFFF")); _painter.setRenderHint(QPainter::Antialiasing); _painter.drawRoundRect(QRectF(QPointF(_margin, _margin), QPointF(_width - _margin, _height - _margin)), _radius, _radius); }
drawShadow(painter, 10, 2.0, QColor(120, 120, 120, 32), QColor(255, 255, 255, 0), 0.0, 1.0, 0.6, width(), height());
don't forgetsetAttribute(Qt::WA_TranslucentBackground);
Final Resualt : https://onedrive.live.com/?cid=8882d1e3bc0f61ab&id=8882D1E3BC0F61AB!7415&authkey=!AH66ZieCJDqvXhk