当我在PyQt6中使用自定义Widget作为QMainWindow的CentralWidget时,CentralWidget和QMainWindow之间存在间隙?我想知道为什么会这样。这是我的代码:
from PyQt6.QtWidgets import QApplication, QWidget, QMainWindow, QLabel, QHBoxLayout
import sys
class MyWidget(QWidget):
def __init__(self):
super().__init__()
self._layout = QHBoxLayout(self)
self.label = QLabel("hello")
self.label.setStyleSheet("QLabel {color: white;}")
self._layout.addWidget(self.label)
self.setStyleSheet("background-color: black; color: white;")
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
# When using custom widgets, there is a gap
self.central_widget = MyWidget()
# When using Qwidget, there is no gap
# self.central_widget = QWidget()
# self.central_layout = QHBoxLayout()
# self.central_layout.addWidget(QLabel("hello"))
# self.central_widget.setLayout(self.central_layout)
self.setCentralWidget(self.central_widget)
# self.central_widget.setStyleSheet("background-color: black; color: white; border: none;")
if __name__ == '__main__':
app = QApplication(sys.argv)
win = MainWindow()
win.show()
sys.exit(app.exec())
我想知道为什么使用自定义小部件和使用 QWidget 之间存在差异,以及如何修复它。
您误解了结果。
在您的自定义子类中,您将设置以下样式表:
background-color: black; color: white;
这会产生以下结果:
您看到的不是小部件的背景,而是标签的背景。您在边缘附近看到的间隙是 layout 边距。
如果在标签上指定对齐方式,情况会更清楚;将子项添加到布局时,布局将尝试使小部件占据“布局单元格”内尽可能多的可用空间,但如果指定了对齐方式,它将仅使用小部件的大小提示。
尝试执行以下操作:
self._layout.addWidget(self.label, alignment=Qt.AlignCenter)
你会看到这个:
理论上,你可以尝试取消布局边距:
self._layout.setContentsMargins(0, 0, 0, 0)
实际上,这不是正确的解决方案,因为:
因此,为了使小部件拥有自己的背景,您必须在 QSS 中使用正确的语法(使用选择器类型)并确保父小部件实际绘制其背景,这可以通过设置
Qt.WA_StyledBackground
来实现属性,或者通过实现 paintEvent()
.
class MyWidget(QWidget):
def __init__(self):
...
self.setStyleSheet("MyWidget { background-color: black;} ")
self.setAttribute(Qt.WA_StyledBackground)
或者:
class MyWidget(QWidget):
def __init__(self):
...
self.setStyleSheet("MyWidget { background-color: black;} ")
def paintEvent(self, event):
qp = QStylePainter(self)
opt = QStyleOption()
opt.initFrom(self)
qp.drawPrimitive(QStyle.PE_Widget, opt)