fix: restore JumpStyle seek slider and fix fractional truncation bug

- Add JumpStyle(QProxyStyle) to player_header.py so clicking the seek
  bar jumps to the clicked position (lost during player_header extraction)
- Fix _on_slider_user_action: int(frac) always truncated to 0
  (e.g. 500/1000=0.5 → int(0.5)=0), now emits raw value 0-1000
- Fix _on_user_seek_frac: properly converts slider value (0-1000) to
  playback position with bounds clamping
This commit is contained in:
Maksim Totmin 2026-06-01 20:09:52 +07:00
parent a66446120c
commit aaaf354c9d
2 changed files with 17 additions and 5 deletions

View File

@ -379,8 +379,13 @@ class MainWindow(QMainWindow):
if self.audio_output: if self.audio_output:
self.audio_output.setVolume(value / 100.0) self.audio_output.setVolume(value / 100.0)
def _on_user_seek_frac(self, frac: int): def _on_user_seek_frac(self, value: int):
self.player.setPosition(int(frac * self.player.duration())) duration = self.player.duration()
if duration <= 0:
return
new_pos = int(value / 1000.0 * duration)
new_pos = max(0, min(duration - 1, new_pos))
self.player.setPosition(new_pos)
def _on_player_position(self, position: int): def _on_player_position(self, position: int):
duration = self.player.duration() duration = self.player.duration()

View File

@ -1,5 +1,5 @@
from PyQt6.QtWidgets import ( from PyQt6.QtWidgets import (
QWidget, QHBoxLayout, QVBoxLayout, QPushButton, QLabel, QSlider, QGroupBox, QStyle, QWidget, QHBoxLayout, QVBoxLayout, QPushButton, QLabel, QSlider, QGroupBox, QStyle, QProxyStyle,
) )
from PyQt6.QtCore import Qt, pyqtSignal from PyQt6.QtCore import Qt, pyqtSignal
from PyQt6.QtGui import QPixmap, QColor from PyQt6.QtGui import QPixmap, QColor
@ -11,6 +11,13 @@ def _fmt_time(ms: int) -> str:
return f"{m}:{s:02d}" return f"{m}:{s:02d}"
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 PlayerHeader(QGroupBox): class PlayerHeader(QGroupBox):
prev_requested = pyqtSignal() prev_requested = pyqtSignal()
play_pause_requested = pyqtSignal() play_pause_requested = pyqtSignal()
@ -54,6 +61,7 @@ class PlayerHeader(QGroupBox):
self.time_label_start.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter) self.time_label_start.setAlignment(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)
self.position_slider = QSlider(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.setMinimum(0)
self.position_slider.setMaximum(1000) self.position_slider.setMaximum(1000)
self.position_slider.setValue(0) self.position_slider.setValue(0)
@ -95,8 +103,7 @@ class PlayerHeader(QGroupBox):
layout.addLayout(now_playing_layout) layout.addLayout(now_playing_layout)
def _on_slider_user_action(self): def _on_slider_user_action(self):
frac = self.position_slider.value() / 1000.0 self.position_changed_by_user.emit(self.position_slider.value())
self.position_changed_by_user.emit(int(frac))
def set_cover(self, pixmap: QPixmap = None, tooltip: str = ""): def set_cover(self, pixmap: QPixmap = None, tooltip: str = ""):
if pixmap: if pixmap: