name: pyqt-styling description: "PyQt/PySide6 QSS styling - selectors, properties, pseudo-states, dark theme, widget-specific styles" metadata: author: mte90 version: 1.0.0 tags: - python - qt - pyqt - pyside - styling - qss - css - themes
PyQt Styling - QSS (Qt Style Sheets)
Complete guide to styling Qt applications with QSS.
Basic Syntax
Type Selectors
/* Match all widgets of a type */
QLabel {
color: #333333;
font-size: 14px;
}
QPushButton {
background-color: #0078d4;
color: white;
border: none;
padding: 8px 16px;
}
QLineEdit {
border: 1px solid #cccccc;
border-radius: 4px;
padding: 4px;
}
Class Selectors
/* Match widgets with specific property */
QPushButton[primary="true"] {
background-color: #0078d4;
color: white;
}
QLabel[heading="true"] {
font-size: 24px;
font-weight: bold;
}
ID Selectors
/* Match specific widget by objectName */
#myButton {
background-color: red;
}
#statusLabel {
color: green;
}
Pseudo-States
/* Hover state */
QPushButton:hover {
background-color: #106ebe;
}
/* Pressed state */
QPushButton:pressed {
background-color: #005a9e;
}
/* Disabled state */
QPushButton:disabled {
background-color: #cccccc;
color: #666666;
}
/* Focus state */
QLineEdit:focus {
border: 2px solid #0078d4;
}
/* Checked state (for checkable widgets) */
QCheckBox:checked {
color: green;
}
/* Selected state */
QListWidget::item:selected {
background-color: #0078d4;
color: white;
}
Applying Styles
Application-Wide
from PySide6.QtWidgets import QApplication
app = QApplication()
# Inline
app.setStyleSheet("""
QLabel { color: #333; }
QPushButton { padding: 5px 10px; }
""")
# From file
with open("style.qss", "r") as f:
app.setStyleSheet(f.read())
Widget-Specific
button = QPushButton("Styled")
button.setStyleSheet("""
QPushButton {
background-color: blue;
color: white;
border-radius: 5px;
}
QPushButton:hover {
background-color: darkblue;
}
""")
Custom Properties
# Set custom property
button = QPushButton("Primary")
button.setProperty("primary", True)
# Force style refresh
button.style().unpolish(button)
button.style().polish(button)
/* Use in QSS */
QPushButton[primary="true"] {
background-color: #0078d4;
color: white;
}
QPushButton[primary="true"]:hover {
background-color: #106ebe;
}
Common Properties
Colors
/* Text color */
color: #333333;
/* Background color */
background-color: white;
/* Selection colors */
selection-color: white;
selection-background-color: #0078d4;
/* Border color */
border: 1px solid #cccccc;
/* Alternate row color */
alternate-background-color: #f5f5f5;
Fonts
/* Font family */
font-family: "Segoe UI", Arial, sans-serif;
/* Font size */
font-size: 14px;
/* Font weight */
font-weight: bold; /* normal, bold, 100-900 */
/* Font style */
font-style: italic;
/* Combined */
font: bold 14px "Segoe UI";
Borders
/* All sides */
border: 1px solid #cccccc;
/* Individual sides */
border-top: 1px solid #cccccc;
border-right: 2px dashed #999999;
border-bottom: 1px solid #cccccc;
border-left: none;
/* Border radius */
border-radius: 4px;
/* Individual corners */
border-top-left-radius: 8px;
border-top-right-radius: 8px;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
Spacing
/* Padding (inside border) */
padding: 10px;
padding: 10px 20px; /* vertical horizontal */
padding: 5px 10px 5px 10px; /* top right bottom left */
/* Margin (outside border) */
margin: 5px;
/* Spacing between widgets */
spacing: 10px;
Size
/* Minimum size */
min-width: 100px;
min-height: 30px;
/* Maximum size */
max-width: 500px;
max-height: 200px;
/* Fixed size */
width: 200px;
height: 50px;
Widget-Specific Styles
QPushButton
QPushButton {
background-color: #0078d4;
color: white;
border: none;
border-radius: 4px;
padding: 8px 16px;
font-weight: bold;
}
QPushButton:hover {
background-color: #106ebe;
}
QPushButton:pressed {
background-color: #005a9e;
}
QPushButton:disabled {
background-color: #cccccc;
color: #666666;
}
/* Flat button */
QPushButton[flat="true"] {
background-color: transparent;
color: #0078d4;
border: 1px solid #0078d4;
}
QLineEdit
QLineEdit {
background-color: white;
border: 1px solid #cccccc;
border-radius: 4px;
padding: 4px 8px;
selection-background-color: #0078d4;
}
QLineEdit:focus {
border: 2px solid #0078d4;
}
QLineEdit:disabled {
background-color: #f5f5f5;
color: #999999;
}
/* Password field */
QLineEdit[echoMode="2"] {
lineedit-password-character: 9679; /* Unicode bullet */
}
QComboBox
QComboBox {
background-color: white;
border: 1px solid #cccccc;
border-radius: 4px;
padding: 4px 8px;
}
QComboBox:hover {
border-color: #999999;
}
QComboBox::drop-down {
border: none;
width: 24px;
}
QComboBox::down-arrow {
image: url(down_arrow.png);
width: 12px;
height: 12px;
}
/* Dropdown list */
QComboBox QAbstractItemView {
background-color: white;
border: 1px solid #cccccc;
selection-background-color: #0078d4;
}
QTabWidget
QTabWidget::pane {
border: 1px solid #cccccc;
border-radius: 4px;
}
QTabBar::tab {
background-color: #f5f5f5;
border: 1px solid #cccccc;
padding: 8px 16px;
margin-right: 2px;
}
QTabBar::tab:selected {
background-color: white;
border-bottom-color: white;
}
QTabBar::tab:hover {
background-color: #e5e5e5;
}
QScrollBar
/* Vertical scrollbar */
QScrollBar:vertical {
background-color: #f5f5f5;
width: 12px;
margin: 0;
}
QScrollBar::handle:vertical {
background-color: #cccccc;
border-radius: 6px;
min-height: 30px;
}
QScrollBar::handle:vertical:hover {
background-color: #999999;
}
QScrollBar::add-line:vertical,
QScrollBar::sub-line:vertical {
height: 0;
}
Dark Theme Example
DARK_THEME = """
/* Global */
* {
font-family: "Segoe UI", Arial, sans-serif;
}
QWidget {
background-color: #1e1e1e;
color: #e0e0e0;
}
/* Main window */
QMainWindow {
background-color: #1e1e1e;
}
/* Labels */
QLabel {
color: #e0e0e0;
}
/* Buttons */
QPushButton {
background-color: #0e639c;
color: white;
border: none;
border-radius: 4px;
padding: 6px 12px;
font-weight: bold;
}
QPushButton:hover {
background-color: #1177bb;
}
QPushButton:pressed {
background-color: #0d5a8a;
}
QPushButton:disabled {
background-color: #3c3c3c;
color: #666666;
}
/* Input fields */
QLineEdit, QTextEdit, QPlainTextEdit {
background-color: #2d2d2d;
color: #e0e0e0;
border: 1px solid #3c3c3c;
border-radius: 4px;
padding: 4px 8px;
selection-background-color: #0e639c;
}
QLineEdit:focus, QTextEdit:focus, QPlainTextEdit:focus {
border-color: #0e639c;
}
/* ComboBox */
QComboBox {
background-color: #2d2d2d;
color: #e0e0e0;
border: 1px solid #3c3c3c;
border-radius: 4px;
padding: 4px 8px;
}
QComboBox:hover {
border-color: #4a4a4a;
}
QComboBox::drop-down {
border: none;
width: 20px;
}
QComboBox QAbstractItemView {
background-color: #2d2d2d;
color: #e0e0e0;
selection-background-color: #0e639c;
border: 1px solid #3c3c3c;
}
/* SpinBox */
QSpinBox, QDoubleSpinBox {
background-color: #2d2d2d;
color: #e0e0e0;
border: 1px solid #3c3c3c;
border-radius: 4px;
padding: 4px;
}
/* Checkbox */
QCheckBox {
color: #e0e0e0;
spacing: 8px;
}
QCheckBox::indicator {
width: 16px;
height: 16px;
border: 1px solid #3c3c3c;
border-radius: 3px;
}
QCheckBox::indicator:checked {
background-color: #0e639c;
border-color: #0e639c;
}
/* Radio button */
QRadioButton {
color: #e0e0e0;
spacing: 8px;
}
QRadioButton::indicator {
width: 16px;
height: 16px;
border: 1px solid #3c3c3c;
border-radius: 8px;
}
QRadioButton::indicator:checked {
background-color: #0e639c;
border-color: #0e639c;
}
/* Tab widget */
QTabWidget::pane {
border: 1px solid #3c3c3c;
background-color: #1e1e1e;
}
QTabBar::tab {
background-color: #2d2d2d;
color: #e0e0e0;
border: 1px solid #3c3c3c;
padding: 6px 12px;
margin-right: 2px;
}
QTabBar::tab:selected {
background-color: #1e1e1e;
border-bottom-color: #1e1e1e;
}
QTabBar::tab:hover {
background-color: #3c3c3c;
}
/* Scrollbar */
QScrollBar:vertical {
background-color: #2d2d2d;
width: 12px;
}
QScrollBar::handle:vertical {
background-color: #4a4a4a;
border-radius: 6px;
min-height: 30px;
}
QScrollBar::handle:vertical:hover {
background-color: #5a5a5a;
}
QScrollBar::add-line:vertical,
QScrollBar::sub-line:vertical {
height: 0;
}
/* Scrollbar horizontal */
QScrollBar:horizontal {
background-color: #2d2d2d;
height: 12px;
}
QScrollBar::handle:horizontal {
background-color: #4a4a4a;
border-radius: 6px;
min-width: 30px;
}
QScrollBar::handle:horizontal:hover {
background-color: #5a5a5a;
}
/* Menu */
QMenuBar {
background-color: #2d2d2d;
color: #e0e0e0;
}
QMenuBar::item:selected {
background-color: #0e639c;
}
QMenu {
background-color: #2d2d2d;
color: #e0e0e0;
border: 1px solid #3c3c3c;
}
QMenu::item:selected {
background-color: #0e639c;
}
/* Tooltip */
QToolTip {
background-color: #2d2d2d;
color: #e0e0e0;
border: 1px solid #3c3c3c;
padding: 4px;
}
/* Status bar */
QStatusBar {
background-color: #007acc;
color: white;
}
/* GroupBox */
QGroupBox {
border: 1px solid #3c3c3c;
border-radius: 4px;
margin-top: 12px;
padding-top: 12px;
font-weight: bold;
}
QGroupBox::title {
subcontrol-origin: margin;
left: 8px;
padding: 0 4px;
}
"""
# Apply
app.setStyleSheet(DARK_THEME)
Best Practices
- Use semantic class names -
primary,danger,warning - Organize styles by widget - Keep related styles together
- Use variables - Store colors in custom properties
- Test on all platforms - Colors and fonts vary
- Use relative units -
emfor fonts (limited support) - Keep styles modular - Separate files per theme