refactor: replace JumpSlider subclass with QProxyStyle, clamp slider seek bounds

This commit is contained in:
Maksim Totmin 2026-06-01 08:57:55 +07:00
parent d153d69bfd
commit 9cdb27dace

View File

@ -16,7 +16,7 @@ from PyQt6.QtWidgets import (
QComboBox, QCheckBox, QTabWidget, QListWidget, QListWidgetItem,
QMessageBox, QSpinBox, QGroupBox, QHeaderView,
QTableWidget, QTableWidgetItem, QSlider, QMenu, QDialog, QStyle,
QStyleOptionSlider
QProxyStyle
)
from PyQt6.QtCore import Qt, QThread, pyqtSignal, QUrl, QTimer
from PyQt6.QtGui import QPixmap, QColor
@ -286,29 +286,11 @@ class WorkerThread(QThread):
self.wait()
class JumpSlider(QSlider):
def _jump_to_pos(self, x):
opt = QStyleOptionSlider()
self.initStyleOption(opt)
gr = self.style().subControlRect(
QStyle.ComplexControl.CC_Slider, opt,
QStyle.SubControl.SC_SliderGroove, self
)
val = QStyle.sliderValueFromPosition(
self.minimum(), self.maximum(),
int(x) - gr.x(), gr.width()
)
self.setValue(val)
def mousePressEvent(self, ev):
if ev.button() == Qt.MouseButton.LeftButton:
self._jump_to_pos(ev.position().x())
super().mousePressEvent(ev)
def mouseMoveEvent(self, ev):
if ev.buttons() & Qt.MouseButton.LeftButton:
self._jump_to_pos(ev.position().x())
super().mouseMoveEvent(ev)
class JumpStyle(QProxyStyle):
def styleHint(self, hint, opt=None, widget=None, returnData=None):
if hint == QStyle.StyleHint.SH_Slider_AbsoluteSetButtons:
return Qt.MouseButton.LeftButton.value
return super().styleHint(hint, opt, widget, returnData)
class MainWindow(QMainWindow):
@ -576,7 +558,8 @@ class MainWindow(QMainWindow):
self.time_label_start.setFixedWidth(40)
self.time_label_start.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)
self.position_slider = JumpSlider(Qt.Orientation.Horizontal)
self.position_slider = QSlider(Qt.Orientation.Horizontal)
self.position_slider.setStyle(JumpStyle(self.position_slider.style()))
self.position_slider.setMinimum(0)
self.position_slider.setMaximum(1000)
self.position_slider.setValue(0)
@ -1039,9 +1022,10 @@ class MainWindow(QMainWindow):
def _on_slider_pressed(self):
if self.player:
self.player.setPosition(
int(self.position_slider.value() / 1000.0 * self.player.duration())
)
duration = self.player.duration()
new_pos = int(self.position_slider.value() / 1000.0 * duration)
new_pos = max(0, min(duration - 1, new_pos))
self.player.setPosition(new_pos)
def _on_slider_released(self):
pass