def __init__(self, parent=None): super(PlaylistWidget, self).__init__(parent) self.songOperator = SongOperator(self) self.initial_params() self.set_attritutes() self.create_menu_items() self.create_connections()
class PlaylistWidget(PlaylistWidgetBasic): play_music_at_row_signal = pyqtSignal(int) play_or_pause_signal = pyqtSignal(int) playing_list_changed_signal = pyqtSignal(str, str) musics_added_signal = pyqtSignal(bool) musics_removed_signal = pyqtSignal() musics_cleared_signal = pyqtSignal() musics_marked_signal = pyqtSignal() download_signal = pyqtSignal() show_artist_info_signal = pyqtSignal(str) show_song_info_signal = pyqtSignal(int) tag_values_changed_signal = pyqtSignal(int, str, str, str) playlist_changed_signal = pyqtSignal() def __init__(self, parent=None): super(PlaylistWidget, self).__init__(parent) self.songOperator = SongOperator(self) self.initial_params() self.set_attritutes() self.create_menu_items() self.create_connections() def create_connections(self): self.cellEntered.connect(self.cell_entered) self.customContextMenuRequested.connect(self.music_table_menu) self.selectAllAction.triggered.connect(self.select_all_rows) self.selectInvertAction.triggered.connect(self.select_invert_rows) self.selectNoneAction.triggered.connect(self.select_none_rows) self.copytoMenu.triggered.connect(self.copy_to_other_playlist) self.movetoMenu.triggered.connect(self.move_to_other_playlist) self.addMusicAction.triggered.connect(self.add_musics) self.markSelectedAsFavoriteAction.triggered.connect( self.mark_selected_as_favorite) self.removeAction.triggered.connect(self.remove_musics) self.deleteAction.triggered.connect(self.delete_musics) self.clearListWidgetAction.triggered.connect(self.clear_musics) self.songSpecAction.triggered.connect(self.show_song_spec) self.artistSpecAction.triggered.connect(self.show_artist_info) self.downloadAction.triggered.connect(self.download_signal.emit) self.doubleClicked.connect(self.double_click_to_play) self.songOperator.wheel_event_triggered_signal.connect(self.wheelEvent) self.songOperator.double_clicked_signal.connect( self.double_click_to_play_with_row) self.songOperator.right_mouse_button_clicked_signal.connect( self.music_table_menu) self.songOperator.left_mouse_button_clicked_signal.connect( self.selectRow) self.songOperator.left_mouse_button_dragged_signal.connect( self.select_multi_rows) def cell_entered(self, row, column): if self.songOperator.isHidden(): self.songOperator.set_contents(row, self.item(row, column).text()) self.songOperator.show() oldRow = self.songOperator.get_row() if self.item(oldRow, column): self.item(oldRow, column).setText(self.playlist.get_music_title_at(oldRow)) self.songOperator.set_contents(row, self.playlist.get_music_title_at(row)) self.item(row, column).setText('') scrollBar = self.verticalScrollBar() scrolledValue = scrollBar.value() # if scrolledValue and scrolledValue == scrollBar.maximum(): # scrolledValue -= 1 self.songOperator.setGeometry(0, (row - scrolledValue) * self.rowHeight(row), 270, 31) def leaveEvent(self, event=None): self.hide_song_operator() def select_multi_rows(self, pos): exactPos = pos + self.songOperator.pos() item = self.itemAt(exactPos) if item: self.cell_entered(item.row(), 0) if not item.isSelected(): item.setSelected(True) def hide_song_operator(self): if not self.songOperator.isHidden(): oldRow = self.songOperator.get_row() item = self.item(oldRow, 0) if item: item.setText(self.playlist.get_music_title_at(oldRow)) self.songOperator.hide() def initial_params(self): self.files = [] self.lock = None self.downloadDir = '' self.deleteFlag = False self.isPlaying = False self.playingList = Playlist() self.allPlaylistNames = [] self.mode = 0 def set_playlist_names(self, listNames): self.allPlaylistNames = listNames def set_lock(self, lock): self.lock = lock def set_download_dir(self, dir): self.downloadDir = dir def set_playing_status(self, playlist): self.playingList = playlist def set_playlist_use_name(self, listName): if self.listName != listName: self.listName = listName self.playlist_changed_signal.emit() self.isPlaying = False if self.playingList.get_name() == listName: self.isPlaying = True if self.get_playing_used_state(): self.playlist = self.playingList.copy() else: self.playlist.fill_list(listName) self.fill_playlist_widget(self.playlist) self.select_row() self.pick_actions_into_menu() def get_playing_used_state(self): return self.isPlaying def get_playlist_length(self): return self.playlist.length() def get_playing_list_name(self): return self.playingList.get_name() def set_attritutes(self): self.setMouseTracking(True) self.setContextMenuPolicy(Qt.CustomContextMenu) self.setEditTriggers(QAbstractItemView.NoEditTriggers) self.setSelectionBehavior(QAbstractItemView.SelectRows) self.horizontalHeader().setDefaultAlignment(Qt.AlignLeft) self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.horizontalHeader().setVisible(False) self.verticalHeader().setVisible(False) self.setShowGrid(False) self.setRowCount(0) self.setColumnCount(1) self.setColumnWidth(0, 270) self.setColumnWidth(1, 80) def pick_actions_into_menu(self): self.listMenu.clear() if self.listName == Configures.PlaylistOnline: self.create_online_playlist_menu() elif self.listName == Configures.PlaylistFavorite: self.create_favor_playlist_menu() else: self.create_other_playlist_menu() def create_menu_items(self): self.listMenu = QMenu() self.addMusicAction = QAction("添加歌曲", self) self.selectAllAction = QAction("全选", self) self.selectInvertAction = QAction("反选", self) self.selectNoneAction = QAction("取消选择", self) self.markSelectedAsFavoriteAction = QAction("添加到“我的收藏”", self) self.copytoMenu = QMenu('复制到...') self.movetoMenu = QMenu('移动到...') self.downloadAction = QAction("下载", self) self.removeAction = QAction("移除歌曲", self) self.deleteAction = QAction("移除歌曲并删除本地文件", self) self.clearListWidgetAction = QAction("清空列表", self) self.songSpecAction = QAction("歌曲信息", self) self.artistSpecAction = QAction("歌手信息", self) def create_online_playlist_menu(self): self.listMenu.addAction(self.downloadAction) self.listMenu.addSeparator() self.listMenu.addAction(self.selectAllAction) self.listMenu.addAction(self.selectInvertAction) self.listMenu.addAction(self.selectNoneAction) self.listMenu.addSeparator() self.listMenu.addAction(self.removeAction) self.listMenu.addSeparator() self.listMenu.addAction(self.clearListWidgetAction) self.listMenu.addSeparator() self.listMenu.addAction(self.songSpecAction) self.listMenu.addAction(self.artistSpecAction) def create_favor_playlist_menu(self): self.listMenu.addAction(self.addMusicAction) self.listMenu.addSeparator() self.listMenu.addAction(self.selectAllAction) self.listMenu.addAction(self.selectInvertAction) self.listMenu.addAction(self.selectNoneAction) self.listMenu.addSeparator() self.listMenu.addAction(self.removeAction) self.listMenu.addAction(self.deleteAction) self.listMenu.addSeparator() self.listMenu.addAction(self.clearListWidgetAction) self.listMenu.addSeparator() self.listMenu.addAction(self.songSpecAction) self.listMenu.addAction(self.artistSpecAction) def fill_copyto_and_moveto_menu(self): self.copytoMenu.clear() self.movetoMenu.clear() if self.listName == Configures.PlaylistDefault: if len(self.allPlaylistNames) > 4: for i, name in enumerate(self.allPlaylistNames): if i >= 4: self.add_action(name) return True elif self.listName == Configures.PlaylistDownloaded: if len(self.allPlaylistNames) > 3: for i, name in enumerate(self.allPlaylistNames): if i >= 4 or i == 1: self.add_action(name) return True else: for i, name in enumerate(self.allPlaylistNames): if i == 1 or i >= 4 and name != self.listName: self.add_action(name) return True return False def add_action(self, name): action1 = QAction(name, self) self.copytoMenu.addAction(action1) action2 = QAction(name, self) self.movetoMenu.addAction(action2) def create_other_playlist_menu(self): self.listMenu.addAction(self.addMusicAction) self.listMenu.addSeparator() self.listMenu.addAction(self.selectAllAction) self.listMenu.addAction(self.selectInvertAction) self.listMenu.addAction(self.selectNoneAction) self.listMenu.addSeparator() self.listMenu.addAction(self.markSelectedAsFavoriteAction) self.listMenu.addSeparator() if self.fill_copyto_and_moveto_menu(): self.listMenu.addMenu(self.copytoMenu) self.listMenu.addMenu(self.movetoMenu) self.listMenu.addSeparator() self.listMenu.addAction(self.removeAction) self.listMenu.addAction(self.deleteAction) self.listMenu.addSeparator() self.listMenu.addAction(self.clearListWidgetAction) self.listMenu.addSeparator() self.listMenu.addAction(self.songSpecAction) self.listMenu.addAction(self.artistSpecAction) def music_table_menu(self, pos): pos += QPoint(10, 0) self.listMenu.exec_(self.mapToGlobal(pos)) def select_row(self): row = self.playingList.get_current_row() if self.get_playing_used_state() and row >= 0: self.selectRow(row) def add_musics(self): self.files = QFileDialog.getOpenFileNames(self, "选择音乐文件", self.downloadDir, self.tr("*.mp3"))[0] if not self.files: return self.exec_add_operation(self.files) self.musics_added_signal.emit(True) for item in self.files: row = self.playlist.get_item_index(item) self.setRangeSelected( QTableWidgetSelectionRange(row, 0, row, self.columnCount() - 1), True) @operate_after_check_thread_locked_state @trace_to_keep_time def exec_add_operation(self, files): self.addedIndexes = [] for item in sorted( list(set(files) - set(self.playlist.get_items_queue()))): self.add_a_music(item) self.addedIndexes.append(self.playlist.get_item_index(item)) if self.addedIndexes: self.playlist.commit_records() def remove_musics(self): self.removedIndexes = [] selecteds = self.selectedIndexes() currentRow = self.playingList.get_current_row( ) % self.playingList.length() if selecteds: for index in selecteds: row = index.row() if index.column() == 0: self.removedIndexes.append(row) self.removedIndexes.sort(reverse=True) if self.deleteFlag: text_tmp1 = "移除并删除本地文件" text_tmp2 = "有%s首歌曲将被移出列表,并被彻底删除,请确认!" % len( self.removedIndexes) else: text_tmp1 = "移除选中项" text_tmp2 = "有%s首歌曲将被移出列表,请确认!" % len(self.removedIndexes) ok = QMessageBox.warning(self, text_tmp1, text_tmp2, QMessageBox.No | QMessageBox.Yes, QMessageBox.No) if ok == QMessageBox.Yes: self.hide_song_operator() item = self.playingList.get_item_from_queue(currentRow) if not (self.get_playing_used_state() and currentRow in self.removedIndexes): self.exec_remove_operation(self.removedIndexes) if self.get_playing_used_state(): currentRow = self.playlist.get_item_index(item) else: currentMusic = self.playingList.get_music_title_at( currentRow) if self.deleteFlag: text_tmp3 = "移除并删除当前歌曲" text_tmp4 = "当前播放的歌曲: %s 将会被移除并被删除,请确认!" % currentMusic else: text_tmp3 = "移除当前歌曲" text_tmp4 = "当前播放的歌曲: %s 将会被移除,请确认!" % currentMusic ok = QMessageBox.warning(self, text_tmp3, text_tmp4, QMessageBox.No | QMessageBox.Yes, QMessageBox.No) if ok == QMessageBox.Yes: self.exec_remove_operation(self.removedIndexes) currentRow = -1 else: self.removedIndexes.remove(currentRow) self.exec_remove_operation(self.removedIndexes) currentRow = self.playlist.get_item_index(item) self.playlist.set_current_row(currentRow) self.musics_removed_signal.emit() def remove_without_check(self, selecteds): self.hide_song_operator() self.removedIndexes = [] currentRow = self.playingList.get_current_row( ) % self.playingList.length() if len(selecteds): for index in selecteds: row = index.row() if index.column() == 0: self.removedIndexes.append(row) self.removedIndexes.sort(reverse=True) item = self.playingList.get_item_from_queue(currentRow) if not (self.get_playing_used_state() and currentRow in self.removedIndexes): self.exec_remove_operation(self.removedIndexes) if self.get_playing_used_state(): currentRow = self.playlist.get_item_index(item) else: self.exec_remove_operation(self.removedIndexes) currentRow = -1 self.playlist.set_current_row(currentRow) self.musics_removed_signal.emit() @operate_after_check_thread_locked_state def exec_remove_operation(self, rows): if len(rows): for row in rows: self.removeRow(row) self.playlist.remove_item_at(row, self.deleteFlag) self.playlist.commit_records() def delete_musics(self): self.deleteFlag = True self.remove_musics() self.deleteFlag = False def clear_musics(self): if not self.rowCount(): return ok = QMessageBox.warning(self, "清空列表", "当前列表的所有歌曲(包括当前播放歌曲)都将被移除,请确认!", QMessageBox.No | QMessageBox.Yes, QMessageBox.No) if ok == QMessageBox.Yes: self.hide_song_operator() self.exec_clear_operation() self.musics_cleared_signal.emit() @operate_after_check_thread_locked_state def exec_clear_operation(self): self.clear_all_items() self.playlist.clear_list() self.playlist.commit_records() #标记选中项为喜欢 def mark_selected_as_favorite(self): selecteds = self.selectedIndexes() self.markedIndexes = [] playlistTemp = Playlist() playlistTemp.fill_list(Configures.PlaylistFavorite) existsTitles = playlistTemp.get_titles() for index in selecteds: row = index.row() path = self.playlist.get_music_path_at(row) title = self.playlist.get_music_title_at(row) if index.column( ) == 0 and title not in existsTitles and os.path.exists(path): playlistTemp.add_item(self.playlist.get_item_from_queue(row), self.playlist.get_record_at(row)) self.markedIndexes.append(row) if len(self.markedIndexes): playlistTemp.commit_records() self.musics_marked_signal.emit() def copy_to_other_playlist(self, action): selecteds = self.selectedIndexes() self.add_items_to_new_playlist(action.text(), selecteds) self.select_range_rows(selecteds) def move_to_other_playlist(self, action): selecteds = self.selectedIndexes() self.add_items_to_new_playlist(action.text(), selecteds) self.remove_without_check(selecteds) def add_items_to_new_playlist(self, name, selecteds): currentListName = self.listName if not selecteds: return playlistTemp = Playlist() for index in selecteds: row = index.row() if index.column() == 0: playlistTemp.add_item(self.playlist.get_item_from_queue(row), self.playlist.get_infos_at(row)) self.set_playlist_use_name(name) self.add_musics_from_other_playlist(playlistTemp) self.set_playlist_use_name(currentListName) def add_musics_from_other_playlist(self, playlistTemp): self.addedIndexes = [] for item in sorted( list(playlistTemp.get_ids() - self.playlist.get_ids())): self.playlist.add_item(item, playlistTemp.get_info_use_id(item)) self.addedIndexes.append(self.playlist.get_item_index(item)) if self.addedIndexes: self.playlist.commit_records() self.musics_added_signal.emit(False) def select_range_rows(self, selecteds, flag=True): for index in selecteds: if index.column() == 0: self.select_a_row(index.row(), flag) def select_a_row(self, row, flag=True): self.setRangeSelected( QTableWidgetSelectionRange(row, 0, row, self.columnCount() - 1), flag) def select_invert_rows(self): selecteds = self.selectedIndexes() self.select_all_rows() self.select_range_rows(selecteds, False) def select_all_rows(self): self.setRangeSelected( QTableWidgetSelectionRange(0, 0, self.rowCount() - 1, self.columnCount() - 1), True) def select_none_rows(self): self.setRangeSelected( QTableWidgetSelectionRange(0, 0, self.rowCount() - 1, self.columnCount() - 1), False) def show_song_spec(self): row = self.currentRow() self.show_song_info_signal.emit(row) def show_artist_info(self): row = self.currentRow() artist, musicName = get_artist_and_musicname_from_title( self.playlist.get_music_title_at(row)) self.show_artist_info_signal.emit(artist) def change_tag_value(self, row, title, album, modifiedTime): oldTitle = self.playlist.get_music_title_at(row) self.playlist.set_music_title_at(row, title, False) self.playlist.set_music_album_at(row, album, False) self.playlist.set_modified_time_at(row, modifiedTime, False) self.playlist.commit_records() if oldTitle != title: widgetItem = self.item(row, 0) widgetItem.setText(title) rename_lyric_file_use_title(oldTitle, title) self.tag_values_changed_signal.emit(row, oldTitle, title, album) def double_click_to_play(self, index): row = index.row() self.double_click_to_play_with_row(row) def double_click_to_play_with_row(self, row): self.selectRow(row) self.playlist.set_current_row(row) if self.get_playing_used_state(): self.play_or_pause_signal.emit(row) else: self.isPlaying = True self.playing_list_changed_signal.emit(self.playingList.get_name(), self.listName)
class PlaylistWidget(PlaylistWidgetBasic): play_music_at_row_signal = pyqtSignal(int) play_or_pause_signal = pyqtSignal(int) playing_list_changed_signal = pyqtSignal(str, str) musics_added_signal = pyqtSignal(bool) musics_removed_signal = pyqtSignal() musics_cleared_signal = pyqtSignal() musics_marked_signal = pyqtSignal() download_signal = pyqtSignal() show_artist_info_signal = pyqtSignal(str) show_song_info_signal = pyqtSignal(int) tag_values_changed_signal = pyqtSignal(int, str, str, str) playlist_changed_signal = pyqtSignal() def __init__(self, parent=None): super(PlaylistWidget, self).__init__(parent) self.songOperator = SongOperator(self) self.initial_params() self.set_attritutes() self.create_menu_items() self.create_connections() def create_connections(self): self.cellEntered.connect(self.cell_entered) self.customContextMenuRequested.connect(self.music_table_menu) self.selectAllAction.triggered.connect(self.select_all_rows) self.selectInvertAction.triggered.connect(self.select_invert_rows) self.selectNoneAction.triggered.connect(self.select_none_rows) self.copytoMenu.triggered.connect(self.copy_to_other_playlist) self.movetoMenu.triggered.connect(self.move_to_other_playlist) self.addMusicAction.triggered.connect(self.add_musics) self.markSelectedAsFavoriteAction.triggered.connect(self.mark_selected_as_favorite) self.removeAction.triggered.connect(self.remove_musics) self.deleteAction.triggered.connect(self.delete_musics) self.clearListWidgetAction.triggered.connect(self.clear_musics) self.songSpecAction.triggered.connect(self.show_song_spec) self.artistSpecAction.triggered.connect(self.show_artist_info) self.downloadAction.triggered.connect(self.download_signal.emit) self.doubleClicked.connect(self.double_click_to_play) self.songOperator.wheel_event_triggered_signal.connect(self.wheelEvent) self.songOperator.double_clicked_signal.connect(self.double_click_to_play_with_row) self.songOperator.right_mouse_button_clicked_signal.connect(self.music_table_menu) self.songOperator.left_mouse_button_clicked_signal.connect(self.selectRow) self.songOperator.left_mouse_button_dragged_signal.connect(self.select_multi_rows) def cell_entered(self, row, column): if self.songOperator.isHidden(): self.songOperator.set_contents(row, self.item(row, column).text()) self.songOperator.show() oldRow = self.songOperator.get_row() if self.item(oldRow, column): self.item(oldRow, column).setText(self.playlist.get_music_title_at(oldRow)) self.songOperator.set_contents(row, self.item(row, column).text()) self.item(row, column).setText('') scrollBar = self.verticalScrollBar() scrolledValue = scrollBar.value() # if scrolledValue and scrolledValue == scrollBar.maximum(): # scrolledValue -= 1 self.songOperator.setGeometry(0, (row - scrolledValue)*self.rowHeight(row), 270, 31) def leaveEvent(self, event=None): self.hide_song_operator() def select_multi_rows(self, pos): exactPos = pos + self.songOperator.pos() item = self.itemAt(exactPos) if item: self.cell_entered(item.row(), 0) if not item.isSelected(): item.setSelected(True) def hide_song_operator(self): if not self.songOperator.isHidden(): oldRow = self.songOperator.get_row() item = self.item(oldRow, 0) if item: item.setText(self.playlist.get_music_title_at(oldRow)) self.songOperator.hide() def initial_params(self): self.files = [] self.lock = None self.downloadDir = '' self.deleteFlag = False self.isPlaying = False self.playingList = Playlist() self.allPlaylistNames = [] self.mode = 0 def set_playlist_names(self, listNames): self.allPlaylistNames = listNames def set_lock(self, lock): self.lock = lock def set_download_dir(self, dir): self.downloadDir = dir def set_playing_status(self, playlist): self.playingList = playlist def set_playlist_use_name(self, listName): if self.listName != listName: self.listName = listName self.playlist_changed_signal.emit() self.isPlaying = False if self.playingList.get_name() == listName: self.isPlaying = True if self.get_playing_used_state(): self.playlist = self.playingList.copy() else: self.playlist.fill_list(listName) self.fill_playlist_widget(self.playlist) self.select_row() self.pick_actions_into_menu() def get_playing_used_state(self): return self.isPlaying def get_playlist_length(self): return self.playlist.length() def get_playing_list_name(self): return self.playingList.get_name() def set_attritutes(self): self.setMouseTracking(True) self.setContextMenuPolicy(Qt.CustomContextMenu) self.setEditTriggers(QAbstractItemView.NoEditTriggers) self.setSelectionBehavior(QAbstractItemView.SelectRows) self.horizontalHeader().setDefaultAlignment(Qt.AlignLeft) self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.horizontalHeader().setVisible(False) self.verticalHeader().setVisible(False) self.setShowGrid(False) self.setRowCount(0) self.setColumnCount(1) self.setColumnWidth(0, 270) self.setColumnWidth(1, 80) def pick_actions_into_menu(self): self.listMenu.clear() if self.listName == Configures.PlaylistOnline: self.create_online_playlist_menu() elif self.listName == Configures.PlaylistFavorite: self.create_favor_playlist_menu() else: self.create_other_playlist_menu() def create_menu_items(self): self.listMenu = QMenu() self.addMusicAction = QAction("添加歌曲", self) self.selectAllAction = QAction("全选", self) self.selectInvertAction = QAction("反选", self) self.selectNoneAction = QAction("取消选择", self) self.markSelectedAsFavoriteAction = QAction("添加到“我的收藏”", self) self.copytoMenu = QMenu('复制到...') self.movetoMenu = QMenu('移动到...') self.downloadAction = QAction("下载", self) self.removeAction = QAction("移除歌曲", self) self.deleteAction = QAction("移除歌曲并删除本地文件", self) self.clearListWidgetAction = QAction("清空列表", self) self.songSpecAction = QAction("歌曲信息", self) self.artistSpecAction = QAction("歌手信息", self) def create_online_playlist_menu(self): self.listMenu.addAction(self.downloadAction) self.listMenu.addSeparator() self.listMenu.addAction(self.selectAllAction) self.listMenu.addAction(self.selectInvertAction) self.listMenu.addAction(self.selectNoneAction) self.listMenu.addSeparator() self.listMenu.addAction(self.removeAction) self.listMenu.addSeparator() self.listMenu.addAction(self.clearListWidgetAction) self.listMenu.addSeparator() self.listMenu.addAction(self.songSpecAction) self.listMenu.addAction(self.artistSpecAction) def create_favor_playlist_menu(self): self.listMenu.addAction(self.addMusicAction) self.listMenu.addSeparator() self.listMenu.addAction(self.selectAllAction) self.listMenu.addAction(self.selectInvertAction) self.listMenu.addAction(self.selectNoneAction) self.listMenu.addSeparator() self.listMenu.addAction(self.removeAction) self.listMenu.addAction(self.deleteAction) self.listMenu.addSeparator() self.listMenu.addAction(self.clearListWidgetAction) self.listMenu.addSeparator() self.listMenu.addAction(self.songSpecAction) self.listMenu.addAction(self.artistSpecAction) def fill_copyto_and_moveto_menu(self): self.copytoMenu.clear() self.movetoMenu.clear() if self.listName == Configures.PlaylistDefault: if len(self.allPlaylistNames) > 4: for i, name in enumerate(self.allPlaylistNames): if i >= 4: self.add_action(name) return True elif self.listName == Configures.PlaylistDownloaded: if len(self.allPlaylistNames) > 3: for i, name in enumerate(self.allPlaylistNames): if i >= 4 or i == 1: self.add_action(name) return True else: for i, name in enumerate(self.allPlaylistNames): if i == 1 or i >= 4 and name!=self.listName: self.add_action(name) return True return False def add_action(self, name): action1 = QAction(name, self) self.copytoMenu.addAction(action1) action2 = QAction(name, self) self.movetoMenu.addAction(action2) def create_other_playlist_menu(self): self.listMenu.addAction(self.addMusicAction) self.listMenu.addSeparator() self.listMenu.addAction(self.selectAllAction) self.listMenu.addAction(self.selectInvertAction) self.listMenu.addAction(self.selectNoneAction) self.listMenu.addSeparator() self.listMenu.addAction(self.markSelectedAsFavoriteAction) self.listMenu.addSeparator() if self.fill_copyto_and_moveto_menu(): self.listMenu.addMenu(self.copytoMenu) self.listMenu.addMenu(self.movetoMenu) self.listMenu.addSeparator() self.listMenu.addAction(self.removeAction) self.listMenu.addAction(self.deleteAction) self.listMenu.addSeparator() self.listMenu.addAction(self.clearListWidgetAction) self.listMenu.addSeparator() self.listMenu.addAction(self.songSpecAction) self.listMenu.addAction(self.artistSpecAction) def music_table_menu(self, pos): pos += QPoint(10, 0) self.listMenu.exec_(self.mapToGlobal(pos)) def select_row(self): row = self.playingList.get_current_row() if self.get_playing_used_state() and row>=0: self.selectRow(row) def add_musics(self): self.files = QFileDialog.getOpenFileNames(self, "选择音乐文件", self.downloadDir, self.tr("*.mp3"))[0] if not self.files: return self.exec_add_operation(self.files) self.musics_added_signal.emit(True) for item in self.files: row = self.playlist.get_item_index(item) self.setRangeSelected(QTableWidgetSelectionRange(row, 0, row, self.columnCount()-1), True) @operate_after_check_thread_locked_state @trace_to_keep_time def exec_add_operation(self, files): self.addedIndexes = [] for item in sorted(list(set(files)-set(self.playlist.get_items_queue()))): self.add_a_music(item) self.addedIndexes.append(self.playlist.get_item_index(item)) if self.addedIndexes: self.playlist.commit_records() def remove_musics(self): self.removedIndexes = [] selecteds = self.selectedIndexes() currentRow = self.playingList.get_current_row() % self.playingList.length() if selecteds: for index in selecteds: row = index.row() if index.column() == 0: self.removedIndexes.append(row) self.removedIndexes.sort(reverse=True) if self.deleteFlag: text_tmp1 = "移除并删除本地文件" text_tmp2 = "有%s首歌曲将被移出列表,并被彻底删除,请确认!"%len(self.removedIndexes) else: text_tmp1 = "移除选中项" text_tmp2 = "有%s首歌曲将被移出列表,请确认!"%len(self.removedIndexes) ok = QMessageBox.warning(self, text_tmp1, text_tmp2, QMessageBox.No|QMessageBox.Yes, QMessageBox.No) if ok == QMessageBox.Yes: self.hide_song_operator() item = self.playingList.get_item_from_queue(currentRow) if not (self.get_playing_used_state() and currentRow in self.removedIndexes): self.exec_remove_operation(self.removedIndexes) if self.get_playing_used_state(): currentRow = self.playlist.get_item_index(item) else: currentMusic = self.playingList.get_music_title_at(currentRow) if self.deleteFlag: text_tmp3 = "移除并删除当前歌曲" text_tmp4 = "当前播放的歌曲: %s 将会被移除并被删除,请确认!"%currentMusic else: text_tmp3 = "移除当前歌曲" text_tmp4 = "当前播放的歌曲: %s 将会被移除,请确认!"%currentMusic ok = QMessageBox.warning(self, text_tmp3, text_tmp4, QMessageBox.No|QMessageBox.Yes, QMessageBox.No) if ok == QMessageBox.Yes: self.exec_remove_operation(self.removedIndexes) currentRow = -1 else: self.removedIndexes.remove(currentRow) self.exec_remove_operation(self.removedIndexes) currentRow = self.playlist.get_item_index(item) self.playlist.set_current_row(currentRow) self.musics_removed_signal.emit() def remove_without_check(self, selecteds): self.hide_song_operator() self.removedIndexes = [] currentRow = self.playingList.get_current_row() % self.playingList.length() if len(selecteds): for index in selecteds: row = index.row() if index.column() == 0: self.removedIndexes.append(row) self.removedIndexes.sort(reverse=True) item = self.playingList.get_item_from_queue(currentRow) if not (self.get_playing_used_state() and currentRow in self.removedIndexes): self.exec_remove_operation(self.removedIndexes) if self.get_playing_used_state(): currentRow = self.playlist.get_item_index(item) else: self.exec_remove_operation(self.removedIndexes) currentRow = -1 self.playlist.set_current_row(currentRow) self.musics_removed_signal.emit() @operate_after_check_thread_locked_state def exec_remove_operation(self, rows): if len(rows): for row in rows: self.removeRow(row) self.playlist.remove_item_at(row, self.deleteFlag) self.playlist.commit_records() def delete_musics(self): self.deleteFlag = True self.remove_musics() self.deleteFlag = False def clear_musics(self): if not self.rowCount(): return ok = QMessageBox.warning(self, "清空列表", "当前列表的所有歌曲(包括当前播放歌曲)都将被移除,请确认!", QMessageBox.No|QMessageBox.Yes, QMessageBox.No) if ok == QMessageBox.Yes: self.hide_song_operator() self.exec_clear_operation() self.musics_cleared_signal.emit() @operate_after_check_thread_locked_state def exec_clear_operation(self): self.clear_all_items() self.playlist.clear_list() self.playlist.commit_records() #标记选中项为喜欢 def mark_selected_as_favorite(self): selecteds = self.selectedIndexes() self.markedIndexes = [] playlistTemp = Playlist() playlistTemp.fill_list(Configures.PlaylistFavorite) existsTitles = playlistTemp.get_titles() for index in selecteds: row = index.row() path = self.playlist.get_music_path_at(row) title = self.playlist.get_music_title_at(row) if index.column() == 0 and title not in existsTitles and os.path.exists(path): playlistTemp.add_item(self.playlist.get_item_from_queue(row), self.playlist.get_record_at(row)) self.markedIndexes.append(row) if len(self.markedIndexes): playlistTemp.commit_records() self.musics_marked_signal.emit() def copy_to_other_playlist(self, action): selecteds = self.selectedIndexes() self.add_items_to_new_playlist(action.text(), selecteds) self.select_range_rows(selecteds) def move_to_other_playlist(self, action): selecteds = self.selectedIndexes() self.add_items_to_new_playlist(action.text(), selecteds) self.remove_without_check(selecteds) def add_items_to_new_playlist(self, name, selecteds): currentListName = self.listName if not selecteds: return playlistTemp = Playlist() for index in selecteds: row = index.row() if index.column() == 0: playlistTemp.add_item(self.playlist.get_item_from_queue(row), self.playlist.get_infos_at(row)) self.set_playlist_use_name(name) self.add_musics_from_other_playlist(playlistTemp) self.set_playlist_use_name(currentListName) def add_musics_from_other_playlist(self, playlistTemp): self.addedIndexes = [] for item in sorted(list(playlistTemp.get_ids()-self.playlist.get_ids())): self.playlist.add_item(item, playlistTemp.get_info_use_id(item)) self.addedIndexes.append(self.playlist.get_item_index(item)) if self.addedIndexes: self.playlist.commit_records() self.musics_added_signal.emit(False) def select_range_rows(self, selecteds, flag=True): for index in selecteds: if index.column() == 0: self.select_a_row(index.row(), flag) def select_a_row(self, row, flag=True): self.setRangeSelected(QTableWidgetSelectionRange(row, 0, row, self.columnCount() - 1), flag) def select_invert_rows(self): selecteds = self.selectedIndexes() self.select_all_rows() self.select_range_rows(selecteds, False) def select_all_rows(self): self.setRangeSelected(QTableWidgetSelectionRange(0, 0, self.rowCount()-1, self.columnCount()-1), True) def select_none_rows(self): self.setRangeSelected(QTableWidgetSelectionRange(0, 0, self.rowCount()-1, self.columnCount()-1), False) def show_song_spec(self): row = self.currentRow() self.show_song_info_signal.emit(row) def show_artist_info(self): row = self.currentRow() artist, musicName = get_artist_and_musicname_from_title(self.playlist.get_music_title_at(row)) self.show_artist_info_signal.emit(artist) def change_tag_value(self, row, title, album, modifiedTime): oldTitle = self.playlist.get_music_title_at(row) self.playlist.set_music_title_at(row, title, False) self.playlist.set_music_album_at(row, album, False) self.playlist.set_modified_time_at(row, modifiedTime, False) self.playlist.commit_records() if oldTitle != title: widgetItem = self.item(row, 0) widgetItem.setText(title) rename_lyric_file_use_title(oldTitle, title) self.tag_values_changed_signal.emit(row, oldTitle, title, album) def double_click_to_play(self, index): row = index.row() self.double_click_to_play_with_row(row) def double_click_to_play_with_row(self, row): self.selectRow(row) self.playlist.set_current_row(row) if self.get_playing_used_state(): self.play_or_pause_signal.emit(row) else: self.isPlaying = True self.playing_list_changed_signal.emit(self.playingList.get_name(), self.listName)