简体   繁体   English

PyQt5 - setStyleSheet 透明/alpha 不起作用?

[英]PyQt5 - setStyleSheet transparent/alpha not working?

I'm currently writing some program using PyQt5, and I wanted to style the scrollbar in the UI我目前正在使用 PyQt5 编写一些程序,我想在 UI 中设置滚动条的样式

QScrollBar:horizontal {
    border: 0px;
    background-color: transparent;
    color: yellow;
    height: 15px;
    margin: 0px 20px 0px 20px;
}

QScrollBar::handle:horizontal {
    background: rgb(100,100,104);
    min-width: 20px;
}

QScrollBar::add-line:horizontal {
    border: 0px;
    background-color: transparent;
    color: yellow;
    width: 20px;
    subcontrol-position: right;
    subcontrol-origin: margin;
}

QScrollBar::sub-line:horizontal {
    border: 0px;
    background-color: transparent;
    color: yellow;
    subcontrol-position: left;
    subcontrol-origin: margin;
}

but it doesn't really show up when I run the program.但是当我运行程序时它并没有真正出现。

在此处输入图像描述

I also tried styling other items in the UI, this time by adding the stylesheets inline.我还尝试在 UI 中设置其他项目的样式,这次是通过添加内联样式表。

self.content = QTextEdit()
self.content.setStyleSheet("QTextEdit {border: 5px solid transparent}")

but this shows up:但这显示了:

在此处输入图像描述

Isn't that border supposed to be transparent?那个边框不应该是透明的吗? I've tried styling other items, but I just can't seem to make the transparent styling work.我尝试过设计其他项目的样式,但似乎无法使透明样式起作用。 I've also tried using rgba(0,0,0,0) instead of transparent and I get the same results.我也尝试过使用rgba(0,0,0,0)而不是透明的,我得到了相同的结果。 Is there something I'm missing here?我在这里缺少什么吗?

EDIT: Here's the MRE as requested by @musicamante编辑:这是@musicamante 要求的 MRE

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *

class MainWindow(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.stylesheet_filename = "qss/styles.qss"
        self.loadStyleSheet(self.stylesheet_filename)

        self.setGeometry(200,200,800,600)

        self.layout = QVBoxLayout()
        self.layout.setContentsMargins(0,0,0,0)
        self.setLayout(self.layout)
        
        self.scene = MainScene()
        self.view = QGraphicsView()

        self.view.setScene(self.scene)
        self.layout.addWidget(self.view)

        self.show()

    def loadStyleSheet(self, filename):
        print('Style loading: ', filename)
        file = QFile(filename)
        file.open(QFile.ReadOnly | QFile.Text)
        stylesheet = file.readAll()
        QApplication.instance().setStyleSheet(str(stylesheet, encoding='utf-8'))

class MainScene(QGraphicsScene):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setSceneRect(-1000,-1000,2000,2000)
        self.setBackgroundBrush(QColor("#252629"))
        self.card = Card()
        self.addItem(self.card)


class Card(QGraphicsItem):
    def __init__(self, parent = None):
        super().__init__(parent)    

        self.setFlag(QGraphicsItem.ItemIsSelectable)
        self.setFlag(QGraphicsItem.ItemIsMovable)  
        
        self.content = Content()

        self.grContent = QGraphicsProxyWidget(self)
        self.content.setGeometry(10,15, 280, 150)
        self.grContent.setWidget(self.content)

    def boundingRect(self):
        return QRectF(0,0,300,180).normalized()

    def paint(self, painter, QStyleOptionGraphicsItem, widget=None):
        #background
        path_background = QPainterPath()
        path_background.addRect(0,0,300,180)
        painter.setPen(Qt.NoPen)
        painter.setBrush(QBrush(QColor("#998090")))
        painter.drawPath(path_background.simplified())


class Content(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.layout = QVBoxLayout()
        self.layout.setContentsMargins(0,0,0,0)
        self.setLayout(self.layout)
        self.content = QTextEdit('I want the background of this QTextEdit and the scrollbar tracks to be transparent, not white.')
        self.content.setStyleSheet("QTextEdit {border: 0px; background-color: transparent}")
        
        self.layout.addWidget(self.content)
        

if __name__ == "__main__":
    app = QApplication(sys.argv)

    mainWindow = MainWindow()
    
    sys.exit(app.exec_())

EDIT 2: And I forgot to paste the qss code:编辑2:我忘了粘贴qss代码:

QScrollBar:horizontal {
    border: 0px;
    background: rgba(0,0,0,0);
    height: 15px;
    margin: 0px 20px 0 20px;
}
QScrollBar::handle:horizontal {
    background: red;
    min-width: 20px;
}
QScrollBar::add-line:horizontal {
    border: 0px;
    background: rgba(0,0,0,0);
    width: 20px;
    subcontrol-position: right;
    subcontrol-origin: margin;
}

QScrollBar::sub-line:horizontal {
    border: 0px;
    background: rgba(0,0,0,0);
    width: 20px;
    subcontrol-position: left;
    subcontrol-origin: margin;
}

While it might seem that the concepts of "standard" css can be applied to Qt StyleSheets (QSS), that is only true for the basic aspects of syntax and inheritance: QSS only implements some of the CSS 2.1 specification, and does not allow layout management (except for borders, margins and padding within the specific widget), which is exclusive responsibility of Qt. While it might seem that the concepts of "standard" css can be applied to Qt StyleSheets (QSS), that is only true for the basic aspects of syntax and inheritance: QSS only implements some of the CSS 2.1 specification, and does not allow layout管理(特定小部件内的边框、边距和填充除外),这是 Qt 的专属责任。

This is very important when trying to set a "transparent" background for a scroll bar, because Qt doesn't allow the "overflow" effect of CSS, since the scrollbars are generally drawn outside the contents of the viewport.这在尝试为滚动条设置“透明”背景时非常重要,因为 Qt 不允许 CSS 的“溢出”效果,因为滚动条通常绘制在视口内容之外

In order to achieve a similar effect, the solution is to correctly set the background of the scroll area (the QGraphicsView, in your case).为了达到类似的效果,解决方案是正确设置滚动区域的背景(在您的情况下为 QGraphicsView)。

QGraphicsView { 
    background: #252629; 
}

Note that, for various reasons, it's not always enough to set a generic stylesheet on the application, and it's sometimes required to explicitly set the scrollbar-dedicated stylesheet on the scroll bars ( self.view.horizontalScrollBar().setStyleSheet(...) , self.view.verticalScrollBar().setStyleSheet(...) ).请注意,由于各种原因,在应用程序上设置通用样式表并不总是足够的,有时需要在滚动条显式设置滚动条专用样式表( self.view.horizontalScrollBar().setStyleSheet(...) , self.view.verticalScrollBar().setStyleSheet(...) )。

Then, the problem with the widget in the QGraphicsScene is different.那么,QGraphicsScene 中的小部件的问题就不同了。 When adding a QGraphicsProxyWidget, the widget is considered as a top level window, so it will have its own background, based on the application palette (which seems white, but it's a light gray).添加 QGraphicsProxyWidget 时,该小部件被视为顶级window,因此它将有自己的背景,基于应用程序调色板(看起来是白色的,但它是浅灰色的)。 The solution, in this case, is the same as when trying to show a "transparent" window:在这种情况下,解决方案与尝试显示“透明”window 时相同:

class Content(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.setAttribute(Qt.WA_TranslucentBackground)
        # ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM