Files
krowlog/ScaledScrollBar.py
Andreas Huber f0555df0a9 switch from PyQt6 to PySide6
PySide6 uses LGPL instead of GPL, which is much nicer to work with.
2022-01-30 10:50:31 +01:00

55 lines
1.9 KiB
Python

import math
from PySide6.QtWidgets import QScrollBar
from PySide6.QtCore import Signal
import logging
log = logging.getLogger("scaledScrollBar")
class ScaledScrollBar(QScrollBar):
is_huge = False
scaledValueChanged = Signal(str)
"""Signal emitted when the scroll bar value changes.
**Note**: The value is a string and must be parsed into an int.
QT's signal api only supports 32bit integers. Ints larger
than 2**32-1 will overflow. Probably because there is some C/C++
code involved. We work around this by converting the python int
into a string."""
def __init__(self):
super(ScaledScrollBar, self).__init__()
self.real_maximum = self.maximum()
super().valueChanged.connect(self._valueChanged)
def setValue(self, value: int) -> None:
if self.is_huge:
real_position = value / self.real_maximum
super().setValue(round(self.maximum() * real_position))
else:
super().setValue(value)
def setMaximum(self, maximum: int) -> None:
if maximum > 2 ** 31:
new_maximum = 1000 * math.log2(maximum)
super().setMaximum(math.ceil(new_maximum))
self.real_maximum = maximum
if not self.is_huge:
old_position = self.value() / self.maximum()
self.setValue(round(new_maximum * old_position))
self.is_huge = True
else:
self.is_huge = False
super().setMaximum(maximum)
def _valueChanged(self, value: int):
if self.is_huge:
real_value = (value / self.maximum()) * self.real_maximum
# print("scaled value changed: %d -> %d (%f)" % (value, real_value, value / self.maximum()))
self.scaledValueChanged.emit(str(int(real_value)))
else:
self.scaledValueChanged.emit(str(int(value)))