Pyqt5 window 全屏不显示边框

Pyqt5 window full screen does not show border

我创建了一个没有任何标题栏且透明的pyqt window。还为我的 window 添加了蓝色边框,但是在 运行 应用程序上我看不到 window.

的任何蓝色边框
from PyQt5.QtWidgets import * 
from PyQt5.QtGui import * 
from PyQt5.QtCore import Qt
import sys
  
class Window(QMainWindow):
    def __init__(self):
        super().__init__()
  
        # this will hide the title bar
        self.setWindowFlag(Qt.FramelessWindowHint)
        self.setStyleSheet("border : 3px solid blue;")
        self.setWindowOpacity(0.01)
        # setting  the geometry of window
        self.setGeometry(100, 100, 400, 300)
        self.showFullScreen()
  
  
  
# create pyqt5 app
App = QApplication(sys.argv)
  
# create the instance of our Window
window = Window()
window.show()
# start the app
sys.exit(App.exec())

如何显示 window 的边框?

您可以使用 TranslucentBackground 属性并在 paintEvent 中绘制 border/background。

class Window(QMainWindow):
    def __init__(self):
        super().__init__()
  
        # this will hide the title bar
        self.setWindowFlag(Qt.FramelessWindowHint)
        self.setAttribute(Qt.WA_TranslucentBackground)
        
        # setting  the geometry of window
        self.setGeometry(100, 100, 400, 300)
        self.showFullScreen()

    def paintEvent(self, event):
        qp = QPainter(self)
        qp.setPen(QPen(Qt.blue, 6))
        qp.drawRect(self.rect())
        
        qp.setOpacity(0.01)
        qp.setPen(Qt.NoPen)
        qp.setBrush(self.palette().window())
        qp.drawRect(self.rect())

原始代码的主要问题是 whole window 变得几乎透明(alpha 通道值为 0.01);这使得 window 的 any 内容尽可能透明,包括边框,除非桌面背景(或底层 windows)有足够的对比度,否则边框几乎不可见使用颜色设置。

虽然 按预期工作并正确回答了 OP 问题,但还有另一种可能性不直接涉及覆盖 paintEvent().

style中设置border的问题sheet 设置WA_TranslucentBackground属性只是explicit window 的不透明部分是可见的(子部件,以及 paintEvent() 中实现的任何其他绘画):背景会自动忽略,通常情况下,边框也会随之消失 [1].

一种可能性是添加一个 子部件 到主部件并仅使用适当的样式设置 that 部件的边框 sheet selector:

class Window(QMainWindow):
    def __init__(self):
        super().__init__()
  
        self.setWindowFlag(Qt.FramelessWindowHint)
        self.setAttribute(Qt.WA_TranslucentBackground)

        borderWidget = QWidget(objectName='borderWidget')
        self.setCentralWidget(borderWidget)

        bgd = self.palette().color(QPalette.Window)
        bgd.setAlphaF(.01)
        self.setStyleSheet('''
            #borderWidget {{
                border: 3px solid blue;
                background: {bgd};
            }}
        '''.format(bgd=bgd.name(bgd.HexArgb)))

        self.showFullScreen()

注意:在上面的代码(和下面的代码)中,背景仍然可见,但 alpha 通道值非常低。如果您不需要它,可以忽略 background,但是,为了保持一致性,最好显式声明它:background: transparent;.

也就是说,考虑到 QMainWindow 有自己的私有布局,这可能会在某些系统上添加不需要的边距(并且尝试覆盖它们可能根本不起作用)。
除非你真的需要 QMainWindow 的任何功能(菜单栏、状态栏、工具栏和停靠小部件),否则你应该使用基本的 QWidget,它可以让你直接控制布局:

class Window(QWidget):
    def __init__(self):
        super().__init__()
  
        self.setWindowFlag(Qt.FramelessWindowHint)
        self.setAttribute(Qt.WA_TranslucentBackground)

        borderWidget = QWidget(objectName='borderWidget')
        layout = QVBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(borderWidget)

        bgd = self.palette().color(QPalette.Window)
        bgd.setAlphaF(.01)
        self.setStyleSheet('''
            #borderWidget {{
                border: 3px solid blue;
                background: {bgd};
            }}
        '''.format(bgd=bgd.name(bgd.HexArgb)))

        self.showFullScreen()

请记住,设置 QWidget 样式的基本 background/border 属性sheet 仅适用于 actual QWidget 实例:Qt 子类以自己的方式实现它,并且如果您要将子窗口小部件创建为 custom QWidget 子类,则上述内容将 NOT 起作用(请参阅 this question and this 注释文档)。

[1] 这取决于平台的实现以及 Qt 如何通过其 QPlatformPlugin 处理它。例如,使用旧版本的 xcompmgr 我可以通过 unsetting WA_NoSystemBackground 属性(根据文档报告,当 WA_TranslucentBackground 是)。虽然正确实施特定平台问题会更好,但这几乎是不可能的,因为它们的行为通常在不同版本之间不一致,并且 window 和组合管理器之间的组合几乎是无限的。提议的解决方案应该适用于所有情况,并且开销尽可能小。