From 7f5e7710e5cbfff20acf78ead4668f7a01e471ab Mon Sep 17 00:00:00 2001 From: Xarkam Date: Wed, 4 Mar 2026 12:46:56 +0100 Subject: [PATCH] Wip style QSlider --- .../slidergroovecolorstyle.cpython-314.pyc | Bin 0 -> 11578 bytes mainwindow.py | 5 +- mainwindow.ui | 8 +- slidergroovecolorstyle.py | 272 ++++++++++++++++++ styles.qss | 62 ++++ 5 files changed, 345 insertions(+), 2 deletions(-) create mode 100644 __pycache__/slidergroovecolorstyle.cpython-314.pyc create mode 100644 slidergroovecolorstyle.py diff --git a/__pycache__/slidergroovecolorstyle.cpython-314.pyc b/__pycache__/slidergroovecolorstyle.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b12f886f04de7055cb5db2ba6f3d47d743fdcca1 GIT binary patch literal 11578 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 literal 0 HcmV?d00001 diff --git a/mainwindow.py b/mainwindow.py index 4d14cb8..af0435b 100644 --- a/mainwindow.py +++ b/mainwindow.py @@ -3,9 +3,11 @@ import os from PyQt6 import QtGui, QtWidgets from PyQt6 import uic from PyQt6.QtCore import Qt -from PyQt6.QtGui import QFontDatabase, QFont +from PyQt6.QtGui import QFontDatabase, QFont, QColor from PyQt6.QtWidgets import QApplication, QMainWindow +from slidergroovecolorstyle import ThinSubPageLineStyle, ThinAddPageLineStyle + # Compile resources.qrc into resources_rc.py # rcc -g python resources.qrc -o resources_rc.py @@ -52,6 +54,7 @@ class MainWindow(QMainWindow): # Adjust UI self.maintitle_label.setFont(QFont(font_family, 38)) self.subtitle_label.setStyleSheet("color: rgb(163, 177, 198)") + #self.horizontalSlider.setStyle(ThinAddPageLineStyle(app.style(), QColor("#2196F3"))) if NO_STAFF : self.staff_btn.hide() diff --git a/mainwindow.ui b/mainwindow.ui index c4d3df4..4ccb39b 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -448,14 +448,20 @@ - true + false + + 20 + Qt::Orientation::Horizontal + + false + diff --git a/slidergroovecolorstyle.py b/slidergroovecolorstyle.py new file mode 100644 index 0000000..2773306 --- /dev/null +++ b/slidergroovecolorstyle.py @@ -0,0 +1,272 @@ +from PyQt6.QtCore import Qt +from PyQt6.QtWidgets import ( + QSlider, QProxyStyle, QStyle +) +from PyQt6.QtGui import QColor + +class SliderGrooveColorStyle(QProxyStyle): + def __init__(self, base_style=None, groove_color=QColor("lightblue")): + super().__init__(base_style) + self.groove_color = groove_color + + def drawComplexControl(self, control, option, painter, widget=None): + if control == QStyle.ComplexControl.CC_Slider and isinstance(widget, QSlider): + + # Récupérer la zone du groove + groove_rect = self.subControlRect( + QStyle.ComplexControl.CC_Slider, + option, + QStyle.SubControl.SC_SliderGroove, + widget + ) + + # Dessiner notre fond + painter.save() + painter.setBrush(self.groove_color) + painter.setPen(Qt.PenStyle.NoPen) + painter.drawRect(groove_rect) + painter.restore() + + # Puis laisser Qt dessiner normalement (handle etc.) + super().drawComplexControl(control, option, painter, widget) + return + + super().drawComplexControl(control, option, painter, widget) + +class SliderSubPageColorStyle(QProxyStyle): + def __init__(self, base_style=None, color=QColor("#4CAF50")): + super().__init__(base_style) + self.color = color + + def drawComplexControl(self, control, option, painter, widget=None): + if control == QStyle.ComplexControl.CC_Slider and isinstance(widget, QSlider): + + # Laisser Qt dessiner le slider normalement + super().drawComplexControl(control, option, painter, widget) + + # Récupérer les rectangles du groove et du handle + groove_rect = self.subControlRect( + control, + option, + QStyle.SubControl.SC_SliderGroove, + widget + ) + + handle_rect = self.subControlRect( + control, + option, + QStyle.SubControl.SC_SliderHandle, + widget + ) + + painter.save() + painter.setBrush(self.color) + painter.setPen(Qt.PenStyle.NoPen) + + if widget.orientation() == Qt.Orientation.Horizontal: + # Partie avant le handle (gauche → centre du handle) + sub_rect = groove_rect.adjusted( + 0, + 0, + handle_rect.center().x() - groove_rect.right(), + 0 + ) + else: + # Vertical (bas → centre du handle) + sub_rect = groove_rect.adjusted( + 0, + handle_rect.center().y() - groove_rect.bottom(), + 0, + 0 + ) + + painter.drawRect(sub_rect) + painter.restore() + + return + + super().drawComplexControl(control, option, painter, widget) + +class SliderAddPageColorStyle(QProxyStyle): + def __init__(self, base_style=None, color=QColor("#FF9800")): + super().__init__(base_style) + self.color = color + + def drawComplexControl(self, control, option, painter, widget=None): + if control == QStyle.ComplexControl.CC_Slider and isinstance(widget, QSlider): + + # Récupérer groove + handle + groove_rect = self.subControlRect( + control, + option, + QStyle.SubControl.SC_SliderGroove, + widget + ) + + handle_rect = self.subControlRect( + control, + option, + QStyle.SubControl.SC_SliderHandle, + widget + ) + + painter.save() + painter.setBrush(self.color) + painter.setPen(Qt.PenStyle.NoPen) + + if widget.orientation() == Qt.Orientation.Horizontal: + # Partie après le handle (centre → fin) + add_rect = groove_rect.adjusted( + handle_rect.center().x() - groove_rect.left(), + 0, + 0, + 0 + ) + else: + # Vertical (centre → haut) + add_rect = groove_rect.adjusted( + 0, + 0, + 0, + handle_rect.center().y() - groove_rect.top() + ) + + painter.drawRect(add_rect) + painter.restore() + + # IMPORTANT : Qt dessine ensuite le handle par-dessus + super().drawComplexControl(control, option, painter, widget) + return + + super().drawComplexControl(control, option, painter, widget) + +class ThinAddPageLineStyle(QProxyStyle): + def __init__(self, base_style=None, color=QColor("#E91E63")): + super().__init__(base_style) + self.color = color + + def drawComplexControl(self, control, option, painter, widget=None): + if control == QStyle.ComplexControl.CC_Slider and isinstance(widget, QSlider): + + groove_rect = self.subControlRect( + control, + option, + QStyle.SubControl.SC_SliderGroove, + widget + ) + + handle_rect = self.subControlRect( + control, + option, + QStyle.SubControl.SC_SliderHandle, + widget + ) + + painter.save() + painter.setBrush(self.color) + painter.setPen(Qt.PenStyle.NoPen) + + if widget.orientation() == Qt.Orientation.Horizontal: + # Épaisseur fine (2 px) + thickness = 2 + + y = groove_rect.center().y() - thickness // 2 + + add_rect = groove_rect.adjusted( + handle_rect.center().x() - groove_rect.left(), + 0, + 0, + 0 + ) + + add_rect.setTop(y) + add_rect.setHeight(thickness) + + else: + thickness = 2 + + x = groove_rect.center().x() - thickness // 2 + + add_rect = groove_rect.adjusted( + 0, + 0, + 0, + handle_rect.center().y() - groove_rect.top() + ) + + add_rect.setLeft(x) + add_rect.setWidth(thickness) + + painter.drawRect(add_rect) + painter.restore() + + # Dessiner ensuite le slider normalement (handle au-dessus) + super().drawComplexControl(control, option, painter, widget) + return + + super().drawComplexControl(control, option, painter, widget) + +class ThinSubPageLineStyle(QProxyStyle): + def __init__(self, base_style=None, color=QColor("#4CAF50")): + super().__init__(base_style) + self.color = color + + def drawComplexControl(self, control, option, painter, widget=None): + if control == QStyle.ComplexControl.CC_Slider and isinstance(widget, QSlider): + + groove_rect = self.subControlRect( + control, + option, + QStyle.SubControl.SC_SliderGroove, + widget + ) + + handle_rect = self.subControlRect( + control, + option, + QStyle.SubControl.SC_SliderHandle, + widget + ) + + painter.save() + painter.setBrush(self.color) + painter.setPen(Qt.PenStyle.NoPen) + + # Épaisseur fine (ajuste si besoin) + thickness = 2 + + if widget.orientation() == Qt.Orientation.Horizontal: + + y = groove_rect.center().y() - thickness // 2 + + sub_rect = groove_rect.adjusted( + 0, + 0, + handle_rect.center().x() - groove_rect.right(), + 0 + ) + + sub_rect.setTop(y) + sub_rect.setHeight(thickness) + + else: + x = groove_rect.center().x() - thickness // 2 + + sub_rect = groove_rect.adjusted( + 0, + handle_rect.center().y() - groove_rect.bottom(), + 0, + 0 + ) + + sub_rect.setLeft(x) + sub_rect.setWidth(thickness) + + painter.drawRect(sub_rect) + painter.restore() + + # Qt redessine le slider (handle au-dessus) + super().drawComplexControl(control, option, painter, widget) + return + + super().drawComplexControl(control, option, painter, widget) \ No newline at end of file diff --git a/styles.qss b/styles.qss index dbba172..2d398b6 100644 --- a/styles.qss +++ b/styles.qss @@ -34,3 +34,65 @@ QTextEdit#info_text { background-color: transparent; border: none; } + +/* +QSlider::groove:horizontal { + border: 1px solid #262626; + height: 10px; +} +QSlider::handle:horizontal { + background: rgb(236, 127, 43); + border: 1px solid rgb(236, 127, 43); + width: 23px; + border-radius: 3px; + height: 100px; + margin: -24px -12px; +} + +QSlider::sub-page:horizontal{ + border:0px; + border-radius:6px; + background:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 #12b9ff, stop: 1.0 #015eea); +} + +QSlider::add-page:horizontal{ + border:0px; + border-radius:6px; + background:qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,stop: 0 rgb(146, 149, 150), stop: 1.0 rgb(253, 254, 254)); +} +*/ + +QSlider::groove:horizontal { + border: 1px inset #1C1C1C; + height: 6px; + border-radius: 3px; +} + +QSlider::groove:horizontal { + border: 1px inset #1C1C1C; + height: 6px; + border-radius: 3px; +} + +QSlider::sub-page:horizontal { + background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #12b9ff, stop: 1.0 #015eea); + border: 1px inset #1C1C1C; + border-radius: 3px; +} + +/* groove background on right of slider */ +QSlider::add-page:horizontal { + background: #7D7D7D; + border: 1px outset #1C1C1C; + border-radius: 3px; +} + +QSlider::handle:horizontal { + background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 rgb(241, 160, 61), stop:1 rgb(233, 111, 29)); + border: 1px solid rgb(213, 125, 2); + width: 12px; + height: 10px; + margin-top: -8px; + margin-bottom: -8px; + border-radius: 2px; +} \ No newline at end of file