├── Glassmorphism └── Glassmorphism.py ├── LICENSE ├── README.md ├── example.py ├── gitignore └── resources ├── bg.jpeg └── icons ├── chat.svg ├── images.svg ├── music.svg ├── phone.svg └── wifi.svg /Glassmorphism/Glassmorphism.py: -------------------------------------------------------------------------------- 1 | #MIT License 2 | # 3 | #Copyright (c) 2022 GvozdevLeonid 4 | # 5 | #Permission is hereby granted, free of charge, to any person obtaining a copy 6 | #of this software and associated documentation files (the "Software"), to deal 7 | #in the Software without restriction, including without limitation the rights 8 | #to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | #copies of the Software, and to permit persons to whom the Software is 10 | #furnished to do so, subject to the following conditions: 11 | # 12 | #The above copyright notice and this permission notice shall be included in all 13 | #copies or substantial portions of the Software. 14 | # 15 | #THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | #IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | #FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | #AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | #LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | #OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | #SOFTWARE. 22 | 23 | 24 | try: 25 | from PySide6 import ( 26 | QtWidgets, 27 | QtCore, 28 | QtGui 29 | ) 30 | except ImportError: 31 | try: 32 | from PySide2 import ( 33 | QtWidgets, 34 | QtCore, 35 | QtGui 36 | ) 37 | except ImportError: 38 | try: 39 | from PyQt6 import ( 40 | QtWidgets, 41 | QtCore, 42 | QtGui 43 | ) 44 | except ImportError: 45 | try: 46 | from PyQt5 import ( 47 | QtWidgets, 48 | QtCore, 49 | QtGui 50 | ) 51 | except ImportError: 52 | pass 53 | import math 54 | 55 | 56 | class BackDrop(QtWidgets.QGraphicsEffect): 57 | def __init__(self, blur: int = 0, radius: int = 0, 58 | backgrounds: list[dict] = None): 59 | QtWidgets.QGraphicsEffect.__init__(self) 60 | self._blur = blur 61 | self._radius = radius 62 | self._backgrounds = backgrounds 63 | 64 | self._size = QtCore.QSize(0, 0) 65 | 66 | self._animation_pixmap = None 67 | self._forward_animation = False 68 | self._animation_position = QtCore.QPointF(0, 0) 69 | self._animation = QtCore.QPropertyAnimation(self, 70 | b"animation_position") 71 | 72 | self._check_backgrounds() 73 | try: 74 | @QtCore.Property(QtCore.QPointF) 75 | def animation_position(self): 76 | return self._animation_position 77 | except AttributeError: 78 | @QtCore.pyqtProperty(QtCore.QPointF) 79 | def animation_position(self): 80 | return self._animation_position 81 | 82 | @animation_position.setter 83 | def animation_position(self, value: QtCore.QPointF): 84 | self._animation_position = value 85 | self.update() 86 | 87 | @staticmethod 88 | def _blur_pixmap(src, blur_radius): 89 | w, h = src.width(), src.height() 90 | 91 | effect = QtWidgets.QGraphicsBlurEffect(blurRadius=blur_radius) 92 | 93 | scene = QtWidgets.QGraphicsScene() 94 | item = QtWidgets.QGraphicsPixmapItem() 95 | item.setPixmap(QtGui.QPixmap(src)) 96 | item.setGraphicsEffect(effect) 97 | scene.addItem(item) 98 | 99 | res = QtGui.QImage(QtCore.QSize(w, h), 100 | QtGui.QImage.Format.Format_ARGB32) 101 | res.fill(QtCore.Qt.GlobalColor.transparent) 102 | 103 | ptr = QtGui.QPainter(res) 104 | ptr.setRenderHints(QtGui.QPainter.RenderHint.Antialiasing | 105 | QtGui.QPainter.RenderHint.SmoothPixmapTransform) 106 | scene.render(ptr, QtCore.QRectF(), QtCore.QRectF(0, 0, w, h)) 107 | ptr.end() 108 | 109 | return QtGui.QPixmap(res) 110 | 111 | @staticmethod 112 | def _cut_pixmap(pixmap, mask, width, height): 113 | painter = QtGui.QPainter(pixmap) 114 | painter.setTransform(QtGui.QTransform()) 115 | painter.setRenderHints(QtGui.QPainter.RenderHint.Antialiasing | 116 | QtGui.QPainter.RenderHint.SmoothPixmapTransform) 117 | painter.setCompositionMode( 118 | QtGui.QPainter.CompositionMode.CompositionMode_DestinationIn) 119 | painter.drawPixmap(0, 0, width, height, mask) 120 | painter.end() 121 | 122 | @staticmethod 123 | def _get_colored_pixmap(brush_color, pen_color, 124 | pen_width, width, height, radius): 125 | pixmap = QtGui.QPixmap(width, height) 126 | pixmap.fill(QtCore.Qt.GlobalColor.transparent) 127 | painter = QtGui.QPainter(pixmap) 128 | painter.setRenderHints(QtGui.QPainter.RenderHint.Antialiasing | 129 | QtGui.QPainter.RenderHint.SmoothPixmapTransform) 130 | painter.setBrush(brush_color) 131 | painter.setPen(QtGui.QPen(pen_color, pen_width)) 132 | painter.drawRoundedRect(QtCore.QRectF(0.0, 0.0, width, height), 133 | radius, radius) 134 | painter.end() 135 | 136 | return pixmap 137 | 138 | def _get_blur_background(self, source): 139 | source_rect = self.boundingRectFor( 140 | self.sourceBoundingRect( 141 | QtCore.Qt.CoordinateSystem.DeviceCoordinates)).toRect() 142 | x, y, w, h = source_rect.getRect() 143 | scale = int(source.devicePixelRatioF()) 144 | 145 | background_expanded = source.copy(x * scale - self._blur, 146 | y * scale - self._blur, 147 | w * scale + self._blur * 2, 148 | h * scale + self._blur * 2) 149 | 150 | blurred_background_expanded = self._blur_pixmap(background_expanded, 151 | self._blur) 152 | 153 | blurred_background = blurred_background_expanded.copy(self._blur // 2, 154 | self._blur // 2, 155 | w, h) 156 | 157 | return blurred_background 158 | 159 | def _check_backgrounds(self): 160 | for bg in self._backgrounds: 161 | if "background-color" not in bg.keys(): 162 | bg["background-color"] = QtGui.QColor(255, 255, 255, 0) 163 | if "border" not in bg.keys(): 164 | bg["border"] = QtGui.QColor(255, 255, 255, 0) 165 | if "border-width" not in bg.keys(): 166 | bg["border-width"] = 1 167 | if "opacity" not in bg.keys(): 168 | bg["opacity"] = 0 169 | 170 | def _create_animation_pixmap(self, angle: int, line_width: int, 171 | color: QtGui.QColor): 172 | 173 | height = self._size.height() 174 | diagonal = height / math.sin(math.radians(angle)) 175 | width = int(math.sqrt(diagonal ** 2 - height ** 2)) 176 | offset = int(math.sqrt(line_width ** 2 + line_width ** 2)) 177 | 178 | if angle in (0, 180): 179 | width = self._size.height() 180 | start_pos = QtCore.QPointF(0, height) 181 | end_pos = QtCore.QPointF(width * 2 + offset * 2, height) 182 | elif angle == 90: 183 | width = line_width 184 | start_pos = QtCore.QPointF(width + offset, 0) 185 | end_pos = QtCore.QPointF(width + offset, height * 2) 186 | else: 187 | if angle < 90: 188 | start_pos = QtCore.QPointF(offset, height * 2) 189 | end_pos = QtCore.QPointF(width * 2 + offset, 0) 190 | else: 191 | start_pos = QtCore.QPointF(offset, 0) 192 | end_pos = QtCore.QPointF(width * 2 + offset, height * 2) 193 | 194 | self._animation_pixmap = QtGui.QPixmap(width * 2 + offset * 2, 195 | height * 2) 196 | self._animation_pixmap.fill(QtCore.Qt.GlobalColor.transparent) 197 | 198 | painter = QtGui.QPainter(self._animation_pixmap) 199 | painter.setRenderHints(QtGui.QPainter.RenderHint.Antialiasing | 200 | QtGui.QPainter.RenderHint.SmoothPixmapTransform) 201 | painter.setPen(QtGui.QPen(color, line_width * 2)) 202 | painter.drawLine(start_pos, end_pos) 203 | painter.end() 204 | 205 | def draw(self, painter): 206 | 207 | painter.setRenderHints(QtGui.QPainter.RenderHint.Antialiasing | 208 | QtGui.QPainter.RenderHint.SmoothPixmapTransform) 209 | restoreTransform = painter.worldTransform() 210 | 211 | source_rect = self.boundingRectFor(self.sourceBoundingRect( 212 | QtCore.Qt.CoordinateSystem.DeviceCoordinates)).toRect() 213 | x, y, w, h = source_rect.getRect() 214 | 215 | source = self.sourcePixmap(QtCore.Qt.CoordinateSystem.DeviceCoordinates) 216 | if isinstance(source, tuple): 217 | source = source[0] 218 | scale = int(source.devicePixelRatioF()) 219 | 220 | if self._size.width() != w or self._size.height() != h: 221 | self._size = QtCore.QSize(w, h) 222 | 223 | main_background = self._get_blur_background(painter.device()) 224 | 225 | painter.setTransform(QtGui.QTransform()) 226 | painter.setPen(QtCore.Qt.PenStyle.NoPen) 227 | 228 | mask = self._get_colored_pixmap(QtGui.QColor("#FFFFFF"), 229 | QtGui.QColor("#FFFFFF"), 230 | 1, w * scale, h * scale, 231 | self._radius * scale) 232 | 233 | self._cut_pixmap(main_background, mask, w, h) 234 | 235 | backgrounds = [] 236 | for i, bg in enumerate(self._backgrounds): 237 | background = bg["opacity"], self._get_colored_pixmap( 238 | bg["background-color"], 239 | bg["border"], 240 | bg["border-width"] * scale, 241 | w * scale, h * scale 242 | , self._radius * scale) 243 | self._cut_pixmap(background[1], mask, w * 2, h * 2) 244 | backgrounds.append(background) 245 | 246 | self._cut_pixmap(source, mask, w, h) 247 | 248 | painter.drawPixmap(x, y, w, h, main_background) 249 | 250 | for bg in backgrounds: 251 | painter.setOpacity(bg[0]) 252 | painter.drawPixmap(x, y, w, h, bg[1]) 253 | 254 | painter.setOpacity(1) 255 | painter.drawPixmap(x, y, source) 256 | 257 | if self._animation.state() == QtCore.QPropertyAnimation.State.Running: 258 | pixmap = QtGui.QPixmap(w, h) 259 | pixmap.fill(QtCore.Qt.GlobalColor.transparent) 260 | pixmap_painter = QtGui.QPainter(pixmap) 261 | pixmap_painter.setRenderHints( 262 | QtGui.QPainter.RenderHint.Antialiasing | 263 | QtGui.QPainter.RenderHint.SmoothPixmapTransform) 264 | pixmap_painter.drawPixmap(int(self._animation_position.x()), 265 | int(self._animation_position.y()), 266 | self._animation_pixmap.width() // 2, 267 | self._animation_pixmap.height() // 2, 268 | self._animation_pixmap) 269 | pixmap_painter.end() 270 | self._cut_pixmap(pixmap, mask, w, h) 271 | painter.drawPixmap(x, y, w, h, pixmap) 272 | 273 | painter.setWorldTransform(restoreTransform) 274 | painter.end() 275 | 276 | def shine_animation(self, duration: int = 300, forward: bool = True, 277 | angle: int = 135, width: int = 40, 278 | color: QtGui.QColor = QtGui.QColor(255, 255, 255, 125)): 279 | if self._animation.state() != QtCore.QPropertyAnimation.State.Running: 280 | self._create_animation_pixmap(angle, width, color) 281 | if forward: 282 | start_point = QtCore.QPointF( 283 | -self._animation_pixmap.width() / 2, 0) 284 | end_point = QtCore.QPointF(self._size.width(), 0) 285 | else: 286 | start_point = QtCore.QPointF(self._size.width(), 0) 287 | end_point = QtCore.QPointF( 288 | -self._animation_pixmap.width() / 2, 0) 289 | 290 | if forward: 291 | self._forward_animation = True 292 | else: 293 | self._forward_animation = False 294 | 295 | self._animation.setStartValue(start_point) 296 | self._animation.setEndValue(end_point) 297 | self._animation.setDuration(duration) 298 | self._animation.start() 299 | 300 | elif self._animation.state() == \ 301 | QtCore.QPropertyAnimation.State.Running and \ 302 | not self._forward_animation: 303 | self._forward_animation = False 304 | 305 | self._animation.stop() 306 | end_point = QtCore.QPointF(self._size.width(), 0) 307 | self._animation.setStartValue(self._animation_position) 308 | self._animation.setEndValue(end_point) 309 | self._animation.setDuration( 310 | duration - self._animation.currentTime()) 311 | self._animation.start() 312 | 313 | elif self._animation.state() == \ 314 | QtCore.QPropertyAnimation.State.Running and\ 315 | self._forward_animation: 316 | self._forward_animation = False 317 | 318 | self._animation.stop() 319 | end_point = QtCore.QPointF(-self._animation_pixmap.width() / 2, 0) 320 | self._animation.setStartValue(self._animation_position) 321 | self._animation.setEndValue(end_point) 322 | self._animation.setDuration( 323 | duration - self._animation.currentTime()) 324 | self._animation.start() 325 | 326 | 327 | class BackDropWrapper(QtWidgets.QWidget): 328 | def __init__(self, widget, blur: int = 0, radius: int = 0, 329 | backgrounds: list[dict] = None, shine_animation: list = None, 330 | move_animation: tuple = None): 331 | QtWidgets.QWidget.__init__(self) 332 | self._widget = widget 333 | 334 | self.mLayout = QtWidgets.QVBoxLayout() 335 | self.mLayout.setContentsMargins(0, 0, 0, 0) 336 | 337 | self.setLayout(self.mLayout) 338 | self.mLayout.addWidget(self._widget) 339 | 340 | self.boxShadow = BackDrop(blur, radius, backgrounds) 341 | self.setGraphicsEffect(self.boxShadow) 342 | 343 | self.setAttribute(QtCore.Qt.WidgetAttribute.WA_Hover) 344 | self.setAttribute(QtCore.Qt.WidgetAttribute.WA_NoMousePropagation) 345 | 346 | self._animation = QtCore.QPropertyAnimation(self, b"pos") 347 | self._normal_pos = None 348 | self._forward_animation = False 349 | 350 | self._shine_animation_info = None 351 | self._move_animation_info = None 352 | 353 | if shine_animation is not None: 354 | self.enable_shine_animation(shine_animation=shine_animation) 355 | if move_animation is not None: 356 | self.enable_move_animation(move_animation=move_animation) 357 | 358 | def enable_shine_animation(self, duration: int = 300, forward: bool = True, 359 | angle: int = 135, width: int = 40, 360 | color: QtGui.QColor = QtGui.QColor(255, 255, 361 | 255, 125), 362 | shine_animation: tuple = None): 363 | if shine_animation is None: 364 | self._shine_animation_info = (duration, forward, 365 | angle, width, color) 366 | else: 367 | self._shine_animation_info = shine_animation 368 | 369 | def enable_move_animation(self, duration: int = 300, 370 | offset: tuple = (0, 0), 371 | forward: bool = True, 372 | move_animation: tuple = None): 373 | if move_animation is None: 374 | self._move_animation_info = (duration, offset, forward) 375 | else: 376 | self._move_animation_info = move_animation 377 | 378 | def event(self, event: QtCore.QEvent) -> bool: 379 | if event.type() == QtGui.QHideEvent.Type.HoverEnter: 380 | if self._shine_animation_info is not None: 381 | duration, forward, angle, width, color = \ 382 | self._shine_animation_info 383 | self.boxShadow.shine_animation(duration, forward, 384 | angle, width, color) 385 | 386 | if self._move_animation_info is not None: 387 | duration, offset, forward = self._move_animation_info 388 | self._move_animation(duration, offset, forward) 389 | return True 390 | if event.type() == QtGui.QHideEvent.Type.HoverLeave: 391 | if self._shine_animation_info is not None: 392 | duration, forward, angle, width, color = \ 393 | self._shine_animation_info 394 | self.boxShadow.shine_animation(duration, not forward, 395 | angle, width, color) 396 | 397 | if self._move_animation_info is not None: 398 | duration, offset, forward = self._move_animation_info 399 | self._move_animation(duration, offset, not forward) 400 | return True 401 | return False 402 | 403 | def _move_animation(self, duration: int = 300, offset: tuple = (0, 0), 404 | forward: bool = True): 405 | if self._normal_pos is None: 406 | self._normal_pos = self.property("pos") 407 | 408 | if self._animation.state() != QtCore.QPropertyAnimation.State.Running: 409 | if forward: 410 | self._normal_pos = self.property("pos") 411 | self._forward_animation = True 412 | end_pos = QtCore.QPointF(self.property("pos").x() + offset[0], 413 | self.property("pos").y() + offset[1]) 414 | else: 415 | self._forward_animation = False 416 | end_pos = self._normal_pos 417 | 418 | self._animation.setStartValue(self.property("pos")) 419 | self._animation.setEndValue(end_pos) 420 | self._animation.setDuration(duration) 421 | self._animation.start() 422 | 423 | elif self._animation.state() == \ 424 | QtCore.QPropertyAnimation.State.Running and \ 425 | not self._forward_animation: 426 | 427 | self._forward_animation = True 428 | end_pos = QtCore.QPointF(self._normal_pos.x() + offset[0], 429 | self._normal_pos.y() + offset[1]) 430 | 431 | self._animation.stop() 432 | self._animation.setStartValue(self._animation.currentValue()) 433 | self._animation.setEndValue(end_pos) 434 | self._animation.setDuration( 435 | duration - self._animation.currentTime()) 436 | self._animation.start() 437 | 438 | elif self._animation.state() == \ 439 | QtCore.QPropertyAnimation.State.Running \ 440 | and self._forward_animation: 441 | self._forward_animation = False 442 | 443 | self._animation.stop() 444 | self._animation.setStartValue(self._animation.currentValue()) 445 | self._animation.setEndValue(self._normal_pos) 446 | self._animation.setDuration( 447 | duration - self._animation.currentTime()) 448 | self._animation.start() 449 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 GvozdevLeonid 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BackDrop effect in PySide6 2 | 3 | So far this is working on Pyside6 and possibly PySide2 as well. Does not work on PyQt6, I will fix the error in the future 4 | 5 | This repository contains two classes: BackDrop is a graphical effect in which you need to set a list of backgrounds, blur and a border radius. BackDropWrapper - a handy wrapper for displaying and animation the backdrop effect. 6 | 7 | BackDrop(blur: int = 0, radius: int = 0, backgrounds: list[dict] = None) 8 | BackDropWrapper(widget: QtWidgets.QObject , blur: int = 0, radius: int = 0, backgrounds: list[dict] = None, shine_animation: list = None, move_animation: tuple = None) 9 | The backgrounds is set as follows: 10 | 11 | grad = QtGui.QLinearGradient(0, 0, 1, 1) 12 | grad.setCoordinateMode(QtGui.QLinearGradient.CoordinateMode.ObjectMode) 13 | grad.setStops([(0, QtGui.QColor(255, 255, 255, 255)), (0.35, QtGui.QColor(255, 255, 255, 125)), (0.65, QtGui.QColor(255, 255, 255, 125)), (1,QtGui.QColor(255, 255, 255, 255))]) 14 | backgrounds=[{"background-color": grad, "border": QtGui.QColor("#FFFFFF"),"border-width": 2, "opacity": .4}] 15 | 16 | Animations run when you hover over the widget and also run in reverse again when you leave the mouse. 17 | All animations are disabled by default, but you can enable them by passing the following arguments: 18 | 19 | shine_animation = (duration: int, forward: bool, angle: int, width: int, color: QtGui.QColor) 20 | move_animation = (duration: int, offset: tuple, forward: bool) 21 | 22 | or you can create BackDropWrapper element and set: 23 | 24 | bdw = BackDropWrapper(QtWidgets.QLabel("Hello World!"), blur=10, radius=25, backgrounds=backgrounds) 25 | bdw.enable_shine_animation(color=QtGui.QColor(255, 255, 255, 90)) 26 | bdw.enable_move_animation(offset=(0, -30)) 27 | 28 | # Example file preview 29 | 30 | normal 31 | hovered 32 | 33 | ![animation](https://user-images.githubusercontent.com/87101242/209816714-2ab1e36e-94c6-4a59-a92d-0a73fc1b1939.gif) 34 | -------------------------------------------------------------------------------- /example.py: -------------------------------------------------------------------------------- 1 | from PySide6 import QtCore, QtWidgets, QtGui 2 | from Glassmorphism.Glassmorphism import * 3 | 4 | def coloredIcon(color: QtGui.QColor, icon_path: str, size: QtCore.QSize, scale: int = 2): 5 | icon = QtGui.QPixmap(size.width() * scale, size.height() * scale) 6 | pixmap_icon = QtGui.QPixmap(icon_path) 7 | 8 | icon.fill(color) 9 | painter = QtGui.QPainter(icon) 10 | painter.setRenderHints(QtGui.QPainter.Antialiasing | QtGui.QPainter.SmoothPixmapTransform) 11 | painter.setCompositionMode(QtGui.QPainter.CompositionMode.CompositionMode_DestinationIn) 12 | painter.drawPixmap(0, 0, size.width() * scale, size.height() * scale, pixmap_icon) 13 | painter.end() 14 | 15 | return icon 16 | 17 | class Icons_with_BackDrop(QtWidgets.QWidget): 18 | def __init__(self): 19 | QtWidgets.QWidget.__init__(self) 20 | ml = QtWidgets.QHBoxLayout() 21 | ml.setContentsMargins(100, 200, 100, 100) 22 | ml.setSpacing(10) 23 | 24 | self.bg_label = QtWidgets.QLabel(self) 25 | pixmap = QtGui.QPixmap("resources/bg.jpeg") 26 | self.bg_label.setPixmap(pixmap) 27 | self.bg_label.setScaledContents( True ) 28 | self.bg_label.setSizePolicy(QtWidgets.QSizePolicy.Policy.Ignored, QtWidgets.QSizePolicy.Policy.Ignored) 29 | self.setLayout(ml) 30 | 31 | grad = QtGui.QLinearGradient(0, 0, 1, 1) 32 | grad.setCoordinateMode(QtGui.QLinearGradient.CoordinateMode.ObjectMode) 33 | grad.setStops([(0, QtGui.QColor(255, 255, 255, 255)), (0.35, QtGui.QColor(255, 255, 255, 125)), (0.65, QtGui.QColor(255, 255, 255, 125)), (1, QtGui.QColor(255, 255, 255, 255))]) 34 | 35 | backgrounds=[{"background-color": grad, "border": QtGui.QColor("#FFFFFF"),"border-width": 2, "opacity": .4}] 36 | 37 | icons = ["resources/icons/chat.svg", "resources/icons/images.svg", "resources/icons/music.svg", "resources/icons/phone.svg", "resources/icons/wifi.svg"] 38 | for icon in icons: 39 | size = QtCore.QSize(50, 50) 40 | btn = QtWidgets.QPushButton() 41 | btn.setIcon(coloredIcon(QtGui.QColor(254, 1, 154), icon, size)) 42 | btn.setIconSize(size) 43 | btn.setStyleSheet("border:none; padding: 20px;") 44 | ml.addWidget(btn) 45 | bdw = BackDropWrapper(btn, 10, 20, backgrounds) 46 | bdw.enable_shine_animation(angle=135, color=QtGui.QColor(255, 255, 255, 90)) 47 | bdw.enable_move_animation(offset=(0, -30)) 48 | ml.addWidget(bdw) 49 | 50 | self.show() 51 | 52 | def resizeEvent(self, event: QtGui.QResizeEvent) -> None: 53 | self.bg_label.setFixedSize(event.size()) 54 | 55 | app = QtWidgets.QApplication([]) 56 | app.setStyle("Fusion") 57 | w = Icons_with_BackDrop() 58 | app.exec() 59 | -------------------------------------------------------------------------------- /gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store -------------------------------------------------------------------------------- /resources/bg.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GvozdevLeonid/BackDrop-in-PyQt-PySide/26461591665109db9a218e7413a57e02edf60b2e/resources/bg.jpeg -------------------------------------------------------------------------------- /resources/icons/chat.svg: -------------------------------------------------------------------------------- 1 | Chatbubble -------------------------------------------------------------------------------- /resources/icons/images.svg: -------------------------------------------------------------------------------- 1 | Images -------------------------------------------------------------------------------- /resources/icons/music.svg: -------------------------------------------------------------------------------- 1 | Musical Notes -------------------------------------------------------------------------------- /resources/icons/phone.svg: -------------------------------------------------------------------------------- 1 | Call -------------------------------------------------------------------------------- /resources/icons/wifi.svg: -------------------------------------------------------------------------------- 1 | Wifi --------------------------------------------------------------------------------