pyqt5窗口全屏不显示边框

Posted

技术标签:

【中文标题】pyqt5窗口全屏不显示边框【英文标题】:Pyqt5 window full screen does not show border 【发布时间】:2021-12-27 17:08:23 【问题描述】:

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

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())

如何显示窗口的边框?

【问题讨论】:

您看不到边框,因为您使窗口几乎完全透明。此外,如果窗口显示为全屏,FramelessWindowHint 是不必要的,因为全屏窗口已经隐藏了框架和标题栏。出于同样的原因,设置几何图形也毫无意义。 @musicamante 这个问题有悬赏,不用paintEvent你能回答吗 @FarhanAhmed 使用绘画事件有什么问题? 如赏金描述中提到的I want paintEvent to be called when the user drags the mouse to create rectangle on screen. So I don't want paintEvent to draw blue border everytime the self.update is called. I know I can use if to draw the border only once. But I do not want to do that @HimanshuPoddar 1. 请使用@username; 2.你不能“只画一次边框”,因为绘图不是这样工作的:paintEvent在系统需要时被调用,甚至在一秒钟内调用几十次,你可以做nothing 关于它; 3. 如果您希望仅在某些情况下显示边框,请创建一个内部变量,在您想要绘制边框时设置它,然后只需在paintEvent() 中检查该变量; 4. 这个问题是关于不显示边框的,而当前接受的答案解决了,您应该为您的 newnew 问题/i> 要求。 【参考方案1】:

您可以使用 TranslucentBackground 属性并在paintEvent 中绘制边框/背景。

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())

【讨论】:

【参考方案2】:

原始代码的主要问题是整个窗口变得几乎透明(alpha通道值为0.01);这使得窗口的任何内容尽可能透明,包括边框,除非桌面背景(或底层窗口)与颜色集有足够的对比度,否则边框实际上变得不可见。

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

在样式表中设置边框设置WA_TranslucentBackground属性的问题是只有显式窗口的不透明部分可见(子小部件和任何paintEvent() 中实现的其他绘画):自动忽略背景,通常情况下也会忽略边框[1]

一种可能性是添加一个子小部件到主小部件,并仅使用适当的样式表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 样式表的基本背景/边框属性仅适用于实际 QWidget 实例:Qt 子类以自己的方式实现它,如果您要创建子小部件为上面的 custom QWidget 子类将 工作(请参阅文档中的this 问题和this 注释)。

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

【讨论】:

以上是关于pyqt5窗口全屏不显示边框的主要内容,如果未能解决你的问题,请参考以下文章

在所有元素顶部显示全屏不确定进度条[重复]

手机chrome全屏不横屏

“全屏不可用”将YouTube视频作为iframe嵌入QWebEngineView中

UINavigationController 总是全屏不调整大小

使 AVPlayer 全屏不加信箱

Android11(api 30)以上设置全屏不起作用的解决方法