header widths and dynamic resizing and stuff
This commit is contained in:
parent
f1d018f7ce
commit
753117dacc
@ -24,6 +24,7 @@ from PyQt5.QtWidgets import (
|
|||||||
from PyQt5.QtCore import (
|
from PyQt5.QtCore import (
|
||||||
QItemSelectionModel,
|
QItemSelectionModel,
|
||||||
QSortFilterProxyModel,
|
QSortFilterProxyModel,
|
||||||
|
QTimer,
|
||||||
Qt,
|
Qt,
|
||||||
QModelIndex,
|
QModelIndex,
|
||||||
pyqtSignal,
|
pyqtSignal,
|
||||||
@ -74,13 +75,13 @@ class MusicTable(QTableView):
|
|||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
# why do i need this?
|
# why do i need this?
|
||||||
self.application_window = application_window
|
self.application_window = application_window
|
||||||
self.config = ConfigParser()
|
|
||||||
# Config
|
# Config
|
||||||
cfg_file = (
|
self.config = ConfigParser()
|
||||||
|
self.cfg_file = (
|
||||||
Path(user_config_dir(appname="musicpom", appauthor="billypom"))
|
Path(user_config_dir(appname="musicpom", appauthor="billypom"))
|
||||||
/ "config.ini"
|
/ "config.ini"
|
||||||
)
|
)
|
||||||
_ = self.config.read(cfg_file)
|
_ = self.config.read(self.cfg_file)
|
||||||
debug(f"music table config: {self.config}")
|
debug(f"music table config: {self.config}")
|
||||||
|
|
||||||
# NOTE:
|
# NOTE:
|
||||||
@ -125,7 +126,6 @@ class MusicTable(QTableView):
|
|||||||
# header
|
# header
|
||||||
self.horizontal_header: QHeaderView = self.horizontalHeader()
|
self.horizontal_header: QHeaderView = self.horizontalHeader()
|
||||||
assert self.horizontal_header is not None # i hate look at linting errors
|
assert self.horizontal_header is not None # i hate look at linting errors
|
||||||
self.horizontal_header.setStretchLastSection(False)
|
|
||||||
self.horizontal_header.setSectionResizeMode(QHeaderView.Interactive)
|
self.horizontal_header.setSectionResizeMode(QHeaderView.Interactive)
|
||||||
# dumb vertical estupido
|
# dumb vertical estupido
|
||||||
self.vertical_header: QHeaderView = self.verticalHeader()
|
self.vertical_header: QHeaderView = self.verticalHeader()
|
||||||
@ -142,7 +142,6 @@ class MusicTable(QTableView):
|
|||||||
# Final actions
|
# Final actions
|
||||||
# self.load_music_table()
|
# self.load_music_table()
|
||||||
self.setup_keyboard_shortcuts()
|
self.setup_keyboard_shortcuts()
|
||||||
self.load_header_widths()
|
|
||||||
|
|
||||||
# _________________
|
# _________________
|
||||||
# | |
|
# | |
|
||||||
@ -165,11 +164,26 @@ class MusicTable(QTableView):
|
|||||||
"""
|
"""
|
||||||
self.focusLeaveSignal.emit()
|
self.focusLeaveSignal.emit()
|
||||||
|
|
||||||
|
|
||||||
def resizeEvent(self, e: typing.Optional[QResizeEvent]) -> None:
|
def resizeEvent(self, e: typing.Optional[QResizeEvent]) -> None:
|
||||||
"""Do something when the QTableView is resized"""
|
"""
|
||||||
|
Do something when the QTableView is resized
|
||||||
|
We will recalculate column widths based on the new table width,
|
||||||
|
retaining the ratio of the original column widths.
|
||||||
|
"""
|
||||||
|
super().resizeEvent(e)
|
||||||
if e is None:
|
if e is None:
|
||||||
raise Exception
|
raise Exception
|
||||||
super().resizeEvent(e)
|
self.load_header_widths(self.saved_column_ratios)
|
||||||
|
|
||||||
|
def showEvent(self, a0):
|
||||||
|
# Restore scroll position
|
||||||
|
super().showEvent(a0)
|
||||||
|
# widths = []
|
||||||
|
# for _ in self.saved_column_ratios:
|
||||||
|
# widths.append('0.001')
|
||||||
|
# self.load_header_widths(widths)
|
||||||
|
QTimer.singleShot(0, lambda: self.load_header_widths(self.saved_column_ratios))
|
||||||
|
|
||||||
def paintEvent(self, e):
|
def paintEvent(self, e):
|
||||||
"""Override paint event to highlight the current cell"""
|
"""Override paint event to highlight the current cell"""
|
||||||
@ -267,7 +281,7 @@ class MusicTable(QTableView):
|
|||||||
_ = worker.signals.signal_result.connect(self.on_get_audio_files_recursively_finished)
|
_ = worker.signals.signal_result.connect(self.on_get_audio_files_recursively_finished)
|
||||||
_ = worker.signals.signal_finished.connect(self.load_music_table)
|
_ = worker.signals.signal_finished.connect(self.load_music_table)
|
||||||
if self.qapp:
|
if self.qapp:
|
||||||
threadpool = self.qapp.threadpool
|
threadpool = self.qapp.threadpool # type: ignore
|
||||||
threadpool.start(worker)
|
threadpool.start(worker)
|
||||||
if files:
|
if files:
|
||||||
self.add_files_to_library(files)
|
self.add_files_to_library(files)
|
||||||
@ -327,9 +341,6 @@ class MusicTable(QTableView):
|
|||||||
else: # Default behavior
|
else: # Default behavior
|
||||||
super().keyPressEvent(e)
|
super().keyPressEvent(e)
|
||||||
|
|
||||||
def showEvent(self, a0):
|
|
||||||
# Restore scroll position
|
|
||||||
super().showEvent(a0)
|
|
||||||
|
|
||||||
# ____________________
|
# ____________________
|
||||||
# | |
|
# | |
|
||||||
@ -370,8 +381,8 @@ class MusicTable(QTableView):
|
|||||||
col_count = self.model2.columnCount()
|
col_count = self.model2.columnCount()
|
||||||
qtableview_width = self.size().width()
|
qtableview_width = self.size().width()
|
||||||
sum_of_cols = self.horizontal_header.length()
|
sum_of_cols = self.horizontal_header.length()
|
||||||
debug(f'qtable_width: {qtableview_width}')
|
# debug(f'qtable_width: {qtableview_width}')
|
||||||
debug(f'sum of cols: {sum_of_cols}')
|
# debug(f'sum of cols: {sum_of_cols}')
|
||||||
|
|
||||||
if sum_of_cols != qtableview_width: # check for discrepancy
|
if sum_of_cols != qtableview_width: # check for discrepancy
|
||||||
if logicalIndex < col_count: # if not the last header
|
if logicalIndex < col_count: # if not the last header
|
||||||
@ -448,6 +459,55 @@ class MusicTable(QTableView):
|
|||||||
# | |
|
# | |
|
||||||
# |____________________|
|
# |____________________|
|
||||||
|
|
||||||
|
def get_current_header_width_ratios(self) -> list[str]:
|
||||||
|
"""
|
||||||
|
Get the current header widths, as ratios
|
||||||
|
"""
|
||||||
|
total_table_width = self.size().width()
|
||||||
|
column_ratios = []
|
||||||
|
for i in range(self.model2.columnCount() - 1):
|
||||||
|
column_width = self.columnWidth(i)
|
||||||
|
ratio = column_width / total_table_width
|
||||||
|
column_ratios.append(str(round(ratio, 4)))
|
||||||
|
# debug(f'get_current_header_width_ratios = {column_ratios}')
|
||||||
|
return column_ratios
|
||||||
|
|
||||||
|
def save_header_ratios(self):
|
||||||
|
"""
|
||||||
|
Saves the current header widths to memory and file, as ratios
|
||||||
|
"""
|
||||||
|
# WARNING: DOES NOT WORK and is not used.
|
||||||
|
# the same functionality is implemented in main.py closeEvent()
|
||||||
|
self.saved_column_ratios = self.get_current_header_width_ratios()
|
||||||
|
column_ratios_as_string = ",".join(self.saved_column_ratios)
|
||||||
|
self.config["table"]["column_ratios"] = column_ratios_as_string
|
||||||
|
# Save the config
|
||||||
|
try:
|
||||||
|
with open(self.cfg_file, "w") as configfile:
|
||||||
|
self.config.write(configfile)
|
||||||
|
except Exception as e:
|
||||||
|
debug(f"wtf man {e}")
|
||||||
|
debug(f"Saved column ratios: {self.saved_column_ratios}")
|
||||||
|
|
||||||
|
def load_header_widths(self, ratios: list[str] | None = None):
|
||||||
|
"""
|
||||||
|
Loads the header widths, based on saved ratios
|
||||||
|
or pass in a list of ratios to be loaded
|
||||||
|
"""
|
||||||
|
self.horizontal_header.setStretchLastSection(True)
|
||||||
|
if ratios is None:
|
||||||
|
column_ratios = self.get_current_header_width_ratios()
|
||||||
|
else:
|
||||||
|
column_ratios = ratios
|
||||||
|
total_table_width = self.size().width()
|
||||||
|
column_widths = []
|
||||||
|
for ratio in column_ratios:
|
||||||
|
column_widths.append(float(ratio) * total_table_width)
|
||||||
|
if isinstance(column_widths, list):
|
||||||
|
for i in range(self.model2.columnCount() - 1):
|
||||||
|
self.setColumnWidth(i, int(column_widths[i]))
|
||||||
|
|
||||||
|
|
||||||
def set_qmodel_index(self, index: QModelIndex):
|
def set_qmodel_index(self, index: QModelIndex):
|
||||||
self.current_song_qmodel_index = index
|
self.current_song_qmodel_index = index
|
||||||
|
|
||||||
@ -469,11 +529,11 @@ class MusicTable(QTableView):
|
|||||||
"""
|
"""
|
||||||
debug('add_files_to_library()')
|
debug('add_files_to_library()')
|
||||||
worker = Worker(add_files_to_database, files, None)
|
worker = Worker(add_files_to_database, files, None)
|
||||||
_ = worker.signals.signal_progress.connect(self.qapp.handle_progress)
|
_ = worker.signals.signal_progress.connect(self.qapp.handle_progress) # type: ignore
|
||||||
_ = worker.signals.signal_result.connect(self.on_add_files_to_database_finished)
|
_ = worker.signals.signal_result.connect(self.on_add_files_to_database_finished)
|
||||||
_ = worker.signals.signal_finished.connect(self.load_music_table)
|
_ = worker.signals.signal_finished.connect(self.load_music_table)
|
||||||
if self.qapp:
|
if self.qapp:
|
||||||
threadpool = self.qapp.threadpool
|
threadpool = self.qapp.threadpool # type: ignore
|
||||||
threadpool.start(worker)
|
threadpool.start(worker)
|
||||||
else:
|
else:
|
||||||
error("Application window could not be found")
|
error("Application window could not be found")
|
||||||
@ -820,17 +880,6 @@ class MusicTable(QTableView):
|
|||||||
self.proxymodel.setSourceModel(self.model2)
|
self.proxymodel.setSourceModel(self.model2)
|
||||||
self.setModel(self.proxymodel)
|
self.setModel(self.proxymodel)
|
||||||
|
|
||||||
def load_header_widths(self):
|
|
||||||
"""
|
|
||||||
Loads the header widths from the last application close.
|
|
||||||
"""
|
|
||||||
table_view_column_widths = str(
|
|
||||||
self.config["table"]["column_widths"]).split(",")
|
|
||||||
debug(f"loaded header widths: {table_view_column_widths}")
|
|
||||||
if not isinstance(table_view_column_widths, list):
|
|
||||||
for i in range(self.model2.columnCount() - 1):
|
|
||||||
self.setColumnWidth(i, int(table_view_column_widths[i]))
|
|
||||||
|
|
||||||
def sort_table_by_multiple_columns(self):
|
def sort_table_by_multiple_columns(self):
|
||||||
"""
|
"""
|
||||||
Sorts the data in QTableView (self) by multiple columns
|
Sorts the data in QTableView (self) by multiple columns
|
||||||
|
|||||||
89
main.py
89
main.py
@ -98,14 +98,14 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
|
|||||||
|
|
||||||
# widget bits
|
# widget bits
|
||||||
self.tableView: MusicTable
|
self.tableView: MusicTable
|
||||||
|
self.tableView.saved_column_ratios: list[str] = str(self.config["table"]["column_ratios"]).split(",") # type: ignore
|
||||||
|
debug(f'AAAAA - {self.tableView.saved_column_ratios}')
|
||||||
self.album_art_scene: QGraphicsScene = QGraphicsScene()
|
self.album_art_scene: QGraphicsScene = QGraphicsScene()
|
||||||
self.player: QMediaPlayer = MediaPlayer()
|
self.player: QMediaPlayer = MediaPlayer()
|
||||||
# set index on choose song
|
# set index on choose song
|
||||||
# index is the model2's row number? i guess?
|
# index is the model2's row number? i guess?
|
||||||
self.probe: QAudioProbe = QAudioProbe() # Gets audio buffer data
|
self.probe: QAudioProbe = QAudioProbe() # Gets audio buffer data
|
||||||
self.audio_visualizer: AudioVisualizer = AudioVisualizer(
|
self.audio_visualizer: AudioVisualizer = AudioVisualizer(self.player, self.probe, self.PlotWidget)
|
||||||
self.player, self.probe, self.PlotWidget
|
|
||||||
)
|
|
||||||
self.timer: QTimer = QTimer(parent=self) # for playback slider and such
|
self.timer: QTimer = QTimer(parent=self) # for playback slider and such
|
||||||
|
|
||||||
# Button styles
|
# Button styles
|
||||||
@ -146,26 +146,17 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
|
|||||||
self.albumGraphicsView.setFixedSize(250, 250)
|
self.albumGraphicsView.setFixedSize(250, 250)
|
||||||
|
|
||||||
# Connections
|
# Connections
|
||||||
self.playbackSlider.sliderReleased.connect(
|
self.playbackSlider.sliderReleased.connect(lambda: self.player.setPosition(self.playbackSlider.value())) # sliderReleased works better than sliderMoved
|
||||||
lambda: self.player.setPosition(self.playbackSlider.value())
|
self.volumeSlider.sliderMoved[int].connect(lambda: self.on_volume_changed())
|
||||||
) # sliderReleased works better than sliderMoved
|
self.speedSlider.sliderMoved.connect(lambda: self.on_speed_changed(self.speedSlider.value()))
|
||||||
self.volumeSlider.sliderMoved[int].connect(
|
|
||||||
lambda: self.on_volume_changed())
|
|
||||||
self.speedSlider.sliderMoved.connect(
|
|
||||||
lambda: self.on_speed_changed(self.speedSlider.value())
|
|
||||||
)
|
|
||||||
# self.speedSlider.doubleClicked.connect(lambda: self.on_speed_changed(1))
|
# self.speedSlider.doubleClicked.connect(lambda: self.on_speed_changed(1))
|
||||||
self.playButton.clicked.connect(
|
self.playButton.clicked.connect(self.on_play_clicked) # Click to play/pause
|
||||||
self.on_play_clicked) # Click to play/pause
|
|
||||||
self.previousButton.clicked.connect(self.on_prev_clicked)
|
self.previousButton.clicked.connect(self.on_prev_clicked)
|
||||||
self.nextButton.clicked.connect(
|
self.nextButton.clicked.connect(self.on_next_clicked) # Click to next song
|
||||||
self.on_next_clicked) # Click to next song
|
|
||||||
|
|
||||||
# FILE MENU
|
# FILE MENU
|
||||||
self.actionOpenFiles.triggered.connect(
|
self.actionOpenFiles.triggered.connect(self.open_files) # Open files window
|
||||||
self.open_files) # Open files window
|
self.actionNewPlaylist.triggered.connect(self.playlistTreeView.create_playlist)
|
||||||
self.actionNewPlaylist.triggered.connect(
|
|
||||||
self.playlistTreeView.create_playlist)
|
|
||||||
self.actionExportPlaylist.triggered.connect(self.export_playlist)
|
self.actionExportPlaylist.triggered.connect(self.export_playlist)
|
||||||
|
|
||||||
# EDIT MENU
|
# EDIT MENU
|
||||||
@ -175,9 +166,7 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
|
|||||||
# QUICK ACTIONS MENU
|
# QUICK ACTIONS MENU
|
||||||
self.actionScanLibraries.triggered.connect(self.scan_libraries)
|
self.actionScanLibraries.triggered.connect(self.scan_libraries)
|
||||||
self.actionDeleteDatabase.triggered.connect(self.delete_database)
|
self.actionDeleteDatabase.triggered.connect(self.delete_database)
|
||||||
self.actionSortColumns.triggered.connect(
|
self.actionSortColumns.triggered.connect(self.tableView.sort_table_by_multiple_columns)
|
||||||
self.tableView.sort_table_by_multiple_columns
|
|
||||||
)
|
|
||||||
|
|
||||||
# QTableView
|
# QTableView
|
||||||
# for drag & drop functionality
|
# for drag & drop functionality
|
||||||
@ -187,36 +176,23 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
|
|||||||
self.lineEditSearch: QLineEdit
|
self.lineEditSearch: QLineEdit
|
||||||
|
|
||||||
# CONNECTIONS
|
# CONNECTIONS
|
||||||
self.lineEditSearch.textTypedSignal.connect(
|
self.lineEditSearch.textTypedSignal.connect(self.handle_search_box_text)
|
||||||
self.handle_search_box_text)
|
|
||||||
# tableView
|
# tableView
|
||||||
self.tableView.playSignal.connect(self.play_audio_file)
|
self.tableView.playSignal.connect(self.play_audio_file)
|
||||||
self.tableView.playPauseSignal.connect(
|
self.tableView.playPauseSignal.connect(self.on_play_clicked) # Spacebar toggle play/pause signal
|
||||||
self.on_play_clicked
|
|
||||||
) # Spacebar toggle play/pause signal
|
|
||||||
self.tableView.handleProgressSignal.connect(self.handle_progress)
|
self.tableView.handleProgressSignal.connect(self.handle_progress)
|
||||||
self.tableView.searchBoxSignal.connect(
|
self.tableView.searchBoxSignal.connect(self.handle_search_box_visibility)
|
||||||
self.handle_search_box_visibility)
|
self.tableView.playlistStatsSignal.connect(self.set_permanent_status_bar_message)
|
||||||
self.tableView.playlistStatsSignal.connect(
|
|
||||||
self.set_permanent_status_bar_message
|
|
||||||
)
|
|
||||||
self.tableView.load_music_table()
|
self.tableView.load_music_table()
|
||||||
self.player.playlistNextSignal.connect(self.on_next_clicked)
|
self.player.playlistNextSignal.connect(self.on_next_clicked)
|
||||||
|
|
||||||
# playlistTreeView
|
# playlistTreeView
|
||||||
self.playlistTreeView.playlistChoiceSignal.connect(
|
self.playlistTreeView.playlistChoiceSignal.connect(self.tableView.load_music_table)
|
||||||
self.tableView.load_music_table
|
self.playlistTreeView.allSongsSignal.connect(self.tableView.load_music_table)
|
||||||
)
|
|
||||||
self.playlistTreeView.allSongsSignal.connect(
|
|
||||||
self.tableView.load_music_table)
|
|
||||||
|
|
||||||
# albumGraphicsView
|
# albumGraphicsView
|
||||||
self.albumGraphicsView.albumArtDropped.connect(
|
self.albumGraphicsView.albumArtDropped.connect(self.set_album_art_for_selected_songs)
|
||||||
self.set_album_art_for_selected_songs
|
self.albumGraphicsView.albumArtDeleted.connect(self.delete_album_art_for_current_song)
|
||||||
)
|
|
||||||
self.albumGraphicsView.albumArtDeleted.connect(
|
|
||||||
self.delete_album_art_for_current_song
|
|
||||||
)
|
|
||||||
|
|
||||||
# _________________
|
# _________________
|
||||||
# | |
|
# | |
|
||||||
@ -233,23 +209,22 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
|
|||||||
def closeEvent(self, a0: QCloseEvent | None) -> None:
|
def closeEvent(self, a0: QCloseEvent | None) -> None:
|
||||||
"""Save settings when closing the application"""
|
"""Save settings when closing the application"""
|
||||||
# MusicTable/tableView column widths
|
# MusicTable/tableView column widths
|
||||||
list_of_column_widths = []
|
# list_of_column_widths = []
|
||||||
for i in range(self.tableView.model2.columnCount()):
|
# for i in range(self.tableView.model2.columnCount()):
|
||||||
list_of_column_widths.append(str(self.tableView.columnWidth(i)))
|
# list_of_column_widths.append(str(self.tableView.columnWidth(i)))
|
||||||
column_widths_as_string = ",".join(list_of_column_widths)
|
# column_widths_as_string = ",".join(list_of_column_widths)
|
||||||
debug(f"saving column widths: {column_widths_as_string}")
|
# debug(f"saving column widths: {column_widths_as_string}")
|
||||||
self.config["table"]["column_widths"] = column_widths_as_string
|
# self.config["table"]["column_widths"] = column_widths_as_string
|
||||||
|
|
||||||
self.config["settings"]["volume"] = str(self.current_volume)
|
self.config["settings"]["volume"] = str(self.current_volume)
|
||||||
self.config["settings"]["window_size"] = (
|
self.config["settings"]["window_size"] = (str(self.width()) + "," + str(self.height()))
|
||||||
str(self.width()) + "," + str(self.height())
|
self.config['table']['column_ratios'] = ",".join(self.tableView.get_current_header_width_ratios())
|
||||||
)
|
|
||||||
# Save the config
|
# Save the config
|
||||||
try:
|
try:
|
||||||
with open(self.cfg_file, "w") as configfile:
|
with open(self.cfg_file, "w") as configfile:
|
||||||
self.config.write(configfile)
|
self.config.write(configfile)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
debug(f"wtf man {e}")
|
debug(f"wtf man {e}")
|
||||||
|
|
||||||
# auto export any playlists that want it
|
# auto export any playlists that want it
|
||||||
try:
|
try:
|
||||||
with DBA.DBAccess() as db:
|
with DBA.DBAccess() as db:
|
||||||
@ -343,12 +318,8 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
|
|||||||
return
|
return
|
||||||
row: int = index.row()
|
row: int = index.row()
|
||||||
next_row: int = row + 1
|
next_row: int = row + 1
|
||||||
next_index: QModelIndex = self.tableView.proxymodel.index(
|
next_index: QModelIndex = self.tableView.proxymodel.index(next_row, index.column())
|
||||||
next_row, index.column()
|
next_filepath = next_index.siblingAtColumn(self.headers.db_list.index("filepath")).data()
|
||||||
)
|
|
||||||
next_filepath = next_index.siblingAtColumn(
|
|
||||||
self.headers.db_list.index("filepath")
|
|
||||||
).data()
|
|
||||||
if next_filepath is None:
|
if next_filepath is None:
|
||||||
return
|
return
|
||||||
self.play_audio_file(next_filepath)
|
self.play_audio_file(next_filepath)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user