From edd8c36c53419a9ca5a18553a7e81f6b47d3dbb3 Mon Sep 17 00:00:00 2001 From: Keith Edmunds Date: Sat, 19 Apr 2025 12:25:29 +0100 Subject: [PATCH] Use signals for setting next track --- app/classes.py | 13 ++++++------- app/music_manager.py | 2 ++ app/musicmuster.py | 31 ++++++++++++++++++++++--------- app/playlistmodel.py | 16 +++++++++++++--- app/playlistrow.py | 33 +++++++++------------------------ app/playlists.py | 2 +- 6 files changed, 53 insertions(+), 44 deletions(-) diff --git a/app/classes.py b/app/classes.py index ab78d9e..7282d99 100644 --- a/app/classes.py +++ b/app/classes.py @@ -244,10 +244,6 @@ class MusicMusterSignals(QObject): # escape there to abandon an edit. enable_escape_signal = pyqtSignal(bool) - # Signals that the next-cued track has changed. Used to update - # playlist headers. - next_track_changed_signal = pyqtSignal() - # Signals that the playlist_id passed should resize all rows. resize_rows_signal = pyqtSignal(int) @@ -277,11 +273,14 @@ class MusicMusterSignals(QObject): # signal_set_next_track takes a PlaylistRow as an argument. We can't # specify that here as it requires us to import PlaylistRow from - # playlistrow.py, which itself imports MusicMusterSignals - - # TBD + # playlistrow.py, which itself imports MusicMusterSignals. It tells + # musicmuster to set the passed track as the next one. signal_set_next_track = pyqtSignal(object) + # Signals that the next-cued track has changed. Used to update + # playlist headers and track timings. + signal_next_track_changed = pyqtSignal() + # Emited when a track starts playing signal_track_started = pyqtSignal(TrackAndPlaylist) diff --git a/app/music_manager.py b/app/music_manager.py index 8281c18..0ba64bc 100644 --- a/app/music_manager.py +++ b/app/music_manager.py @@ -2,6 +2,7 @@ from __future__ import annotations import datetime as dt +import threading from time import sleep @@ -21,6 +22,7 @@ from config import Config import helpers from log import log + class _FadeTrack(QThread): finished = pyqtSignal() diff --git a/app/musicmuster.py b/app/musicmuster.py index 275adb9..0376a29 100755 --- a/app/musicmuster.py +++ b/app/musicmuster.py @@ -101,9 +101,6 @@ class SignalMonitor: self.signals.enable_escape_signal.connect( partial(self.show_signal, "enable_escape_signal ") ) - self.signals.next_track_changed_signal.connect( - partial(self.show_signal, "next_track_changed_signal ") - ) self.signals.resize_rows_signal.connect( partial(self.show_signal, "resize_rows_signal ") ) @@ -140,6 +137,7 @@ class SignalMonitor: self.signals.signal_track_started.connect( partial(self.show_signal, "signal_track_started ") ) + # span_cells_signal is very noisy # self.signals.span_cells_signal.connect( # partial(self.show_signal, "span_cells_signal ") # ) @@ -1659,7 +1657,7 @@ class Window(QMainWindow): """ self.track_sequence.set_next(None) - self.signals.next_track_changed_signal.emit() + self.signals.signal_set_next_track.emit(None) def clear_selection(self, checked: bool = False) -> None: """Clear row selection""" @@ -1741,9 +1739,12 @@ class Window(QMainWindow): self.txtSearch.textChanged.connect(self.search_playlist_text_changed) self.signals.enable_escape_signal.connect(self.enable_escape) - self.signals.next_track_changed_signal.connect(self.update_headers) - self.signals.status_message_signal.connect(self.show_status_message) + self.signals.search_songfacts_signal.connect(self.open_songfacts_browser) + self.signals.search_wikipedia_signal.connect(self.open_wikipedia_browser) self.signals.show_warning_signal.connect(self.show_warning) + self.signals.signal_next_track_changed.connect(self.signal_next_track_changed_handler) + self.signals.signal_set_next_track.connect(self.signal_set_next_track_handler) + self.signals.status_message_signal.connect(self.show_status_message) self.signals.track_ended_signal.connect(self.end_of_track_actions) self.timer10.timeout.connect(self.tick_10ms) @@ -1751,9 +1752,6 @@ class Window(QMainWindow): self.timer100.timeout.connect(self.tick_100ms) self.timer1000.timeout.connect(self.tick_1000ms) - self.signals.search_songfacts_signal.connect(self.open_songfacts_browser) - self.signals.search_wikipedia_signal.connect(self.open_wikipedia_browser) - # @log_call def current_row_or_end(self) -> int: """ @@ -2523,6 +2521,21 @@ class Window(QMainWindow): self._active_tab().scroll_to_top(playlist_track.row_number) + def signal_set_next_track_handler(self, plr: PlaylistRow) -> None: + """ + Handle signal_set_next_track + """ + + self.track_sequence.set_next(plr) + self.signals.signal_next_track_changed.emit() + + def signal_next_track_changed_handler(self) -> None: + """ + Handle next track changed + """ + + self.update_headers() + # @log_call def stop(self, checked: bool = False) -> None: """Stop playing immediately""" diff --git a/app/playlistmodel.py b/app/playlistmodel.py index 8dbddc2..5fce3c7 100644 --- a/app/playlistmodel.py +++ b/app/playlistmodel.py @@ -101,6 +101,7 @@ class PlaylistModel(QAbstractTableModel): self.signals.signal_set_next_row.connect(self.set_next_row) self.signals.signal_track_started.connect(self.track_started) self.signals.track_ended_signal.connect(self.previous_track_ended) + self.signals.signal_next_track_changed.connect(self.signal_next_track_changed_handler) # Populate self.playlist_rows for dto in ds.playlistrows_by_playlist(self.playlist_id): @@ -1303,8 +1304,6 @@ class PlaylistModel(QAbstractTableModel): if self.track_sequence.next: old_next_row = self.track_sequence.next.row_number - self.track_sequence.set_next(plr) - roles = [ Qt.ItemDataRole.BackgroundRole, ] @@ -1314,8 +1313,19 @@ class PlaylistModel(QAbstractTableModel): # only invalidate required roles self.invalidate_row(plr.row_number, roles) - self.signals.next_track_changed_signal.emit() + self.signals.signal_set_next_track.emit(plr) + + def signal_next_track_changed_handler(self) -> None: + """ + Handle next track changed + """ + self.update_track_times() + # Refresh display to show new next track + if self.track_sequence.next: + next_row_number = self.track_sequence.next.row_number + if next_row_number is not None: + self.invalidate_row(next_row_number, [Qt.ItemDataRole.BackgroundRole]) # @log_call def setData( diff --git a/app/playlistrow.py b/app/playlistrow.py index 3d4c091..f77df54 100644 --- a/app/playlistrow.py +++ b/app/playlistrow.py @@ -172,7 +172,9 @@ class PlaylistRow: """ if self.track_id > 0: - raise ApplicationError("Attempting to add track to row with existing track ({self=}") + raise ApplicationError( + "Attempting to add track to row with existing track ({self=}" + ) ds.track_add_to_header(playlistrow_id=self.playlistrow_id, track_id=track_id) @@ -221,28 +223,6 @@ class PlaylistRow: # the change to the database. self.dto.row_number = value - def check_for_end_of_track(self) -> None: - """ - Check whether track has ended. If so, emit track_ended_signal - """ - - if self.start_time is None: - return - - if self.end_of_track_signalled: - return - - if self.music.is_playing(): - return - - self.start_time = None - if self.fade_graph: - self.fade_graph.clear() - # Ensure that player is released - self.music.fade(0) - self.signals.track_ended_signal.emit(self.playlist_id) - self.end_of_track_signalled = True - def drop3db(self, enable: bool) -> None: """ If enable is true, drop output by 3db else restore to full volume @@ -278,7 +258,12 @@ class PlaylistRow: self.start_time = now # Initialise player - self.music.play(self.path, start_time=now, position=position) + self.music.play( + path=self.path, + start_time=now, + playlist_id=self.playlist_id, + position=position, + ) self.end_time = now + dt.timedelta(milliseconds=self.duration) diff --git a/app/playlists.py b/app/playlists.py index 0b5fe09..6e795b0 100644 --- a/app/playlists.py +++ b/app/playlists.py @@ -1142,4 +1142,4 @@ class PlaylistTab(QTableView): self.track_sequence.set_next(None) self.clear_selection() - self.signals.next_track_changed_signal.emit() + self.signals.signal_set_next_track.emit(None)