From 79ed0a36c792e9f4e4e1635a051d61d95b09fe03 Mon Sep 17 00:00:00 2001 From: MarcusStill <69536339+MarcusStill@users.noreply.github.com> Date: Tue, 18 Aug 2026 17:11:46 +0000 Subject: [PATCH] Modernize PySide6 UI with Windows 10/11 QSS styles - Created `files/style.qss` containing modern Windows 10/11 styling (flat design, #0078D4 accent, Segoe UI font) - Modified `main.py` to correctly load and apply `files/style.qss` using `pathlib` for absolute path resolution - Applied the styles globally via `app.setStyleSheet()` while maintaining the native `Fusion` base style - Avoided overriding checkmark/radio button indicators to retain native rendering --- files/style.qss | 207 ++++++++++++++++++++++++++++++++++++++++++++++++ main.py | 9 +++ 2 files changed, 216 insertions(+) create mode 100644 files/style.qss diff --git a/files/style.qss b/files/style.qss new file mode 100644 index 0000000..cf68ad3 --- /dev/null +++ b/files/style.qss @@ -0,0 +1,207 @@ +/* +Windows 10/11 Light Theme Style Sheet +Accent Color: #0078D4 +Font: Segoe UI, 10pt +*/ + +QWidget { + background-color: #FFFFFF; + color: #000000; + font-family: "Segoe UI", sans-serif; + font-size: 10pt; +} + +QMainWindow { + background-color: #F3F3F3; +} + +QDialog { + background-color: #FFFFFF; +} + +/* Buttons */ +QPushButton { + background-color: #F3F3F3; + border: 1px solid #CCCCCC; + border-radius: 4px; + padding: 6px 16px; + color: #000000; +} + +QPushButton:hover { + background-color: #E5E5E5; + border: 1px solid #CCCCCC; +} + +QPushButton:pressed { + background-color: #CCCCCC; + border: 1px solid #999999; +} + +QPushButton:disabled { + background-color: #F9F9F9; + color: #A0A0A0; + border: 1px solid #E0E0E0; +} + +/* Primary/Action Button styled as Accent */ +QPushButton[isPrimary="true"] { + background-color: #0078D4; + color: #FFFFFF; + border: 1px solid #0078D4; +} + +QPushButton[isPrimary="true"]:hover { + background-color: #106EBE; + border: 1px solid #106EBE; +} + +QPushButton[isPrimary="true"]:pressed { + background-color: #005A9E; + border: 1px solid #005A9E; +} + +/* Inputs */ +QLineEdit, QComboBox, QDateEdit, QTimeEdit, QSpinBox, QDoubleSpinBox, QTextEdit, QPlainTextEdit { + background-color: #FFFFFF; + border: 1px solid #CCCCCC; + border-radius: 4px; + padding: 4px 8px; + selection-background-color: #0078D4; + selection-color: #FFFFFF; +} + +QLineEdit:focus, QComboBox:focus, QDateEdit:focus, QTimeEdit:focus, QSpinBox:focus, QDoubleSpinBox:focus, QTextEdit:focus, QPlainTextEdit:focus { + border: 1px solid #0078D4; +} + +QLineEdit:disabled, QComboBox:disabled, QDateEdit:disabled, QTimeEdit:disabled, QSpinBox:disabled, QDoubleSpinBox:disabled, QTextEdit:disabled, QPlainTextEdit:disabled { + background-color: #F3F3F3; + color: #A0A0A0; + border: 1px solid #E0E0E0; +} + +QComboBox::drop-down { + border-left: 1px solid #CCCCCC; + width: 24px; +} + +QComboBox::down-arrow { + image: none; /* Can add a custom arrow if desired, using Qt defaults for now */ +} + +/* Tables */ +QTableWidget, QTableView { + background-color: #FFFFFF; + alternate-background-color: #F9F9F9; + border: 1px solid #CCCCCC; + gridline-color: #E0E0E0; + selection-background-color: #0078D4; + selection-color: #FFFFFF; +} + +QHeaderView::section { + background-color: #F3F3F3; + border: none; + border-right: 1px solid #CCCCCC; + border-bottom: 1px solid #CCCCCC; + padding: 4px; + font-weight: bold; +} + +/* Checkboxes and Radio Buttons - deliberately omitting ::indicator overrides + to keep native Qt indicators */ +QCheckBox, QRadioButton { + spacing: 8px; +} + +QCheckBox:disabled, QRadioButton:disabled { + color: #A0A0A0; +} + +/* Group Boxes */ +QGroupBox { + border: 1px solid #CCCCCC; + border-radius: 4px; + margin-top: 1.2em; + padding-top: 0.5em; +} + +QGroupBox::title { + subcontrol-origin: margin; + subcontrol-position: top left; + left: 8px; + padding: 0 4px; + color: #0078D4; + font-weight: bold; +} + +/* Tabs */ +QTabWidget::pane { + border: 1px solid #CCCCCC; + background-color: #FFFFFF; +} + +QTabBar::tab { + background-color: #F3F3F3; + border: 1px solid #CCCCCC; + border-bottom: none; + padding: 6px 16px; + margin-right: 2px; +} + +QTabBar::tab:selected { + background-color: #FFFFFF; + border-top: 2px solid #0078D4; +} + +QTabBar::tab:hover:!selected { + background-color: #E5E5E5; +} + +/* Scrollbars */ +QScrollBar:vertical { + border: none; + background: #F3F3F3; + width: 14px; + margin: 0px 0px 0px 0px; +} + +QScrollBar::handle:vertical { + background: #CCCCCC; + min-height: 20px; + border-radius: 7px; + margin: 2px; +} + +QScrollBar::handle:vertical:hover { + background: #999999; +} + +QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical { + border: none; + background: none; +} + +QScrollBar:horizontal { + border: none; + background: #F3F3F3; + height: 14px; + margin: 0px 0px 0px 0px; +} + +QScrollBar::handle:horizontal { + background: #CCCCCC; + min-width: 20px; + border-radius: 7px; + margin: 2px; +} + +QScrollBar::handle:horizontal:hover { + background: #999999; +} + +QScrollBar::add-line:horizontal, QScrollBar::sub-line:horizontal { + border: none; + background: none; +} diff --git a/main.py b/main.py index c7f54d0..b075d13 100644 --- a/main.py +++ b/main.py @@ -3556,6 +3556,15 @@ class Payment: if __name__ == "__main__": app = QtWidgets.QApplication(sys.argv) app.setStyle("Fusion") + + # Load and apply QSS style + style_path = Path(__file__).parent / "files" / "style.qss" + if style_path.exists(): + with open(style_path, "r", encoding="utf-8") as f: + app.setStyleSheet(f.read()) + else: + logger.warning(f"Style file not found at {style_path}") + auth = AuthForm() auth.show() auth.ui.label_9.setText(system.database)