From 8684db497fbab77cb02f6b47ea80822df1d49314 Mon Sep 17 00:00:00 2001 From: billypom on debian Date: Sun, 6 Apr 2025 13:44:01 -0400 Subject: [PATCH] ui font editing, artist album title selectable --- README.md | 3 +- main.py | 44 +++++++++++++++++++--- ui.py | 33 ++++++---------- ui.ui | 88 ++++++++++++++++++++----------------------- utils/fft_analyser.py | 5 ++- 5 files changed, 95 insertions(+), 78 deletions(-) diff --git a/README.md b/README.md index da22a5a..ccbca86 100644 --- a/README.md +++ b/README.md @@ -64,5 +64,4 @@ config.ini db/ - allow spectrum analyzer to fall when playback stops or song is paused - ability to delete playlist - automatic "radio" based on artist or genre -- "installer" - put files in /opt? script to install and uninstall... eh -- .deb package? +- jump to currently playing song diff --git a/main.py b/main.py index 225fe0a..0b925a9 100644 --- a/main.py +++ b/main.py @@ -1,6 +1,7 @@ import os import sys import logging +from PyQt5 import QtCore import qdarktheme import typing import traceback @@ -36,7 +37,7 @@ from PyQt5.QtCore import ( QRunnable, ) from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent, QAudioProbe -from PyQt5.QtGui import QClipboard, QCloseEvent, QPixmap, QResizeEvent +from PyQt5.QtGui import QClipboard, QCloseEvent, QFont, QPixmap, QResizeEvent from utils import ( delete_album_art, scan_for_music, @@ -138,35 +139,45 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow): def __init__(self, clipboard): super(ApplicationWindow, self).__init__() - global stopped - stopped = False + + # clipboard good + self.clipboard = clipboard + # Config self.config: ConfigParser = ConfigParser() self.cfg_file = ( Path(user_config_dir(appname="musicpom", appauthor="billypom")) / "config.ini" ) + self.config.read(self.cfg_file) + # Multithreading stuff... self.threadpool = QThreadPool() # UI self.setupUi(self) self.setWindowTitle("musicpom") + + self.setup_fonts() + # self.vLayoutAlbumArt.SetFixedSize() self.status_bar = QStatusBar() self.permanent_status_label = QLabel("Status...") self.status_bar.addPermanentWidget(self.permanent_status_label) self.setStatusBar(self.status_bar) + self.selected_song_filepath: str | None = None self.current_song_filepath: str | None = None self.current_song_metadata: ID3 | dict | None = None self.current_song_album_art: bytes | None = None + + # widget bits self.album_art_scene: QGraphicsScene = QGraphicsScene() - self.config.read(self.cfg_file) self.player: QMediaPlayer = QMediaPlayer() # Audio player object self.probe: QAudioProbe = QAudioProbe() # Gets audio data self.audio_visualizer: AudioVisualizer = AudioVisualizer(self.player) self.timer = QTimer(self) # Audio timing things - self.clipboard = clipboard + + # sharing functions with other classes and that self.tableView.load_qapp(self) self.albumGraphicsView.load_qapp(self) @@ -356,6 +367,27 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow): # | | # |____________________| + def setup_fonts(self): + """Initializes font sizes and behaviors for various UI components""" + font: QFont = QFont() + font.setPointSize(16) + font.setBold(True) + self.artistLabel: QLabel + self.artistLabel.setFont(font) + self.artistLabel.setTextInteractionFlags(QtCore.Qt.TextInteractionFlag.TextSelectableByMouse) + + font: QFont = QFont() + font.setPointSize(16) + font.setBold(False) + self.titleLabel.setFont(font) + self.titleLabel.setTextInteractionFlags(QtCore.Qt.TextInteractionFlag.TextSelectableByMouse) + + font: QFont = QFont() + font.setPointSize(16) + font.setItalic(True) + self.albumLabel.setFont(font) + self.albumLabel.setTextInteractionFlags(QtCore.Qt.TextInteractionFlag.TextSelectableByMouse) + def load_config(self) -> None: """does what it says""" cfg_file = ( @@ -479,7 +511,7 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow): def move_slider(self) -> None: """Handles moving the playback slider""" - if stopped: + if self.player.state() == QMediaPlayer.State.StoppedState: return else: if self.playbackSlider.isSliderDown(): diff --git a/ui.py b/ui.py index 935e09f..65e578c 100644 --- a/ui.py +++ b/ui.py @@ -160,6 +160,11 @@ class Ui_MainWindow(object): self.hLayoutControls2 = QtWidgets.QHBoxLayout() self.hLayoutControls2.setSpacing(6) self.hLayoutControls2.setObjectName("hLayoutControls2") + self.hLayoutVolume = QtWidgets.QHBoxLayout() + self.hLayoutVolume.setObjectName("hLayoutVolume") + self.volumeLabel = QtWidgets.QLabel(self.centralwidget) + self.volumeLabel.setObjectName("volumeLabel") + self.hLayoutVolume.addWidget(self.volumeLabel) self.volumeSlider = QtWidgets.QSlider(self.centralwidget) self.volumeSlider.setMinimum(-1) self.volumeSlider.setMaximum(101) @@ -167,43 +172,29 @@ class Ui_MainWindow(object): self.volumeSlider.setOrientation(QtCore.Qt.Horizontal) self.volumeSlider.setTickPosition(QtWidgets.QSlider.TicksAbove) self.volumeSlider.setObjectName("volumeSlider") - self.hLayoutControls2.addWidget(self.volumeSlider) - self.volumeLabel = QtWidgets.QLabel(self.centralwidget) - self.volumeLabel.setObjectName("volumeLabel") - self.hLayoutControls2.addWidget(self.volumeLabel) + self.hLayoutVolume.addWidget(self.volumeSlider) + self.hLayoutControls2.addLayout(self.hLayoutVolume) + spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.hLayoutControls2.addItem(spacerItem2) self.hLayoutSongDetails = QtWidgets.QHBoxLayout() self.hLayoutSongDetails.setObjectName("hLayoutSongDetails") self.artistLabel = QtWidgets.QLabel(self.centralwidget) - font = QtGui.QFont() - font.setPointSize(24) - font.setBold(True) - font.setWeight(75) - self.artistLabel.setFont(font) self.artistLabel.setObjectName("artistLabel") self.hLayoutSongDetails.addWidget(self.artistLabel) self.titleLabel = QtWidgets.QLabel(self.centralwidget) - font = QtGui.QFont() - font.setPointSize(18) - self.titleLabel.setFont(font) self.titleLabel.setObjectName("titleLabel") self.hLayoutSongDetails.addWidget(self.titleLabel) self.albumLabel = QtWidgets.QLabel(self.centralwidget) - font = QtGui.QFont() - font.setPointSize(16) - font.setBold(False) - font.setItalic(True) - font.setWeight(50) - self.albumLabel.setFont(font) self.albumLabel.setObjectName("albumLabel") self.hLayoutSongDetails.addWidget(self.albumLabel) self.hLayoutControls2.addLayout(self.hLayoutSongDetails) - spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) - self.hLayoutControls2.addItem(spacerItem2) + spacerItem3 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + self.hLayoutControls2.addItem(spacerItem3) self.pushButton = QtWidgets.QPushButton(self.centralwidget) self.pushButton.setObjectName("pushButton") self.hLayoutControls2.addWidget(self.pushButton) self.hLayoutControls2.setStretch(0, 1) - self.hLayoutControls2.setStretch(3, 4) + self.hLayoutControls2.setStretch(2, 5) self.hLayoutControls2.setStretch(4, 1) self.verticalLayout.addLayout(self.hLayoutControls2) self.verticalLayout_3.addLayout(self.verticalLayout) diff --git a/ui.ui b/ui.ui index e665c9c..97473a7 100644 --- a/ui.ui +++ b/ui.ui @@ -273,69 +273,63 @@ - + 6 - - - -1 - - - 101 - - - 50 - + + + + + 50 + + + + + + + -1 + + + 101 + + + 50 + + + Qt::Horizontal + + + QSlider::TicksAbove + + + + + + + Qt::Horizontal - - QSlider::TicksAbove + + + 40 + 20 + - - - - - - 50 - - + - - - - 24 - 75 - true - - - + - - - - 18 - - - + - - - - 16 - 50 - true - false - - - + diff --git a/utils/fft_analyser.py b/utils/fft_analyser.py index 762b8ac..127f53e 100644 --- a/utils/fft_analyser.py +++ b/utils/fft_analyser.py @@ -7,6 +7,7 @@ from pydub import AudioSegment import numpy as np from scipy.ndimage.filters import gaussian_filter1d from logging import debug, info +from PyQt5.QtMultimedia import QMediaPlayer class FFTAnalyser(QtCore.QThread): @@ -117,8 +118,8 @@ class FFTAnalyser(QtCore.QThread): for n, amp in enumerate(point_samples): # amp *= 2 if self.player.state() in ( - self.player.PausedState, - self.player.StoppedState, + QMediaPlayer.State.PausedState, + QMediaPlayer.State.StoppedState ): # More aggressive decay when no audio is playing self.points[n] *= 0.7 # Faster fade out when paused/stopped