Make MusicMusterSignals a singleton class

Moved into datastructures.py
This commit is contained in:
Keith Edmunds 2023-10-31 08:14:34 +00:00
parent 3557d22c54
commit 734d5cb545
6 changed files with 61 additions and 41 deletions

20
app/datastructures.py Normal file
View File

@ -0,0 +1,20 @@
from PyQt6.QtCore import pyqtSignal, QObject
from helpers import singleton
@singleton
class MusicMusterSignals(QObject):
"""
Class for all MusicMuster signals. See:
- https://zetcode.com/gui/pyqt5/eventssignals/
- https://stackoverflow.com/questions/62654525/
emit-a-signal-from-another-class-to-main-class
and Singleton class at
https://refactoring.guru/design-patterns/singleton/python/example#example-0
"""
enable_escape_signal = pyqtSignal(bool)
set_next_track_signal = pyqtSignal(int, int)
span_cells_signal = pyqtSignal(int, int, int, int)
add_track_to_playlist_signal = pyqtSignal(int, int, int, str)

View File

@ -1,3 +1,4 @@
import functools
import os
import psutil
import shutil
@ -381,6 +382,22 @@ def show_warning(parent: QMainWindow, title: str, msg: str) -> None:
QMessageBox.warning(parent, title, msg, buttons=QMessageBox.StandardButton.Cancel)
def singleton(cls):
"""
Make a class a Singleton class (see
https://realpython.com/primer-on-python-decorators/#creating-singletons)
"""
@functools.wraps(cls)
def wrapper_singleton(*args, **kwargs):
if not wrapper_singleton.instance:
wrapper_singleton.instance = cls(*args, **kwargs)
return wrapper_singleton.instance
wrapper_singleton.instance = None
return wrapper_singleton
def trailing_silence(
audio_segment: AudioSegment,
silence_threshold: int = -50,

View File

@ -69,6 +69,7 @@ import icons_rc # noqa F401
import music
from models import Base, Carts, Playdates, PlaylistRows, Playlists, Settings, Tracks
from config import Config
from datastructures import MusicMusterSignals
from playlists import PlaylistTab
from ui.dlg_cart_ui import Ui_DialogCartEdit # type: ignore
from ui.dlg_TrackSelect_ui import Ui_Dialog # type: ignore
@ -238,20 +239,6 @@ class ImportTrack(QObject):
self.finished.emit(self.playlist)
class MusicMusterSignals(QObject):
"""
Class for all MusicMuster signals. See:
- https://zetcode.com/gui/pyqt5/eventssignals/
- https://stackoverflow.com/questions/62654525/
emit-a-signal-from-another-class-to-main-class
"""
enable_escape_signal = pyqtSignal(bool)
set_next_track_signal = pyqtSignal(int, int)
span_cells_signal = pyqtSignal(int, int, int, int)
add_track_to_playlist_signal = pyqtSignal(int, int, str)
class PlaylistTrack:
"""
Used to provide a single reference point for specific playlist tracks,
@ -349,8 +336,6 @@ class Window(QMainWindow, Ui_MainWindow):
self.previous_track_position: Optional[float] = None
self.selected_plrs: Optional[List[PlaylistRows]] = None
self.signals = MusicMusterSignals()
self.set_main_window_size()
self.lblSumPlaytime = QLabel("")
self.statusbar.addPermanentWidget(self.lblSumPlaytime)
@ -379,6 +364,7 @@ class Window(QMainWindow, Ui_MainWindow):
self.timer10.start(10)
self.timer500.start(500)
self.timer1000.start(1000)
self.signals = MusicMusterSignals()
self.connect_signals_slots()
def about(self) -> None:
@ -731,7 +717,6 @@ class Window(QMainWindow, Ui_MainWindow):
playlist_tab = PlaylistTab(
musicmuster=self,
playlist_id=playlist.id,
signals=self.signals,
)
idx = self.tabPlaylist.addTab(playlist_tab, playlist.name)
self.tabPlaylist.setCurrentIndex(idx)
@ -1065,7 +1050,7 @@ class Window(QMainWindow, Ui_MainWindow):
with Session() as session:
dlg = TrackSelectDialog(
session=session,
signals=self.signals,
new_row_number=self.active_tab().get_selected_row_number(),
playlist_id=self.active_tab().playlist_id,
)
dlg.exec()
@ -1923,7 +1908,7 @@ class TrackSelectDialog(QDialog):
def __init__(
self,
session: scoped_session,
signals: MusicMusterSignals,
new_row_number: int,
playlist_id: int,
*args,
**kwargs,
@ -1934,7 +1919,7 @@ class TrackSelectDialog(QDialog):
super().__init__(*args, **kwargs)
self.session = session
self.signals = signals
self.new_row_number = new_row_number
self.playlist_id = playlist_id
self.ui = Ui_Dialog()
self.ui.setupUi(self)
@ -1946,6 +1931,7 @@ class TrackSelectDialog(QDialog):
self.ui.radioTitle.toggled.connect(self.title_artist_toggle)
self.ui.searchString.textEdited.connect(self.chars_typed)
self.track: Optional[Tracks] = None
self.signals = MusicMusterSignals()
record = Settings.get_int_settings(self.session, "dbdialog_width")
width = record.f_int or 800
@ -1974,7 +1960,9 @@ class TrackSelectDialog(QDialog):
track_id = None
if track:
track_id = track.id
self.signals.add_track_to_playlist_signal.emit(self.playlist_id, track_id, note)
self.signals.add_track_to_playlist_signal.emit(
self.playlist_id, self.new_row_number, track_id, note
)
def add_selected_and_close(self) -> None:
"""Handle Add and Close button"""

View File

@ -19,14 +19,15 @@ from PyQt6.QtGui import (
)
from config import Config
from playlists import PlaylistTab
from datastructures import MusicMusterSignals
from dbconfig import scoped_session, Session
from helpers import (
file_is_unreadable,
)
from models import PlaylistRows, Tracks
if TYPE_CHECKING:
from musicmuster import MusicMusterSignals
HEADER_NOTES_COLUMN = 1
class Col(Enum):
@ -98,18 +99,15 @@ class PlaylistModel(QAbstractTableModel):
def __init__(
self,
playlist: PlaylistTab,
playlist_id: int,
signals: "MusicMusterSignals",
*args,
**kwargs,
):
self.playlist = playlist
self.playlist_id = playlist_id
self.signals = signals
super().__init__(*args, **kwargs)
self.playlist_rows: dict[int, PlaylistRowData] = {}
self.signals = MusicMusterSignals()
self.signals.add_track_to_playlist_signal.connect(self.add_track)

View File

@ -36,8 +36,9 @@ from PyQt6.QtWidgets import (
QStyleOption,
)
from config import Config
from datastructures import MusicMusterSignals
from dbconfig import Session, scoped_session
from config import Config
from helpers import (
ask_yes_no,
file_is_unreadable,
@ -48,10 +49,8 @@ from helpers import (
set_track_metadata,
)
from log import log
from models import Playlists, PlaylistRows, Settings, Tracks, NoteColours
import playlistmodel
from playlistmodel import PlaylistModel
if TYPE_CHECKING:
from musicmuster import Window, MusicMusterSignals
@ -66,9 +65,9 @@ class EscapeDelegate(QStyledItemDelegate):
- checks with user before abandoning edit on Escape
"""
def __init__(self, parent, signals: "MusicMusterSignals") -> None:
def __init__(self, parent) -> None:
super().__init__(parent)
self.signals = signals
self.signals = MusicMusterSignals()
def createEditor(
self,
@ -80,7 +79,7 @@ class EscapeDelegate(QStyledItemDelegate):
Intercept createEditor call and make row just a little bit taller
"""
self.signals.enable_escape_signal.emit(False)
signals.enable_escape_signal.emit(False)
if isinstance(self.parent(), PlaylistTab):
p = cast(PlaylistTab, self.parent())
if isinstance(index.data(), str):
@ -156,17 +155,15 @@ class PlaylistTab(QTableView):
self,
musicmuster: "Window",
playlist_id: int,
signals: "MusicMusterSignals",
) -> None:
super().__init__()
# Save passed settings
self.musicmuster = musicmuster
self.playlist_id = playlist_id
self.signals = signals
# Set up widget
self.setItemDelegate(EscapeDelegate(self, self.signals))
self.setItemDelegate(EscapeDelegate(self))
self.setAlternatingRowColors(True)
self.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection)
self.setSelectionBehavior(QAbstractItemView.SelectionBehavior.SelectRows)
@ -194,6 +191,7 @@ class PlaylistTab(QTableView):
h_header.setStretchLastSection(True)
# self.itemSelectionChanged.connect(self._select_event)
# self.signals.set_next_track_signal.connect(self._reset_next)
self.signals = MusicMusterSignals()
self.signals.span_cells_signal.connect(self._span_cells)
# Call self.eventFilter() for events
@ -205,7 +203,7 @@ class PlaylistTab(QTableView):
# self.edit_cell_type: Optional[int]
# Load playlist rows
self.setModel(playlistmodel.PlaylistModel(self, playlist_id, signals))
self.setModel(PlaylistModel(playlist_id))
self._set_column_widths()
# kae def __repr__(self) -> str:

View File

@ -4,13 +4,12 @@ from app.models import (
from app import playlistmodel
from dbconfig import scoped_session
def create_model_with_playlist_rows(
session: scoped_session, rows: int
) -> "playlistmodel.PlaylistModel":
playlist = Playlists(session, "test playlist")
# Create a model
model = playlistmodel.PlaylistModel(playlist.id, None)
model = playlistmodel.PlaylistModel(playlist.id)
for row in range(rows):
plr = model._insert_row(session, row)
newrow = plr.plr_rownum