PySide6 QWidget实现无边框圆角窗口border-radius无效问题
PySide6 无边框QWidget圆角不生效解决方案
问题根源
顶层QWidget开启Qt.FramelessWindowHint后,默认由系统接管窗口底层区域绘制,样式表设置的border-radius仅作用于Qt内部绘制的内容,无法裁剪系统绘制的方形窗口底层,因此圆角不生效。直接使用setMask做像素级遮罩属于硬裁剪,无抗锯齿计算,会出现边缘锯齿、模糊问题。
修复方案
添加Qt.WA_TranslucentBackground窗口属性,让Qt完全接管窗口的区域绘制,跳过系统原生方形背景的渲染,此时样式表的圆角属性会正常生效,且自带抗锯齿效果,边缘平滑。
如果需要避免系统默认阴影在圆角处产生杂色,可以额外添加Qt.NoDropShadowWindowHint窗口标记。
修改后的可运行代码:
from PySide6.QtCore import Qt, QSize from PySide6.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton class MainWidget(QWidget): def __init__(self): super().__init__() self.setWindowFlag(Qt.FramelessWindowHint) # 去掉系统默认阴影,避免圆角边缘出现杂色 self.setWindowFlag(Qt.NoDropShadowWindowHint) # 核心配置:开启窗口半透明绘制,由Qt接管全窗口渲染 self.setAttribute(Qt.WA_TranslucentBackground) self.setFixedSize(QSize(400, 400)) self.setStyleSheet(""" MainWidget { border-radius: 25px; background: red; } """) self.vertical_layout = QVBoxLayout() self.button = QPushButton('Exit') self.button.clicked.connect(lambda: self.close()) self.vertical_layout.addWidget(self.button, alignment=Qt.AlignCenter) self.setLayout(self.vertical_layout) app = QApplication([]) widget = MainWidget() widget.show() app.exec()
补充说明
- 该方案渲染的圆角为Qt矢量抗锯齿绘制,不会出现遮罩方案的边缘模糊问题
- 如果需要窗口阴影效果,不要依赖系统阴影,直接在样式表中为窗口添加
box-shadow属性自定义即可 - 后续实现窗口拖拽、缩放等交互逻辑,和该圆角方案无冲突,正常重写鼠标事件即可
- 若部分环境下出现窗口闪烁问题,可在构造函数中补充
self.setAutoFillBackground(False)解决
内容的提问来源于stack exchange,提问作者Spark Drago
相关产品推荐
相关产品推荐

