I have gone through this page.
For enhancing my custom shadow around my widget/window.But the Problem is i cant use in PyQt5
QT_BEGIN_NAMESPAC Eextern Q_WIDGETS_EXPORT void qt_blurImage(QPainter p, QImage &blurImage, qreal radius, bool quality, bool alphaOnly, int transposed = 0 ); QT_END_NAMESPACE
and the Function qt_blurImage(&blurPainter, tmp, blurRadius(), false, true); described in that page in customshadoweffect.cpp
Can anyone Suggest how to implement that??
Here is my code. -EDIT-
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5 import sip
import ctypes
#This functions is not exposed for PyQt, but can be accessed through ctypes
_qt_blurImage = getattr(ctypes.CDLL(r"E:\Python\Lib\site-packages\PyQt5\Qt5\bin\Qt5Widgets.dll"),
'?qt_blurImage@@YAXPAVQPainter@@AAVQImage@@N_N2H@Z')
class CustomShadowEffect(QGraphicsEffect):
def __init__(self,parent):
super().__init__(parent)
self._distance=4.0
self._blurRadius=10.0
self._color=QColor (0, 0, 0, 80)
def setBlurRadius(self, blurRadius) :
self._blurRadius = blurRadius
self.updateBoundingRect()
def blurRadius(self) :
return self._blurRadius
def setColor(self, color):
self._color = color
def color(self) :
return self._color
def setDistance(self,distance) :
self._distance = distance
self. updateBoundingRect()
def distance(self) :
return self._distance
def boundingRectFor( self,rect) :
delta = self.blurRadius() + self.distance()
return rect.united(rect.adjusted(-delta, -delta, delta, delta))
def draw(self, painter):
# if nothing to show outside the item, just draw source
if ((self.blurRadius() + self.distance()) <= 0) :
self.drawSource(painter);
return;
mode = QGraphicsEffect.PadToEffectiveBoundingRect #return PixmapPadMode
# offset=QPoint()
px,offset = self.sourcePixmap(Qt.DeviceCoordinates, mode)
# return if no source
if (px.isNull()):
return
#save world transform
restoreTransform = painter.worldTransform() #return QTransform
painter.setWorldTransform(QTransform())
#Calculate size for the background image
szi=QSize (int(px.size().width() + 2 * self.distance()), int(px.size().height() + 2 * self.distance()))
tmp=QImage(szi, QImage.Format_ARGB32_Premultiplied)
scaled = px.scaled(szi) #return QPixmap
tmp.fill(0)
tmpPainter=QPainter(tmp)
tmpPainter.setCompositionMode(QPainter.CompositionMode_Source)
tmpPainter.drawPixmap(QPointF(-self.distance(), -self.distance()), scaled)
tmpPainter.end()
#blur the alpha channel
blurred=QImage(tmp.size(), QImage.Format_ARGB32_Premultiplied)
blurred.fill(0)
blurPainter=QPainter(blurred)
self.applyBlurEffect(blurPainter, tmp, self.blurRadius(), False, True)
blurPainter.end()
tmp = blurred
#blacken the image...
tmpPainter.begin(tmp)
tmpPainter.setCompositionMode(QPainter.CompositionMode_SourceIn)
tmpPainter.fillRect(tmp.rect(), self.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)
def applyBlurEffect(self, painter,blurImage, radius, quality, alphaOnly, transposed=0 ):
blurImage = ctypes.c_void_p(sip.unwrapinstance(blurImage))
radius = ctypes.c_double(radius)
quality = ctypes.c_bool(quality)
alphaOnly = ctypes.c_bool(alphaOnly)
transposed = ctypes.c_int(transposed)
if painter:
painter = ctypes.c_void_p(sip.unwrapinstance(painter))
_qt_blurImage(painter, blurImage, radius, quality, alphaOnly, transposed)
if __name__=="__main__":
app=QApplication([])
win=QWidget()
win.resize(400,400)
l=QLabel(win)
l.setGeometry(100,100,200,200)
l.setStyleSheet("background:green;border-radius:15px;color:white;font: 18pt Calibri;")
l.setAlignment(Qt.AlignCenter)
bodyShadow = CustomShadowEffect(l)
bodyShadow.setBlurRadius(20.0)
bodyShadow.setDistance(10.0)
bodyShadow.setColor(QColor(0, 0, 0, 200))
l.setAutoFillBackground(True)
l.setGraphicsEffect(bodyShadow)
l.setText("hello")
win.show()
app.exec_()
Note If you want to use shadow for whole window then Use QWidget instead
if __name__=="__main__":
app=QApplication([])
win=QMainWindow()
win.resize(400,400)
l=QWidget(win)
l.setGeometry(10,10,380,380)
win.setAttribute(Qt.WA_TranslucentBackground)
win.setWindowFlag(Qt.FramelessWindowHint)
l.setStyleSheet("background:green;border-radius:15px;")
bodyShadow = CustomShadowEffect(l)
bodyShadow.setBlurRadius(5.0)
bodyShadow.setDistance(5.0)
bodyShadow.setColor(QColor(23, 144, 255, 255))
l.setGraphicsEffect(bodyShadow)
win.show()
app.exec_()