mirror of
https://github.com/pyapp-kit/superqt.git
synced 2025-12-15 18:50:05 +01:00
update for barColor property
This commit is contained in:
35
README.md
35
README.md
@@ -124,27 +124,30 @@ then you can also target it directly in your style sheet.
|
||||
/* Because QRangeSlider inherits QSlider, it will also inherit styles */
|
||||
QSlider::groove:horizontal {
|
||||
border: 0px;
|
||||
background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #FDE282, stop:1 #EB9A5D);
|
||||
height: 16px;
|
||||
border-radius: 2px;
|
||||
background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #777, stop:1 #aaa);
|
||||
height: 20px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
QSlider::handle:horizontal {
|
||||
background: #271848;
|
||||
border: 1px solid #583856;
|
||||
width: 18px;
|
||||
margin: -2px 0;
|
||||
border-radius: 3px;
|
||||
QSlider::handle {
|
||||
background: qradialgradient(cx:0, cy:0, radius: 1.2, fx:0.5,
|
||||
fy:0.5, stop:0 #eef, stop:1 #000);
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
QSlider::handle:hover {
|
||||
background-color: #2F4F4F;
|
||||
}
|
||||
|
||||
/* "QSlider::sub-page" will style the "bar" area between the QRangeSlider handles */
|
||||
/* "QSlider::sub-page" (which styles the area to the left of the
|
||||
QSlider handle) is the one exception ... */
|
||||
QSlider::sub-page:horizontal {
|
||||
background: #AF5A50;
|
||||
border-radius: 2px;
|
||||
background: #447;
|
||||
border-top-left-radius: 10px;
|
||||
border-bottom-left-radius: 10px;
|
||||
}
|
||||
|
||||
/* for QRangeSlider, use "qproperty-barColor" */
|
||||
QRangeSlider {
|
||||
qproperty-barColor: #447;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -3,31 +3,30 @@ from qtrangeslider.qtcompat import QtCore
|
||||
from qtrangeslider.qtcompat import QtWidgets as QtW
|
||||
|
||||
QSS = """
|
||||
|
||||
QSlider::groove:horizontal {
|
||||
border: 0px;
|
||||
background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #FDE282, stop:1 #EB9A5D);
|
||||
height: 16px;
|
||||
border-radius: 2px;
|
||||
background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #777, stop:1 #aaa);
|
||||
height: 20px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
QSlider::handle:horizontal {
|
||||
background: #271848;
|
||||
border: 1px solid #583856;
|
||||
width: 18px;
|
||||
margin: -2px 0;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
QSlider::handle:hover {
|
||||
background-color: #2F4F4F;
|
||||
QSlider::handle {
|
||||
background: qradialgradient(cx:0, cy:0, radius: 1.2, fx:0.5,
|
||||
fy:0.5, stop:0 #eef, stop:1 #000);
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
QSlider::sub-page:horizontal {
|
||||
background: #AF5A50;
|
||||
border-radius: 2px;
|
||||
background: #447;
|
||||
border-top-left-radius: 10px;
|
||||
border-bottom-left-radius: 10px;
|
||||
}
|
||||
|
||||
QRangeSlider {
|
||||
qproperty-barColor: #447;
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,16 @@ from typing import List, Sequence, Tuple
|
||||
|
||||
from ._style import RangeSliderStyle, update_styles_from_stylesheet
|
||||
from .qtcompat import QtGui
|
||||
from .qtcompat.QtCore import QEvent, QPoint, QPointF, QRect, QRectF, Qt, Signal
|
||||
from .qtcompat.QtCore import (
|
||||
Property,
|
||||
QEvent,
|
||||
QPoint,
|
||||
QPointF,
|
||||
QRect,
|
||||
QRectF,
|
||||
Qt,
|
||||
Signal,
|
||||
)
|
||||
from .qtcompat.QtWidgets import (
|
||||
QApplication,
|
||||
QSlider,
|
||||
@@ -62,9 +71,18 @@ class QRangeSlider(QSlider):
|
||||
|
||||
# color
|
||||
self._style = RangeSliderStyle()
|
||||
self.setStyleSheet("")
|
||||
|
||||
# ############### Public API #######################
|
||||
|
||||
def setStyleSheet(self, styleSheet: str) -> None:
|
||||
# sub-page styles render on top of the lower sliders and don't work here.
|
||||
override = f"""
|
||||
\n{type(self).__name__}::sub-page:horizontal {{background: none}}
|
||||
\n{type(self).__name__}::sub-page:vertical {{background: none}}
|
||||
"""
|
||||
return super().setStyleSheet(styleSheet + override)
|
||||
|
||||
def value(self) -> Tuple[int, ...]:
|
||||
"""Get current value of the widget as a tuple of integers."""
|
||||
return tuple(self._value)
|
||||
@@ -180,6 +198,14 @@ class QRangeSlider(QSlider):
|
||||
opt.sliderPosition = 0
|
||||
return opt
|
||||
|
||||
def _getBarColor(self):
|
||||
return self._style.brush_active or QtGui.QColor()
|
||||
|
||||
def _setBarColor(self, color):
|
||||
self._style.brush_active = color
|
||||
|
||||
barColor = Property(QtGui.QColor, _getBarColor, _setBarColor)
|
||||
|
||||
def _drawBar(self, painter: QStylePainter, opt: QStyleOptionSlider):
|
||||
|
||||
brush = self._style.brush(opt)
|
||||
|
||||
@@ -191,14 +191,29 @@ qradial_pattern = re.compile(
|
||||
re.X,
|
||||
)
|
||||
|
||||
rgba_pattern = re.compile(
|
||||
r"""
|
||||
rgba?\(
|
||||
(?P<r>\d+),\s*
|
||||
(?P<g>\d+),\s*
|
||||
(?P<b>\d+),?\s*(?P<a>\d+)?\)
|
||||
""",
|
||||
re.X,
|
||||
)
|
||||
|
||||
|
||||
def parse_color(color: str) -> Union[str, QGradient]:
|
||||
qc = QColor(color)
|
||||
if qc.isValid():
|
||||
return qc
|
||||
|
||||
match = rgba_pattern.search(color)
|
||||
if match:
|
||||
rgba = [int(x) if x else 255 for x in match.groups()]
|
||||
return QColor(*rgba)
|
||||
|
||||
# try linear gradient:
|
||||
match = qlineargrad_pattern.match(color)
|
||||
match = qlineargrad_pattern.search(color)
|
||||
if match:
|
||||
grad = QLinearGradient(*[float(i) for i in match.groups()[:4]])
|
||||
grad.setColorAt(0, QColor(match.groupdict()["stop0"]))
|
||||
@@ -206,8 +221,7 @@ def parse_color(color: str) -> Union[str, QGradient]:
|
||||
return grad
|
||||
|
||||
# try linear gradient:
|
||||
match = qradial_pattern.match(color)
|
||||
print("match", match.groupdict())
|
||||
match = qradial_pattern.search(color)
|
||||
if match:
|
||||
grad = QRadialGradient(*[float(i) for i in match.groups()[:5]])
|
||||
grad.setColorAt(0, QColor(match.groupdict()["stop0"]))
|
||||
@@ -220,33 +234,31 @@ def parse_color(color: str) -> Union[str, QGradient]:
|
||||
|
||||
def update_styles_from_stylesheet(obj: "QRangeSlider"):
|
||||
qss = obj.styleSheet()
|
||||
p = obj
|
||||
while p.parent():
|
||||
qss = p.styleSheet() + qss
|
||||
p = p.parent()
|
||||
|
||||
parent = obj.parent()
|
||||
while parent is not None:
|
||||
qss = parent.styleSheet() + qss
|
||||
parent = parent.parent()
|
||||
qss = QApplication.instance().styleSheet() + qss
|
||||
|
||||
obj._style.has_stylesheet = False
|
||||
# obj._style.has_stylesheet = False
|
||||
|
||||
# Find bar color
|
||||
# TODO: optional horizontal or vertical
|
||||
match = re.search(r"Slider::sub-page:?([^{\s]*)?\s*{\s*([^}]+)}", qss, re.S)
|
||||
if match:
|
||||
orientation, content = match.groups()
|
||||
for line in reversed(content.splitlines()):
|
||||
bgrd = re.search(r"background(-color)?:\s*([^;]+)", line)
|
||||
if bgrd:
|
||||
color = parse_color(bgrd.groups()[-1])
|
||||
obj._style.brush_active = color
|
||||
# TODO: parse for inactive and disabled
|
||||
obj._style.brush_inactive = color
|
||||
obj._style.brush_disabled = color
|
||||
obj._style.has_stylesheet = True
|
||||
class_name = type(obj).__name__
|
||||
_ss = f"\n{class_name}::sub-page:{orientation}{{background: none}}"
|
||||
# TODO: block double event
|
||||
obj.setStyleSheet(qss + _ss)
|
||||
break
|
||||
# # Find bar color
|
||||
# # TODO: optional horizontal or vertical
|
||||
# match = re.search(r"Slider::sub-page:?([^{\s]*)?\s*{\s*([^}]+)}", qss, re.S)
|
||||
# if match:
|
||||
# orientation, content = match.groups()
|
||||
# for line in reversed(content.splitlines()):
|
||||
# bgrd = re.search(r"background(-color)?:\s*([^;]+)", line)
|
||||
# if bgrd:
|
||||
# color = parse_color(bgrd.groups()[-1])
|
||||
# obj._style.brush_active = color
|
||||
# # TODO: parse for inactive and disabled
|
||||
# obj._style.brush_inactive = color
|
||||
# obj._style.brush_disabled = color
|
||||
# obj._style.has_stylesheet = True
|
||||
# obj.update()
|
||||
# break
|
||||
|
||||
# Find bar height/width
|
||||
for orient, dim in (("horizontal", "height"), ("vertical", "width")):
|
||||
|
||||
Reference in New Issue
Block a user