7. PySide6 样式和动画
QSS 基本语法
类似 CSS,QSS 每一条都是由一个选择器和一组声明构成:
- 选择器选出要对哪种控件进行样式修改
- 每个声明都是键值对,键为属性,值为属性值
QWidget {
color: #000;
background-color: #fff;
}
使用方式
为降低耦合,往往把 QSS 写在一个单独的 style.qss
文件中,然后在 main.py
的 QMainWindow
中加载样式。
新建一个扩展名为 .qss
的文件,如 style.qss
,编辑内容。
QWidget {
color: #e34fff;
background-color: #000;
}
在 main.py
中加载样式:
import sys
from PySide6.QtCore import QFile, Qt
from PySide6.QtWidgets import QApplication, QLabel, QMainWindow
class QSSLoader:
def __init__(self, path: str) -> None:
self._path = path
def load(self) -> str:
f = QFile(self._path)
f.open(QFile.ReadOnly | QFile.Text)
stylesheet = f.readAll()
return stylesheet.data().decode("utf-8")
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("QSS Demo")
self.resize(400, 300)
label = QLabel("Hello World")
label.setAlignment(Qt.AlignCenter)
self.setCentralWidget(label)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.setStyleSheet(QSSLoader("style.qss").load())
window.show()
sys.exit(app.exec())
动态修改
部分参考了 hektorprofe/curso-qt-pyside-udemy 的代码。
import sys
from PySide6.QtWidgets import (
QApplication,
QCheckBox,
QFormLayout,
QLabel,
QLineEdit,
QMainWindow,
QPlainTextEdit,
QPushButton,
QRadioButton,
QSpinBox,
QVBoxLayout,
QWidget,
)
STYLE = """QMainWindow {
background-color: #212121;
}
QLabel {
color: #e9e9e9;
}
QPushButton {
background-color: orange;
font-family: 'Arial';
font-size: 14px;
font-weight: bold;
}
"""
class QSSEditor(QWidget):
def __init__(self, parent: QWidget | None = None):
super().__init__()
self._parent = parent
self.resize(480, 320)
self.setWindowTitle("QSS Editor")
self._editor = QPlainTextEdit()
self._editor.setStyleSheet(
"background-color: #212121;color: #e9e9e9;"
"font-family: Consolas; font-size: 16px; "
)
self._editor.setFont("Consolas")
self._editor.setPlainText(STYLE)
self._editor.textChanged.connect(self.update_style)
layout = QVBoxLayout()
layout.addWidget(self._editor)
self.setLayout(layout)
self.show()
def update_style(self):
qss = self._editor.toPlainText()
try:
self._parent.setStyleSheet(qss)
except:
pass
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
layout = QFormLayout()
layout.addRow("QCheckBox", QCheckBox())
layout.addRow("QRadioButton", QRadioButton())
layout.addRow("QLabel", QLabel("QLabel"))
layout.addRow("QPushButton", QPushButton("QPushButton"))
layout.addRow("QLineEdit", QLineEdit("QLineEdit"))
layout.addRow("QSpinBox", QSpinBox())
widget = QWidget()
widget.setLayout(layout)
self.setCentralWidget(widget)
label = QLabel("QLabel")
label.setObjectName("label")
layout.addRow(label)
self._qss_editor = QSSEditor(self)
self.setStyleSheet(STYLE)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())