class SearchFrame(QWidget): switch_to_online_list = pyqtSignal() add_bunch_to_list_succeed = pyqtSignal() listen_online_signal = pyqtSignal(str, str, str) listen_local_signal = pyqtSignal(str) add_to_download_signal = pyqtSignal() def __init__(self, parent = None): super(SearchFrame, self).__init__(parent) self.setup_ui() self.reset_search() self.create_connects() def setup_ui(self): self.searchTable = SearchTable() self.searchBox = SearchBox() self.previousPageButton = QToolButton() self.previousPageButton.setFixedSize(40, 31) icon0 = QIcon(":/iconSources/icons/previousPage.png") self.previousPageButton.setIcon(icon0) self.previousPageButton.setIconSize(QSize(25, 25)) self.previousPageButton.setCursor(QCursor(Qt.PointingHandCursor)) self.previousPageButton.setToolTip('上一页') self.nextPageButton = QToolButton() self.nextPageButton.setFixedSize(40, 31) icon1 = QIcon(":/iconSources/icons/nextPage.png") self.nextPageButton.setIcon(icon1) self.nextPageButton.setIconSize(QSize(25, 25)) self.nextPageButton.setCursor(QCursor(Qt.PointingHandCursor)) self.nextPageButton.setToolTip('下一页') self.jumpNum = QLineEdit('0') self.jumpNum.setFixedWidth(39) self.jumpNum.setAlignment(Qt.AlignRight) self.pageNum = QLabel("/ 0") self.pageNum.setFixedHeight(35) self.pageNum.setFixedWidth(35) self.pageNum.setAlignment(Qt.AlignCenter ) self.pageNum.setToolTip('当前页码/总页数') self.controlWidget = QWidget() controlLayout = QHBoxLayout(self.controlWidget) controlLayout.setMargin(0) controlLayout.setSpacing(4) spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) controlLayout.addItem(spacerItem) controlLayout.addWidget(self.previousPageButton) controlLayout.addWidget(self.jumpNum) controlLayout.addWidget(self.pageNum) controlLayout.addWidget(self.nextPageButton) controlLayout.addItem(spacerItem) self.controlSearch = QWidget() controlSearchLayout = QVBoxLayout(self.controlSearch) controlSearchLayout.setMargin(0) controlSearchLayout.setSpacing(2) controlSearchLayout.addWidget(self.searchTable) controlSearchLayout.addWidget(self.controlWidget) mainLayout = QVBoxLayout(self) mainLayout.setMargin(2) mainLayout.setSpacing(2) mainLayout.addWidget(self.searchBox) mainLayout.addWidget(self.controlSearch) self.searchByType = 'all' self.searchBox.searchComboBox.setCurrentIndex(0) def create_connects(self): self.searchTable.installEventFilter(self) self.previousPageButton.clicked.connect(self.previous_page) self.nextPageButton.clicked.connect(self.next_page) self.jumpNum.returnPressed.connect(self.go_to_page) self.searchBox.searchButton.clicked.connect(self.search_musics) self.searchBox.lineEdit.returnPressed.connect(self.search_musics) self.searchBox.searchComboBox.currentIndexChanged.connect(self.searchtype_changed) self.searchBox.resetButton.clicked.connect(self.reset_search) self.searchTable.switchToOnlineListAction.triggered.connect(self.switch_to_online_list) self.searchTable.cellDoubleClicked.connect(self.searchtable_clicked) self.searchTable.cellClicked.connect(self.show_tooltip) self.searchTable.listenOnlineAction.triggered.connect(self.listen_online) self.searchTable.downloadAction.triggered.connect(self.download) self.searchTable.addBunchToListAction.triggered.connect(self.add_bunch_to_list) def eventFilter(self, target, event): if target == self.searchTable: if event.type() == QEvent.Resize: width = self.searchTable.width() widthTemp = (width-35)/3 self.searchTable.setColumnWidth(0, 35) self.searchTable.setColumnWidth(1, widthTemp) self.searchTable.setColumnWidth(2, widthTemp) self.searchTable.setColumnWidth(3, widthTemp) return False def show_tooltip(self, row): mark = self.searchTable.item(row, 0).text() songName = self.searchTable.item(row, 1).text() artist = self.searchTable.item(row, 2).text() album = self.searchTable.item(row, 3).text() self.searchTable.setToolTip("评分:%s\n 歌曲:%s\n歌手:%s\n专辑:%s"%(mark, songName, artist, album)) def switch_to_list(self): self.switchToOnlineList.emit() def listen_online(self): if not self.searchTable.rowCount(): return self.searchtable_clicked(self.searchTable.currentRow()) def searchtable_clicked(self, row): musicName = self.searchTable.item(row, 1).text() artist = self.searchTable.item(row, 2).text() title = artist + '._.' + musicName album = self.searchTable.item(row, 3).text() musicId = self.searchTable.item(row, 4).text() songLink = SearchOnline.get_song_link(musicId) if not songLink: return songLinkWrap = songLink + '~' + musicId self.listen_online_signal.emit(title, album, songLinkWrap) def add_bunch_to_list(self): selections = self.searchTable.selectionModel() selecteds = selections.selectedIndexes() if not len(selecteds): return model = TableModel() model.initial_model("在线试听") songsInOnlineList = [] added_items = [] t1 = time.time() for i in range(model.rowCount()): songsInOnlineList.append(model.record(i).value("paths")) t2 = time.time() print(t2-t1) self.setCursor(QCursor(Qt.BusyCursor)) for index in selecteds: if index.column() == 0: row = index.row() musicId = self.searchTable.item(row, 4).text() songLink = SearchOnline.get_song_link(musicId) if not songLink: continue songLinkWrap = songLink + '~' + musicId if songLinkWrap not in songsInOnlineList: musicName = self.searchTable.item(row, 1).text() artist = self.searchTable.item(row, 2).text() title = artist + '._.' + musicName album = self.searchTable.item(row, 3).text() lrcName = title + '.lrc' lrcPath = os.path.join(Configures.lrcsDir, lrcName) if os.path.exists(lrcPath): os.remove(lrcPath) added_items.append([title, songLinkWrap]) # SearchOnline.get_lrc_path(title, musicId) model.add_record(title, '未知', album, songLinkWrap) if len(added_items): thread = DownloadLrcThread(added_items) thread.setDaemon(True) thread.setName("downloadLrc") thread.start() self.add_bunch_to_list_succeed.emit() self.setCursor(QCursor(Qt.ArrowCursor)) print(time.time()-t2) print("Success") def download(self): if not self.searchTable.rowCount(): return # t1 = time.time() hasExisted = [] linkError = [] self.toBeEmited = [] selections = self.searchTable.selectionModel() selecteds = selections.selectedIndexes() if not len(selecteds): return with open(Configures.settingFile, 'r') as f: downloadDir = f.read() self.setCursor(QCursor(Qt.BusyCursor)) for index in selecteds: if index.column() == 0: row = index.row() songName = self.searchTable.item(row, 1).text() artist = self.searchTable.item(row, 2).text() title = artist + '._.' + songName musicName = title + '.mp3' musicPath = os.path.join(downloadDir, musicName) if os.path.exists(musicPath): hasExisted.append(title) continue for t in threading.enumerate(): if t.name == musicPath: continue album = self.searchTable.item(row, 3).text() musicId = self.searchTable.item(row, 4).text() songLink = SearchOnline.get_song_link(musicId) if not songLink: linkError.append(title) continue # QMessageBox.critical(self, '错误','链接错误,无法下载该歌曲!') # return # songInfo = '->'.join([songLink, musicPath, title , album, musicId]) self.toBeEmited.append([songLink, musicPath, title , album, musicId]) # songInfos = json.dumps(toBeEmited) self.add_to_download_signal.emit() self.setCursor(QCursor(Qt.ArrowCursor)) # print('searchPageWidget.py searchFrame.download timecost = %s'%(time.time()-t1)) if len(hasExisted): hasExistFiles = '\n'.join(hasExisted) self.show() QMessageBox.information(self, '提示','以下歌曲已在下载目录中,将不再进行下载!\n%s'%hasExistFiles) if len(linkError): linkErrorFiles = '\n'.join(linkError) self.show() QMessageBox.critical(self, '错误','以下歌曲链接出错,无法下载!\n%s'%linkErrorFiles) def reset_search(self): self.searchBox.lineEdit.clear() self.searchTable.clear_search_table() self.currentKeyword = None self.currentPage = 0 self.hit = 0 self.pages = 0 self.searchBox.searchButton.setText('搜索') self.pageNum.setText('/ 0') self.jumpNum.setText('0') def searchtype_changed(self, index): if index == 0: self.searchByType = 'all' elif index == 1: self.searchByType = 'artist' else: self.searchByType = 'album' self.search_musics() def go_to_page(self): if not self.currentKeyword: self.jumpNum.setText('%s'%self.currentPage) self.pageNum.setFocus() return page = self.jumpNum.text() try: page = int(page) except ValueError : self.jumpNum.setText('%s'%(self.currentPage + 1)) QMessageBox.information(None, "提示", "请输入1~%s内的整数!"%self.pages) return if page == (self.currentPage + 1): self.pageNum.setFocus() return if page > self.pages or page < 1: self.jumpNum.setText('%s'%(self.currentPage + 1)) QMessageBox.information(None, "提示", "页码范围1~%s"%self.pages) return self.show_musics(self.searchByType, self.currentKeyword, page - 1) self.currentPage = page - 1 self.searchBox.searchButton.setFocus() def search_musics(self): self.searchBox.searchButton.setFocus() keyword = self.searchBox.lineEdit.text() if not keyword: QMessageBox.information(self, '提示', '请输入搜索关键词!') return # if keyword == self.currentKeyword: # return self.currentKeyword = keyword self.hit = self.show_musics(self.searchByType, self.currentKeyword, 0) if self.hit == Configures.URLERROR: return self.currentPage = 0 if self.hit: self.pages = self.hit//15 + 1 self.jumpNum.setText('1') self.pageNum.setText('/ %s'%self.pages) else: self.jumpNum.setText('0') self.pageNum.setText('/ 0') self.searchBox.searchButton.setText('搜索(%s)'%self.hit) def previous_page(self): if not self.currentPage: return self.currentPage -= 1 self.show_musics(self.searchByType, self.currentKeyword, self.currentPage) self.jumpNum.setText('%s'%(self.currentPage + 1)) def next_page(self): if self.currentPage + 1 >= self.pages: return self.currentPage += 1 self.show_musics(self.searchByType, self.currentKeyword, self.currentPage) self.jumpNum.setText('%s'%(self.currentPage + 1)) def show_musics(self, searchByType, keyword, page): self.searchTable.clear_search_table() t1 = time.time() songs, hit = SearchOnline.search_songs(searchByType, keyword, page) if hit == Configures.URLERROR: QMessageBox.critical(None, "错误", "联网出错!\n请检查网络连接是否正常!") return Configures.URLERROR if not songs or hit == 0: return hit for song in songs: music = song[0] artist = song[1] album = song[2] if not album: album = '未知专辑' music_id = song[3] # artistId = song['ARTISTID'] score = song[4] self.searchTable.add_record(score, music, artist, album, music_id) self.searchTable.sortItems(0, Qt.DescendingOrder) t2 = time.time() print('searchPageWidget.py searchFrame.show_musics %s'%(t2 - t1)) return hit