You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyQt实现背景透明但保留窗口边框与标题栏的技术问询

PyQt窗口背景透明且保留标题栏与边框解决方案

问题描述

需要实现一个PyQt应用,要求窗口背景完全透明(可看到后方运行的程序),但保留可调整大小的边框、标题栏以及最小化、关闭按钮。以下是尝试的代码及遇到的问题:

import sys

from PyQt5.QtWidgets import (
    QWidget, QApplication, QPushButton, QVBoxLayout,
    QLabel
    )
from PyQt5.QtGui import (
    QPainter, QBrush, QColor, QPen
    )
from PyQt5.QtCore import QRect, QPoint, Qt, QSize

class MyWidget(QWidget):
    def __init__(self):
        super().__init__()
        self.setGeometry(30,30,600,400)

        # 以下代码尝试实现背景透明
        self.setWindowOpacity(.8)
        self.setStyleSheet("background:red;")
        self.setAttribute(Qt.WA_NoSystemBackground)
        self.setAttribute(Qt.WA_TranslucentBackground)
        self.setAttribute(Qt.WA_PaintOnScreen)
        # self.setWindowFlag(Qt.FramelessWindowHint)

        self.layout = QVBoxLayout()
        self.layout.setAlignment(Qt.AlignRight) 
        self.button = QPushButton("X")
        self.button.setFixedSize(QSize(40, 40))
        
        self.layout.addWidget(self.button)
        self.setLayout(self.layout)

        self.button.clicked.connect(self.close)
  
        self.show()
        self.setFocus()
        

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = MyWidget()
    sys.exit(app.exec_())

测试情况说明

  • self.setWindowOpacity(.8):生效,但标题栏同步透明,完全透明时标题栏消失。
  • self.setStyleSheet("background:red;"):仅使背景变黑,设置红色只为确保按钮可见。
  • self.setAttribute(Qt.WA_NoSystemBackground)、self.setAttribute(Qt.WA_PaintOnScreen):无明显作用。
  • self.setAttribute(Qt.WA_TranslucentBackground)与self.setWindowFlag(Qt.FramelessWindowHint)搭配:实现透明,但标题栏和边框完全消失。

解决方案

核心思路是启用半透明背景属性但保留系统窗口框架,通过重写paintEvent绘制完全透明的背景,避免默认不透明背景覆盖透明效果。

修改后的完整代码:

import sys

from PyQt5.QtWidgets import (
    QWidget, QApplication, QPushButton, QVBoxLayout,
    QLabel
    )
from PyQt5.QtGui import (
    QPainter, QColor
    )
from PyQt5.QtCore import Qt, QSize

class MyWidget(QWidget):
    def __init__(self):
        super().__init__()
        self.setGeometry(30,30,600,400)

        # 关键:启用半透明背景属性,不隐藏系统窗口框架
        self.setAttribute(Qt.WA_TranslucentBackground)

        self.layout = QVBoxLayout()
        self.layout.setAlignment(Qt.AlignRight) 
        self.button = QPushButton("X")
        self.button.setFixedSize(QSize(40, 40))
        
        self.layout.addWidget(self.button)
        self.setLayout(self.layout)

        self.button.clicked.connect(self.close)
  
        self.show()
        self.setFocus()

    def paintEvent(self, event):
        # 绘制完全透明的背景,确保窗口主体区域透明
        painter = QPainter(self)
        painter.fillRect(self.rect(), QColor(0, 0, 0, 0))

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = MyWidget()
    sys.exit(app.exec_())

关键修改说明

  1. 移除setWindowOpacity:避免影响标题栏透明度。
  2. 保留WA_TranslucentBackground:允许窗口存在透明区域,这是实现背景透明的核心属性。
  3. 移除WA_NoSystemBackground和WA_PaintOnScreen:这两个属性会干扰系统窗口框架的正常渲染。
  4. 重写paintEvent:绘制全透明的背景色(RGBA的alpha值为0),替代QWidget默认的不透明背景,确保窗口主体完全透明,同时系统标题栏和边框不受影响。

这样就能实现背景完全透明、保留可调整边框及标题栏控件的需求。

内容的提问来源于stack exchange,提问作者AccidentalTaylorExpansion

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 08:45:03