Reputation: 349
I have the following code in which I try to show a shadow effect behind the QMainWindow, for which I use QGraphicsDropShadowEffect
to be able to get the shadow.
But when running the code does not suspend anything.
I already tried modifying the color and the offset but it did not work either
Code. Py
from PyQt5.QtWidgets import QMainWindow,QApplication,QGraphicsDropShadowEffect
from PyQt5 import QtCore,QtGui
from PyQt5 import uic
class CInicial(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
uic.loadUi("ConfiguracionInicial.ui",self)
self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
self.shadow = QGraphicsDropShadowEffect(self)
self.shadow.setBlurRadius(99)
self.shadow.setColor(QtGui.QColor(99,255,255))
self.shadow.setOffset(4)
self.setGraphicsEffect(self.shadow)
app = QApplication([])
ci = CInicial()
ci.show()
app.exec_()
. Ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>683</width>
<height>482</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<property name="styleSheet">
<string notr="true">background-color:#5E5858;</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QFrame" name="fContenedor1">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>691</width>
<height>41</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">background:qlineargradient(spread:pad, x1:0.498, y1:1, x2:0.472, y2:0, stop:0 rgba(46, 46, 48, 255), stop:1 rgba(137, 137, 137, 255));</string>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>5</x>
<y>9</y>
<width>151</width>
<height>21</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="styleSheet">
<string notr="true">color:white;
background:none;</string>
</property>
<property name="text">
<string>Configuración Inicial</string>
</property>
</widget>
</widget>
</widget>
</widget>
<resources/>
<connections/>
</ui>
Upvotes: 1
Views: 2275
Reputation: 21
If you want to not only drop the shadow but also make the corner rounded, here is the solution.
from PyQt5.QtCore import Qt, QRectF, QMargins
from PyQt5.QtGui import QColor, QPainter, QPainterPath, QBrush, QPen, QRegion, QPalette
from PyQt5.QtWidgets import QWidget, QMainWindow, QApplication, QGraphicsDropShadowEffect, QGridLayout, QLabel, \
QTextEdit, QVBoxLayout
# shadow + rounded frame
class ShadowFrame(QWidget):
def __init__(self, main_window):
super().__init__()
# main_window is main widget to show
self.__main_window = main_window
self.__initUi()
def __initUi(self):
# for frameless window/prevent occurrence of minor bugs
self.setWindowFlags(Qt.Window | Qt.FramelessWindowHint | Qt.WindowMinMaxButtonsHint)
# make basic background(which is dark) invisible to show shadow
self.setAttribute(Qt.WA_TranslucentBackground)
# set the shadow
self.__effect = QGraphicsDropShadowEffect()
self.__effect.setBlurRadius(12.0)
self.__effect.setColor(QColor(0, 0, 0, 127))
self.__effect.setOffset(0.0)
self.setGraphicsEffect(self.__effect)
lay = QGridLayout()
lay.addWidget(self.__main_window)
self.setLayout(lay)
def paintEvent(self, e):
painter = QPainter(self)
# set the background and pen (looks like Windows 11 default window)
pen = QPen(QColor(Qt.gray), 1)
brush = QBrush(QColor(241, 241, 241, 255))
painter.setPen(pen)
painter.setBrush(brush)
# set rounded window
path = QPainterPath()
rect = self.rect()
# set margin to each direction for giving the space to show shadow
rect = rect.marginsRemoved(QMargins(5, 5, 5, 5))
# rounded corner's radius
radius = 12.0
path.addRoundedRect(QRectF(rect), radius, radius)
# set antialiasing to enhance quality of window
painter.setRenderHints(QPainter.Antialiasing)
painter.drawPath(path)
return super().paintEvent(e)
# sample widget to put inside the shadow(+rounded) frame
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.__initUi()
def __initUi(self):
lbl = QLabel()
lbl.setText('Shadow window example')
textEdit = QTextEdit()
lay = QVBoxLayout()
lay.addWidget(lbl)
lay.addWidget(textEdit)
mainWidget = QWidget()
mainWidget.setLayout(lay)
self.setCentralWidget(mainWidget)
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
widget = MainWindow()
# put inside the shadow(+rounded) frame
window = ShadowFrame(widget)
window.show()
app.exec_()
Check my repo if you want to see the detail of it: https://github.com/yjg30737/pyqt-shadow-frame-window-example
Upvotes: 0
Reputation: 244301
When the shadow effect is applied it is painted in the parent widget, so in the case of your CInicial it will have no effect. One solution is to create a parent widget and set the Initialize through a layout:
from PyQt5 import QtCore, QtGui, QtWidgets, uic
class Container(QtWidgets.QWidget):
def __init__(self, window, parent=None):
super(Container, self).__init__(parent)
self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(window)
lay.setContentsMargins(10, 10, 10, 10)
shadow = QtWidgets.QGraphicsDropShadowEffect(self,
blurRadius=9.0,
color=QtGui.QColor(99, 255, 255),
offset=QtCore.QPointF(8.0, 8.0)
)
window.setGraphicsEffect(shadow)
class CInicial(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(CInicial, self).__init__(parent)
uic.loadUi("ConfiguracionInicial.ui",self)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = CInicial()
container = Container(w)
container.resize(640, 480)
container.show()
sys.exit(app.exec_())
Upvotes: 5