透明图像覆盖主要 window 背景颜色的框架

Transparent image covers frame with main window background color

我正在尝试使用 PyQt 设计棋盘 GUI。该板由框架组成。当我放置棋子的透明 PNG 时,PNG 使用 window 的背景着色,从而覆盖下面的框架。当 window 没有设置背景颜色时,棋子及其下方的正方形会正常显示。我怎样才能将图像设置为不使用 window 背景色覆盖其下方的方框?

这是输出的屏幕截图:

from PyQt5 import QtWidgets
import PyQt5.QtWidgets as qtw
import PyQt5.QtGui as qtg
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *

DIM = 1024
SQUARE = 70
PIECE = 60

class MainWindow(qtw.QWidget):
    def __init__(self):
        super().__init__()
        self.setLayout(qtw.QGridLayout())
        self.resize(DIM,DIM)        
        
        board = [[] for _ in range(0, 8)]
        for r, row in enumerate(board):
            for c in range(0, 8):
                square = QFrame(self)
                square.setObjectName(u"frame" + f"{r}-{c}")
                square.setGeometry(QRect(DIM // 2 - SQUARE * (c - 4),
                                        DIM - 300 - SQUARE*(r+1), SQUARE, SQUARE))
                if (r + c) % 2 == 0:
                    square.setStyleSheet(u"background-color: grey;")
                else:
                    square.setStyleSheet(u"background-color: white;")
                board[r].append(square)
        

        self.setStyleSheet("background-color: indigo;")        
        self.setWindowFlag(Qt.FramelessWindowHint)
        
        pawn = QtWidgets.QLabel(self)
        pawn.setPixmap(qtg.QPixmap("pieces/b_pawn.png"))
        pawn.setGeometry(DIM // 2 - 2 * SQUARE + 5 , DIM - 300 - SQUARE + 5, PIECE, PIECE)

        self.show()

app = qtw.QApplication([])
mw = MainWindow()

app.exec_()
mw.show()

问题是您正在为顶级小部件设置 general 背景,并且由于样式表传播给子项,结果是该片段继承了该背景。

解决方案是始终避免此类笼统声明并正确使用 selectors

在这种情况下,您可以使用 class 选择器:

class MainWindow(qtw.QWidget):
    def __init__(self):
        # ...
        self.setStyleSheet("MainWindow {background-color: indigo;}") 

不相关的考虑因素:

  • 迭代本身内迭代正在修改的列表时要小心,并且要注意无论如何您都没有正确利用它:您已经拥有内部列表,因此请改用 row.append(square)
  • 您正在创建布局,但并未使用它;这可能会成为一个问题,因为调整主 window 的大小将不允许板调整其大小或位置:如果 window 变大,板将只占据界面的一部分,但如果尺寸更小,它可以变得完全隐形;请参阅 以了解在保持正确纵横比的同时考虑 window 调整大小的可能实现;
  • 最后的 mw.show() 永远不会被调用(至少,没有用),因为你把它放在 之后 进入应用程序事件循环(app.exec_());