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窗口全屏不显示边框的主要内容,如果未能解决你的问题,请参考以下文章
“全屏不可用”将YouTube视频作为iframe嵌入QWebEngineView中