multithreading working
This commit is contained in:
parent
31f23efcc1
commit
c4d181f1c1
@ -19,6 +19,7 @@ from PyQt5.QtWidgets import (
|
|||||||
from PyQt5.QtCore import (
|
from PyQt5.QtCore import (
|
||||||
QAbstractItemModel,
|
QAbstractItemModel,
|
||||||
QModelIndex,
|
QModelIndex,
|
||||||
|
QThreadPool,
|
||||||
Qt,
|
Qt,
|
||||||
pyqtSignal,
|
pyqtSignal,
|
||||||
QTimer,
|
QTimer,
|
||||||
@ -49,17 +50,21 @@ class MusicTable(QTableView):
|
|||||||
enterKey = pyqtSignal()
|
enterKey = pyqtSignal()
|
||||||
deleteKey = pyqtSignal()
|
deleteKey = pyqtSignal()
|
||||||
refreshMusicTable = pyqtSignal()
|
refreshMusicTable = pyqtSignal()
|
||||||
|
handleProgressSignal = pyqtSignal(str)
|
||||||
|
getThreadPoolSignal = pyqtSignal()
|
||||||
|
|
||||||
def __init__(self, parent):
|
def __init__(self, parent=None, application_window=None):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
|
self.application_window = application_window
|
||||||
|
|
||||||
# FIXME: why does this give me pyright errors
|
# FIXME: why does this give me pyright errors
|
||||||
self.model = QStandardItemModel()
|
self.model = QStandardItemModel()
|
||||||
self.setModel(self.model)
|
self.setModel(self.model)
|
||||||
# self.model: QAbstractItemModel | None = QAbstractItemModel(self)
|
|
||||||
|
|
||||||
# Config
|
# Config
|
||||||
self.config = configparser.ConfigParser()
|
self.config = configparser.ConfigParser()
|
||||||
self.config.read("config.ini")
|
self.config.read("config.ini")
|
||||||
|
self.threadpool = QThreadPool
|
||||||
# gui names of headers
|
# gui names of headers
|
||||||
self.table_headers = [
|
self.table_headers = [
|
||||||
"title",
|
"title",
|
||||||
@ -98,12 +103,12 @@ class MusicTable(QTableView):
|
|||||||
self.deleteKey.connect(self.delete_songs)
|
self.deleteKey.connect(self.delete_songs)
|
||||||
self.model.dataChanged.connect(self.on_cell_data_changed) # editing cells
|
self.model.dataChanged.connect(self.on_cell_data_changed) # editing cells
|
||||||
self.model.layoutChanged.connect(self.restore_scroll_position)
|
self.model.layoutChanged.connect(self.restore_scroll_position)
|
||||||
|
|
||||||
self.load_music_table()
|
self.load_music_table()
|
||||||
self.setup_keyboard_shortcuts()
|
self.setup_keyboard_shortcuts()
|
||||||
|
|
||||||
def contextMenuEvent(self, event):
|
def contextMenuEvent(self, a0):
|
||||||
"""Right-click context menu for rows in Music Table"""
|
"""Right-click context menu for rows in Music Table"""
|
||||||
|
assert a0 is not None
|
||||||
menu = QMenu(self)
|
menu = QMenu(self)
|
||||||
add_to_playlist_action = QAction("Add to playlist", self)
|
add_to_playlist_action = QAction("Add to playlist", self)
|
||||||
add_to_playlist_action.triggered.connect(self.add_selected_files_to_playlist)
|
add_to_playlist_action.triggered.connect(self.add_selected_files_to_playlist)
|
||||||
@ -130,7 +135,7 @@ class MusicTable(QTableView):
|
|||||||
menu.addAction(delete_action)
|
menu.addAction(delete_action)
|
||||||
# show
|
# show
|
||||||
self.set_selected_song_filepath()
|
self.set_selected_song_filepath()
|
||||||
menu.exec_(event.globalPos())
|
menu.exec_(a0.globalPos())
|
||||||
|
|
||||||
def show_id3_tags_debug_menu(self):
|
def show_id3_tags_debug_menu(self):
|
||||||
"""Shows ID3 tags for a specific .mp3 file"""
|
"""Shows ID3 tags for a specific .mp3 file"""
|
||||||
@ -151,6 +156,10 @@ class MusicTable(QTableView):
|
|||||||
QMessageBox.Yes,
|
QMessageBox.Yes,
|
||||||
)
|
)
|
||||||
if reply:
|
if reply:
|
||||||
|
try:
|
||||||
|
self.model.dataChanged.disconnect(self.on_cell_data_changed)
|
||||||
|
except Exception as e:
|
||||||
|
pass
|
||||||
selected_filepaths = self.get_selected_songs_filepaths()
|
selected_filepaths = self.get_selected_songs_filepaths()
|
||||||
selected_indices = self.get_selected_rows()
|
selected_indices = self.get_selected_rows()
|
||||||
for file in selected_filepaths:
|
for file in selected_filepaths:
|
||||||
@ -159,14 +168,16 @@ class MusicTable(QTableView):
|
|||||||
"SELECT id FROM song WHERE filepath = ?", (file,)
|
"SELECT id FROM song WHERE filepath = ?", (file,)
|
||||||
)[0][0]
|
)[0][0]
|
||||||
delete_song_id_from_database(song_id)
|
delete_song_id_from_database(song_id)
|
||||||
self.model.dataChanged.disconnect(self.on_cell_data_changed)
|
|
||||||
for index in selected_indices:
|
for index in selected_indices:
|
||||||
try:
|
try:
|
||||||
self.model.removeRow(index)
|
self.model.removeRow(index)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.info(f" delete_songs() failed | {e}")
|
logging.info(f" delete_songs() failed | {e}")
|
||||||
|
try:
|
||||||
|
self.model.dataChanged.connect(self.on_cell_data_changed)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
self.load_music_table()
|
self.load_music_table()
|
||||||
self.model.dataChanged.connect(self.on_cell_data_changed)
|
|
||||||
|
|
||||||
def open_directory(self):
|
def open_directory(self):
|
||||||
"""Opens the currently selected song in the system file manager"""
|
"""Opens the currently selected song in the system file manager"""
|
||||||
@ -237,19 +248,44 @@ class MusicTable(QTableView):
|
|||||||
if e is None:
|
if e is None:
|
||||||
return
|
return
|
||||||
data = e.mimeData()
|
data = e.mimeData()
|
||||||
|
logging.info(f"dropEvent data: {data}")
|
||||||
if data and data.hasUrls():
|
if data and data.hasUrls():
|
||||||
|
directories = []
|
||||||
files = []
|
files = []
|
||||||
for url in data.urls():
|
for url in data.urls():
|
||||||
if url.isLocalFile():
|
if url.isLocalFile():
|
||||||
files.append(url.path())
|
path = url.toLocalFile()
|
||||||
|
if os.path.isdir(path):
|
||||||
|
# append 1 directory
|
||||||
|
directories.append(path)
|
||||||
|
else:
|
||||||
|
# append 1 file
|
||||||
|
files.append(path)
|
||||||
e.accept()
|
e.accept()
|
||||||
worker = Worker(add_files_to_library, files)
|
print(f"directories: {directories}")
|
||||||
worker.signals.signal_progress.connect(self.handle_progress)
|
print(f"files: {files}")
|
||||||
worker.signals.signal_finished.connect(self.load_music_table)
|
if directories:
|
||||||
self.threadpool.start(worker)
|
worker = Worker(self.get_audio_files_recursively, directories)
|
||||||
|
worker.signals.signal_progress.connect(self.handle_progress)
|
||||||
|
worker.signals.signal_result.connect(self.on_recursive_search_finished)
|
||||||
|
worker.signals.signal_finished.connect(self.load_music_table)
|
||||||
|
if self.qapp:
|
||||||
|
threadpool = self.qapp.threadpool
|
||||||
|
threadpool.start(worker)
|
||||||
|
if files:
|
||||||
|
self.add_files(files)
|
||||||
else:
|
else:
|
||||||
e.ignore()
|
e.ignore()
|
||||||
|
|
||||||
|
def on_recursive_search_finished(self, result):
|
||||||
|
"""file search completion handler"""
|
||||||
|
if result:
|
||||||
|
self.add_files(result)
|
||||||
|
|
||||||
|
def handle_progress(self, data):
|
||||||
|
"""Emits data to main"""
|
||||||
|
self.handleProgressSignal.emit(data)
|
||||||
|
|
||||||
def keyPressEvent(self, e):
|
def keyPressEvent(self, e):
|
||||||
"""Press a key. Do a thing"""
|
"""Press a key. Do a thing"""
|
||||||
if not e:
|
if not e:
|
||||||
@ -287,27 +323,28 @@ class MusicTable(QTableView):
|
|||||||
def on_cell_data_changed(self, topLeft: QModelIndex, bottomRight: QModelIndex):
|
def on_cell_data_changed(self, topLeft: QModelIndex, bottomRight: QModelIndex):
|
||||||
"""Handles updating ID3 tags when data changes in a cell"""
|
"""Handles updating ID3 tags when data changes in a cell"""
|
||||||
logging.info("on_cell_data_changed")
|
logging.info("on_cell_data_changed")
|
||||||
id_index = self.model.index(topLeft.row(), 0) # ID is column 0, always
|
if isinstance(self.model, QStandardItemModel):
|
||||||
song_id = self.model.data(id_index, Qt.UserRole)
|
id_index = self.model.index(topLeft.row(), 0) # ID is column 0, always
|
||||||
# filepath is always the last column
|
song_id = self.model.data(id_index, Qt.UserRole)
|
||||||
filepath_column_idx = self.model.columnCount() - 1
|
# filepath is always the last column
|
||||||
filepath_index = self.model.index(topLeft.row(), filepath_column_idx)
|
filepath_column_idx = self.model.columnCount() - 1
|
||||||
# exact index of the edited cell in 2d space
|
filepath_index = self.model.index(topLeft.row(), filepath_column_idx)
|
||||||
filepath = self.model.data(filepath_index) # filepath
|
# exact index of the edited cell in 2d space
|
||||||
# update the ID3 information
|
filepath = self.model.data(filepath_index) # filepath
|
||||||
user_input_data = topLeft.data()
|
# update the ID3 information
|
||||||
edited_column_name = self.database_columns[topLeft.column()]
|
user_input_data = topLeft.data()
|
||||||
logging.info(f"edited column name: {edited_column_name}")
|
edited_column_name = self.database_columns[topLeft.column()]
|
||||||
response = set_id3_tag(filepath, edited_column_name, user_input_data)
|
logging.info(f"edited column name: {edited_column_name}")
|
||||||
if response:
|
response = set_id3_tag(filepath, edited_column_name, user_input_data)
|
||||||
# Update the library with new metadata
|
if response:
|
||||||
update_song_in_database(song_id, edited_column_name, user_input_data)
|
# Update the library with new metadata
|
||||||
|
update_song_in_database(song_id, edited_column_name, user_input_data)
|
||||||
|
|
||||||
def handle_reorganize_selected_files(self):
|
def handle_reorganize_selected_files(self):
|
||||||
""""""
|
""""""
|
||||||
worker = Worker(self.reorganize_selected_files)
|
worker = Worker(self.reorganize_selected_files)
|
||||||
worker.signals.signal_progress.connect(self.qapp.handle_progress)
|
worker.signals.signal_progress.connect(self.qapp.handle_progress)
|
||||||
self.threadpool.start(worker)
|
self.qapp.threadpool.start(worker)
|
||||||
|
|
||||||
def reorganize_selected_files(self, progress_callback):
|
def reorganize_selected_files(self, progress_callback):
|
||||||
"""Ctrl+Shift+R = Reorganize"""
|
"""Ctrl+Shift+R = Reorganize"""
|
||||||
@ -352,9 +389,7 @@ class MusicTable(QTableView):
|
|||||||
f"reorganize_selected_files() | Error moving file: {filepath} | {e}"
|
f"reorganize_selected_files() | Error moving file: {filepath} | {e}"
|
||||||
)
|
)
|
||||||
# Draw the rest of the owl
|
# Draw the rest of the owl
|
||||||
# self.model.dataChanged.disconnect(self.on_cell_data_changed)
|
|
||||||
self.load_music_table()
|
self.load_music_table()
|
||||||
# self.model.dataChanged.connect(self.on_cell_data_changed)
|
|
||||||
QMessageBox.information(
|
QMessageBox.information(
|
||||||
self, "Reorganization complete", "Files successfully reorganized"
|
self, "Reorganization complete", "Files successfully reorganized"
|
||||||
)
|
)
|
||||||
@ -365,12 +400,21 @@ class MusicTable(QTableView):
|
|||||||
self.set_current_song_filepath()
|
self.set_current_song_filepath()
|
||||||
self.playPauseSignal.emit()
|
self.playPauseSignal.emit()
|
||||||
|
|
||||||
def add_files(self, files, progress_callback) -> None:
|
def add_files(self, files) -> None:
|
||||||
"""When song(s) added to the library, update the tableview model
|
"""Thread handles adding songs to library
|
||||||
- Drag & Drop song(s) on tableView
|
- Drag & Drop song(s) on tableView
|
||||||
- File > Open > List of song(s)
|
- File > Open > List of song(s)
|
||||||
"""
|
"""
|
||||||
add_files_to_library(files, progress_callback)
|
logging.info(f"add files, files: {files}")
|
||||||
|
worker = Worker(add_files_to_library, files)
|
||||||
|
worker.signals.signal_progress.connect(self.handle_progress)
|
||||||
|
worker.signals.signal_finished.connect(self.load_music_table)
|
||||||
|
if self.qapp:
|
||||||
|
threadpool = self.qapp.threadpool
|
||||||
|
threadpool.start(worker)
|
||||||
|
else:
|
||||||
|
logging.warning("Application window could not be found")
|
||||||
|
# add_files_to_library(files, progress_callback)
|
||||||
return
|
return
|
||||||
|
|
||||||
def load_music_table(self, *playlist_id):
|
def load_music_table(self, *playlist_id):
|
||||||
@ -384,7 +428,6 @@ class MusicTable(QTableView):
|
|||||||
# Loading the table also causes cell data to change, technically
|
# Loading the table also causes cell data to change, technically
|
||||||
# so we must disconnect the dataChanged trigger before loading
|
# so we must disconnect the dataChanged trigger before loading
|
||||||
# then re-enable after we are done loading
|
# then re-enable after we are done loading
|
||||||
pass
|
|
||||||
self.model.dataChanged.disconnect(self.on_cell_data_changed)
|
self.model.dataChanged.disconnect(self.on_cell_data_changed)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.info(
|
logging.info(
|
||||||
@ -394,7 +437,6 @@ class MusicTable(QTableView):
|
|||||||
self.vertical_scroll_position = (
|
self.vertical_scroll_position = (
|
||||||
self.verticalScrollBar().value()
|
self.verticalScrollBar().value()
|
||||||
) # Get my scroll position before clearing
|
) # Get my scroll position before clearing
|
||||||
# temporarily disconnect the datachanged signal to avoid EVERY SONG getting triggered
|
|
||||||
self.model.clear()
|
self.model.clear()
|
||||||
self.model.setHorizontalHeaderLabels(self.table_headers)
|
self.model.setHorizontalHeaderLabels(self.table_headers)
|
||||||
if playlist_id:
|
if playlist_id:
|
||||||
@ -434,10 +476,13 @@ class MusicTable(QTableView):
|
|||||||
item.setData(id, Qt.UserRole)
|
item.setData(id, Qt.UserRole)
|
||||||
self.model.layoutChanged.emit() # emits a signal that the view should be updated
|
self.model.layoutChanged.emit() # emits a signal that the view should be updated
|
||||||
try:
|
try:
|
||||||
# self.model.dataChanged.connect(self.on_cell_data_changed)
|
|
||||||
self.restore_scroll_position()
|
self.restore_scroll_position()
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
try:
|
||||||
|
self.model.dataChanged.connect(self.on_cell_data_changed)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
def restore_scroll_position(self) -> None:
|
def restore_scroll_position(self) -> None:
|
||||||
"""Restores the scroll position"""
|
"""Restores the scroll position"""
|
||||||
@ -447,6 +492,19 @@ class MusicTable(QTableView):
|
|||||||
lambda: self.verticalScrollBar().setValue(self.vertical_scroll_position),
|
lambda: self.verticalScrollBar().setValue(self.vertical_scroll_position),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def get_audio_files_recursively(self, directories, progress_callback=None):
|
||||||
|
"""Scans a directories for files"""
|
||||||
|
extensions = self.config.get("settings", "extensions").split(",")
|
||||||
|
audio_files = []
|
||||||
|
for directory in directories:
|
||||||
|
for root, _, files in os.walk(directory):
|
||||||
|
for file in files:
|
||||||
|
if any(file.lower().endswith(ext) for ext in extensions):
|
||||||
|
audio_files.append(os.path.join(root, file))
|
||||||
|
if progress_callback:
|
||||||
|
progress_callback.emit(file)
|
||||||
|
return audio_files
|
||||||
|
|
||||||
def get_selected_rows(self) -> list[int]:
|
def get_selected_rows(self) -> list[int]:
|
||||||
"""Returns a list of indexes for every selected row"""
|
"""Returns a list of indexes for every selected row"""
|
||||||
selection_model = self.selectionModel()
|
selection_model = self.selectionModel()
|
||||||
@ -509,5 +567,5 @@ class MusicTable(QTableView):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def load_qapp(self, qapp) -> None:
|
def load_qapp(self, qapp) -> None:
|
||||||
"""Necessary for talking between components..."""
|
"""Necessary for using members and methods of main application window"""
|
||||||
self.qapp = qapp
|
self.qapp = qapp
|
||||||
|
|||||||
48
main.py
48
main.py
@ -78,8 +78,8 @@ class WorkerSignals(QObject):
|
|||||||
# (i.e. lists of filepaths)
|
# (i.e. lists of filepaths)
|
||||||
|
|
||||||
signal_started = pyqtSignal()
|
signal_started = pyqtSignal()
|
||||||
signal_finished = pyqtSignal()
|
|
||||||
signal_result = pyqtSignal(object)
|
signal_result = pyqtSignal(object)
|
||||||
|
signal_finished = pyqtSignal()
|
||||||
signal_progress = pyqtSignal(str)
|
signal_progress = pyqtSignal(str)
|
||||||
|
|
||||||
|
|
||||||
@ -117,13 +117,17 @@ class Worker(QRunnable):
|
|||||||
"""
|
"""
|
||||||
self.signals.signal_started.emit()
|
self.signals.signal_started.emit()
|
||||||
try:
|
try:
|
||||||
self.fn(*self.args, **self.kwargs)
|
result = self.fn(*self.args, **self.kwargs)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
exctype, value = sys.exc_info()[:2]
|
exctype, value = sys.exc_info()[:2]
|
||||||
self.signals.signal_finished.emit((exctype, value, traceback.format_exc()))
|
self.signals.signal_finished.emit((exctype, value, traceback.format_exc()))
|
||||||
finally:
|
else:
|
||||||
self.signals.signal_finished.emit()
|
if result:
|
||||||
|
self.signals.signal_finished.emit()
|
||||||
|
self.signals.signal_result.emit(result)
|
||||||
|
else:
|
||||||
|
self.signals.signal_finished.emit()
|
||||||
|
|
||||||
|
|
||||||
class ApplicationWindow(QMainWindow, Ui_MainWindow):
|
class ApplicationWindow(QMainWindow, Ui_MainWindow):
|
||||||
@ -153,8 +157,8 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
|
|||||||
self.audio_visualizer: AudioVisualizer = AudioVisualizer(self.player)
|
self.audio_visualizer: AudioVisualizer = AudioVisualizer(self.player)
|
||||||
self.current_volume: int = 50
|
self.current_volume: int = 50
|
||||||
self.qapp = qapp
|
self.qapp = qapp
|
||||||
self.tableView.load_qapp(self.qapp)
|
self.tableView.load_qapp(self)
|
||||||
self.albumGraphicsView.load_qapp(self.qapp)
|
self.albumGraphicsView.load_qapp(self)
|
||||||
self.config.read("config.ini")
|
self.config.read("config.ini")
|
||||||
# Initialization
|
# Initialization
|
||||||
self.timer = QTimer(self) # Audio timing things
|
self.timer = QTimer(self) # Audio timing things
|
||||||
@ -209,7 +213,8 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
|
|||||||
self.actionDeleteLibrary.triggered.connect(self.clear_database)
|
self.actionDeleteLibrary.triggered.connect(self.clear_database)
|
||||||
self.actionDeleteDatabase.triggered.connect(self.delete_database)
|
self.actionDeleteDatabase.triggered.connect(self.delete_database)
|
||||||
|
|
||||||
## tableView triggers
|
## CONNECTIONS
|
||||||
|
# tableView
|
||||||
self.tableView.doubleClicked.connect(
|
self.tableView.doubleClicked.connect(
|
||||||
self.play_audio_file
|
self.play_audio_file
|
||||||
) # Listens for the double click event, then plays the song
|
) # Listens for the double click event, then plays the song
|
||||||
@ -220,7 +225,7 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
|
|||||||
self.on_play_clicked
|
self.on_play_clicked
|
||||||
) # Spacebar toggle play/pause signal
|
) # Spacebar toggle play/pause signal
|
||||||
|
|
||||||
## Playlist triggers
|
# playlistTreeView
|
||||||
self.playlistTreeView.playlistChoiceSignal.connect(
|
self.playlistTreeView.playlistChoiceSignal.connect(
|
||||||
self.tableView.load_music_table
|
self.tableView.load_music_table
|
||||||
)
|
)
|
||||||
@ -233,9 +238,12 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
|
|||||||
self.albumGraphicsView.albumArtDeleted.connect(
|
self.albumGraphicsView.albumArtDeleted.connect(
|
||||||
self.delete_album_art_for_selected_songs
|
self.delete_album_art_for_selected_songs
|
||||||
)
|
)
|
||||||
|
# multithreading
|
||||||
|
# whatever
|
||||||
self.tableView.viewport().installEventFilter(
|
self.tableView.viewport().installEventFilter(
|
||||||
self
|
self
|
||||||
) # for drag & drop functionality
|
) # for drag & drop functionality
|
||||||
|
self.tableView.handleProgressSignal.connect(self.handle_progress)
|
||||||
# set column widths
|
# set column widths
|
||||||
table_view_column_widths = str(self.config["table"]["column_widths"]).split(",")
|
table_view_column_widths = str(self.config["table"]["column_widths"]).split(",")
|
||||||
for i in range(self.tableView.model.columnCount()):
|
for i in range(self.tableView.model.columnCount()):
|
||||||
@ -244,6 +252,14 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
|
|||||||
self.tableView.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
|
self.tableView.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
|
||||||
self.tableView.horizontalHeader().setStretchLastSection(False)
|
self.tableView.horizontalHeader().setStretchLastSection(False)
|
||||||
|
|
||||||
|
def reload_config(self) -> None:
|
||||||
|
"""does what it says"""
|
||||||
|
self.config.read("config.ini")
|
||||||
|
|
||||||
|
def get_thread_pool(self) -> QThreadPool:
|
||||||
|
"""Returns the threadpool instance"""
|
||||||
|
return self.threadpool
|
||||||
|
|
||||||
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
|
||||||
@ -483,22 +499,6 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
|
|||||||
worker = Worker(add_files_to_library, filenames)
|
worker = Worker(add_files_to_library, filenames)
|
||||||
worker.signals.signal_finished.connect(self.tableView.load_music_table)
|
worker.signals.signal_finished.connect(self.tableView.load_music_table)
|
||||||
worker.signals.signal_progress.connect(self.handle_progress)
|
worker.signals.signal_progress.connect(self.handle_progress)
|
||||||
# try:
|
|
||||||
# worker.signals.signal_started.connect(
|
|
||||||
# lambda: self.tableView.model.dataChanged.disconnect(
|
|
||||||
# self.tableView.on_cell_data_changed
|
|
||||||
# )
|
|
||||||
# )
|
|
||||||
# except:
|
|
||||||
# pass
|
|
||||||
# try:
|
|
||||||
# worker.signals.signal_finished.connect(
|
|
||||||
# lambda: self.tableView.model.dataChanged.connect(
|
|
||||||
# self.tableView.on_cell_data_changed
|
|
||||||
# )
|
|
||||||
# )
|
|
||||||
# except:
|
|
||||||
# pass
|
|
||||||
self.threadpool.start(worker)
|
self.threadpool.start(worker)
|
||||||
|
|
||||||
def handle_progress(self, data):
|
def handle_progress(self, data):
|
||||||
|
|||||||
@ -8,7 +8,7 @@ config = ConfigParser()
|
|||||||
config.read("config.ini")
|
config.read("config.ini")
|
||||||
|
|
||||||
|
|
||||||
def add_files_to_library(files, progress_callback):
|
def add_files_to_library(files, progress_callback=None):
|
||||||
"""Adds audio file(s) to the sqllite db
|
"""Adds audio file(s) to the sqllite db
|
||||||
files = list() of fully qualified paths to audio file(s)
|
files = list() of fully qualified paths to audio file(s)
|
||||||
Returns a list of dictionaries of metadata
|
Returns a list of dictionaries of metadata
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user