Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
class SearchFrame(QWidget):
    add_bunch_to_list_succeed = pyqtSignal()
    listen_online_signal = pyqtSignal(str, str, str, str)
    add_to_download_signal = pyqtSignal()
    back_to_main_signal = pyqtSignal()

    def __init__(self, parent=None):
        super(SearchFrame, self).__init__(parent)
        self.init_params()
        self.setup_ui()
        self.create_connections()

    def setup_ui(self):
        self.searchTable = SearchTable()
        self.searchTable.setColumnWidth(0, 39)
        self.searchTable.setColumnWidth(1, 205)
        self.searchTable.setColumnWidth(2, 180)
        self.searchTable.setColumnWidth(3, 180)

        self.firstPageButton = QPushButton("首页",
                                           clicked=self.jump_to_first_page)
        self.firstPageButton.setFocusPolicy(Qt.NoFocus)
        self.firstPageButton.setFixedHeight(31)
        self.lastPageButton = QPushButton("末页", clicked=self.jump_to_last_page)
        self.lastPageButton.setFocusPolicy(Qt.NoFocus)
        self.lastPageButton.setFixedHeight(31)

        self.previousPageButton = QPushButton("上一页")
        self.previousPageButton.setFocusPolicy(Qt.NoFocus)
        self.previousPageButton.setFixedHeight(31)

        self.nextPageButton = QPushButton('下一页')
        self.nextPageButton.setFocusPolicy(Qt.NoFocus)
        self.nextPageButton.setFixedHeight(31)

        self.jumpNum = QLineEdit('0')
        self.jumpNum.setFocusPolicy(Qt.StrongFocus)
        self.jumpNum.setFixedSize(84, 31)
        self.jumpNum.setAlignment(Qt.AlignRight | Qt.AlignVCenter)

        self.pageNum = QLabel("/ 0")
        self.pageNum.setFixedSize(45, 31)
        self.pageNum.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)

        #页码栏布局
        pageNumLayout = QHBoxLayout(self.jumpNum)
        pageNumLayout.addStretch()
        pageNumLayout.addWidget(self.pageNum)
        pageNumLayout.setContentsMargins(0, 0, 0, 0)
        pageNumLayout.setSpacing(0)
        pageNumLayout.setContentsMargins(0, 0, 0, 0)
        self.jumpNum.setTextMargins(0, 0, self.pageNum.width(), 0)

        #综合布局
        self.controlWidget = QWidget()
        controlLayout = QHBoxLayout(self.controlWidget)
        controlLayout.setContentsMargins(0, 0, 0, 0)
        controlLayout.setSpacing(6)
        controlLayout.addWidget(self.firstPageButton)
        controlLayout.addWidget(self.previousPageButton)
        controlLayout.addWidget(self.jumpNum)
        controlLayout.addWidget(self.nextPageButton)
        controlLayout.addWidget(self.lastPageButton)

        mainLayout = QVBoxLayout(self)
        mainLayout.setSpacing(7)
        mainLayout.setContentsMargins(0, 0, 0, 0)
        mainLayout.addWidget(self.searchTable)
        mainLayout.addWidget(self.controlWidget)

        self.currentPage = 0
        self.pages = 0
        self.currentKeyword = ''
        self.searchByType = 'all'

    def create_connections(self):
        self.previousPageButton.clicked.connect(self.previous_page)
        self.nextPageButton.clicked.connect(self.next_page)
        self.jumpNum.returnPressed.connect(self.go_to_page)

        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 init_params(self):
        self.downloadDir = globalSettings.DownloadfilesPath

    def set_download_dir(self, path):
        self.downloadDir = path

    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 listen_online(self):
        if not self.searchTable.rowCount():
            return
        selections = self.searchTable.selectionModel()
        selecteds = selections.selectedIndexes()
        if not len(selecteds):
            return
        row = selecteds[0].row()
        self.searchtable_clicked(row)

    def searchtable_clicked(self, row):
        musicName = self.searchTable.item(row, 1).text()
        artist = self.searchTable.item(row, 2).text()
        title = connect_as_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
        thread = DownloadLrcThread([(title, musicId)])
        thread.setDaemon(True)
        thread.setName('downloadLrc')
        thread.start()
        self.listen_online_signal.emit(title, album, songLink, musicId)

    def add_bunch_to_list(self):
        """向“在线试听”列表批量添加歌曲。"""
        selecteds = self.searchTable.selectedIndexes()
        if not len(selecteds):
            return
        self.added_items = []
        playlistTemp = Playlist()
        playlistTemp.fill_list(Configures.PlaylistOnline)
        musicIdsInOnlineList = playlistTemp.get_items_queue()
        for index in selecteds:
            if index.column() == 0:
                row = index.row()
                musicId = self.searchTable.item(row, 4).text()
                if musicId not in musicIdsInOnlineList:
                    musicName = self.searchTable.item(row, 1).text()
                    artist = self.searchTable.item(row, 2).text()
                    title = connect_as_title(artist, musicName)
                    album = self.searchTable.item(row, 3).text()
                    lrcPath = composite_lyric_path_use_title(title)
                    if os.path.exists(lrcPath):
                        os.remove(lrcPath)
                    self.added_items.append([title, musicId])
                    playlistTemp.add_record(musicId, title,
                                            Configures.ZeroTime, album,
                                            Configures.NoLink, 0, musicId)
        if len(self.added_items):
            playlistTemp.commit_records()
            thread = DownloadLrcThread(self.added_items)
            thread.setDaemon(True)
            thread.setName("downloadLrc")
            thread.start()
            self.add_bunch_to_list_succeed.emit()

    def download(self):
        if not self.searchTable.rowCount():
            return
        hasExisted = []
        self.readyToDownloadSongs = []
        selections = self.searchTable.selectionModel()
        selecteds = selections.selectedIndexes()
        if not len(selecteds):
            return
        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 = connect_as_title(artist, songName)
                musicName = get_full_music_name_from_title(title)
                musicPath = os.path.join(self.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 = Configures.NoLink
                self.readyToDownloadSongs.append(
                    [songLink, musicPath, title, album, musicId])
        self.add_to_download_signal.emit()
        self.setCursor(QCursor(Qt.ArrowCursor))
        if len(hasExisted):
            hasExistFiles = '\n'.join(hasExisted)
            self.show()
            QMessageBox.information(self, '提示',
                                    '以下歌曲已在下载目录中,将不再进行下载!\n%s' % hasExistFiles)

    def searchtype_changed(self, index):
        if index == 0:
            self.searchByType = 'all'
        elif index == 1:
            self.searchByType = 'artist'
        else:
            self.searchByType = 'album'

    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)
            if page == (self.currentPage + 1):
                self.pageNum.setFocus()
                self.jumpNum.setText('%i' % page)
                return
            if page > self.pages or page < 1:
                self.jumpNum.setText('%s' % (self.currentPage + 1))
                QMessageBox.information(None, "提示", "页码范围1~%s" % self.pages)
                return
            self.jumpNum.setText('%i' % page)
        except ValueError:
            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.pageNum.setFocus()

    def search_musics(self, keyword):
        if not keyword:
            QMessageBox.information(self, '提示', '请输入搜索关键词!')
            return False
        self.currentKeyword = keyword
        self.hit = self.show_musics(self.searchByType, self.currentKeyword, 0)
        if self.hit == Configures.UrlError:
            QMessageBox.critical(None, "错误", "联网出错!\n请检查网络连接是否正常!")
            return False
        self.currentPage = 0
        if not self.hit:
            self.jumpNum.setText('0')
            self.pageNum.setText('/ 0')
            QMessageBox.warning(None, "错误", "未找到任何结果!")
            return False
        self.pages = self.hit // Configures.NumSearchOneTime + 1
        self.jumpNum.setText('1')
        self.pageNum.setText('/ %s' % self.pages)
        return True

    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()
        songs, hit = SearchOnline.search_songs(searchByType, keyword, page)
        if hit == Configures.UrlError:
            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)
        return hit

    def jump_to_first_page(self):
        if not self.pages or self.currentPage == 0:
            return
        self.currentPage = 0
        self.show_musics(self.searchByType, self.currentKeyword,
                         self.currentPage)
        self.jumpNum.setText('%s' % (self.currentPage + 1))

    def jump_to_last_page(self):
        if not self.pages or self.currentPage == self.pages - 1:
            return
        self.currentPage = self.pages - 1
        self.show_musics(self.searchByType, self.currentKeyword,
                         self.currentPage)
        self.jumpNum.setText('%s' % (self.currentPage + 1))
Ejemplo n.º 3
0
class SearchFrame(QWidget):
    add_bunch_to_list_succeed = pyqtSignal()
    listen_online_signal = pyqtSignal(str, str, str, str)
    add_to_download_signal = pyqtSignal()
    back_to_main_signal = pyqtSignal()

    def  __init__(self, parent = None):
        super(SearchFrame, self).__init__(parent)
        self.init_params()
        self.setup_ui()
        self.create_connections()
    
    def setup_ui(self):
        self.searchTable = SearchTable()
        self.searchTable.setColumnWidth(0, 39)
        self.searchTable.setColumnWidth(1, 205)
        self.searchTable.setColumnWidth(2, 180)
        self.searchTable.setColumnWidth(3, 180)
        
        self.firstPageButton = QPushButton("首页", clicked = self.jump_to_first_page)
        self.firstPageButton.setFocusPolicy(Qt.NoFocus)
        self.firstPageButton.setFixedHeight(31)
        self.lastPageButton = QPushButton("末页", clicked = self.jump_to_last_page)
        self.lastPageButton.setFocusPolicy(Qt.NoFocus)
        self.lastPageButton.setFixedHeight(31)
        
        self.previousPageButton = QPushButton("上一页")
        self.previousPageButton.setFocusPolicy(Qt.NoFocus)
        self.previousPageButton.setFixedHeight(31)
        
        self.nextPageButton = QPushButton('下一页')
        self.nextPageButton.setFocusPolicy(Qt.NoFocus)
        self.nextPageButton.setFixedHeight(31)
        
        self.jumpNum = QLineEdit('0')
        self.jumpNum.setFocusPolicy(Qt.StrongFocus)
        self.jumpNum.setFixedSize(84, 31)
        self.jumpNum.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
        
        self.pageNum = QLabel("/ 0")
        self.pageNum.setFixedSize(45, 31)
        self.pageNum.setAlignment(Qt.AlignLeft | Qt.AlignVCenter )

#页码栏布局
        pageNumLayout = QHBoxLayout(self.jumpNum)
        pageNumLayout.addStretch()
        pageNumLayout.addWidget(self.pageNum)
        pageNumLayout.setContentsMargins(0, 0, 0, 0)
        pageNumLayout.setSpacing(0)
        pageNumLayout.setContentsMargins(0, 0, 0, 0)
        self.jumpNum.setTextMargins(0, 0, self.pageNum.width(), 0)

#综合布局
        self.controlWidget = QWidget()
        controlLayout = QHBoxLayout(self.controlWidget)
        controlLayout.setContentsMargins(0, 0, 0, 0)
        controlLayout.setSpacing(6)
        controlLayout.addWidget(self.firstPageButton)
        controlLayout.addWidget(self.previousPageButton)
        controlLayout.addWidget(self.jumpNum)
        controlLayout.addWidget(self.nextPageButton)
        controlLayout.addWidget(self.lastPageButton)
        
        mainLayout = QVBoxLayout(self)
        mainLayout.setSpacing(7)
        mainLayout.setContentsMargins(0, 0, 0, 0)
        mainLayout.addWidget(self.searchTable)
        mainLayout.addWidget(self.controlWidget)
        
        self.currentPage = 0
        self.pages = 0
        self.currentKeyword = ''
        self.searchByType = 'all'
    
    def create_connections(self):
        self.previousPageButton.clicked.connect(self.previous_page)
        self.nextPageButton.clicked.connect(self.next_page)
        self.jumpNum.returnPressed.connect(self.go_to_page)

        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 init_params(self):
        self.downloadDir = globalSettings.DownloadfilesPath
    
    def set_download_dir(self, path):
        self.downloadDir = path
    
    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 listen_online(self):
        if not self.searchTable.rowCount():
            return
        selections = self.searchTable.selectionModel()
        selecteds = selections.selectedIndexes()
        if not len(selecteds):
            return
        row = selecteds[0].row()
        self.searchtable_clicked(row)
            
    def searchtable_clicked(self, row):
        musicName = self.searchTable.item(row, 1).text()
        artist = self.searchTable.item(row, 2).text()
        title = connect_as_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
        thread = DownloadLrcThread([(title, musicId)])
        thread.setDaemon(True)
        thread.setName('downloadLrc')
        thread.start()
        self.listen_online_signal.emit(title, album, songLink, musicId)
    
    def add_bunch_to_list(self):
        """向“在线试听”列表批量添加歌曲。"""
        selecteds = self.searchTable.selectedIndexes()
        if not len(selecteds):
            return
        self.added_items = []
        playlistTemp = Playlist()
        playlistTemp.fill_list(Configures.PlaylistOnline)
        musicIdsInOnlineList = playlistTemp.get_items_queue()
        for index in selecteds:
            if index.column() == 0:
                row = index.row()
                musicId = self.searchTable.item(row, 4).text()
                if musicId  not in musicIdsInOnlineList:
                    musicName = self.searchTable.item(row, 1).text()
                    artist = self.searchTable.item(row, 2).text()
                    title = connect_as_title(artist, musicName)
                    album = self.searchTable.item(row, 3).text()
                    lrcPath = composite_lyric_path_use_title(title)
                    if os.path.exists(lrcPath):
                        os.remove(lrcPath)
                    self.added_items.append([title, musicId])
                    playlistTemp.add_record(musicId, title, Configures.ZeroTime, album, Configures.NoLink, 0, musicId)
        if len(self.added_items):
            playlistTemp.commit_records()
            thread = DownloadLrcThread(self.added_items)
            thread.setDaemon(True)
            thread.setName("downloadLrc")
            thread.start()
            self.add_bunch_to_list_succeed.emit()
            
    def download(self):
        if not self.searchTable.rowCount():
            return
        hasExisted = []
        self.readyToDownloadSongs = []
        selections = self.searchTable.selectionModel()
        selecteds = selections.selectedIndexes()
        if  not len(selecteds):
            return
        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 = connect_as_title(artist, songName)
                musicName = get_full_music_name_from_title(title)
                musicPath = os.path.join(self.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 = Configures.NoLink
                self.readyToDownloadSongs.append([songLink, musicPath, title , album, musicId])
        self.add_to_download_signal.emit()
        self.setCursor(QCursor(Qt.ArrowCursor))
        if len(hasExisted):
            hasExistFiles = '\n'.join(hasExisted)
            self.show()
            QMessageBox.information(self, '提示','以下歌曲已在下载目录中,将不再进行下载!\n%s'%hasExistFiles)
    
    def searchtype_changed(self, index):
        if index == 0:
            self.searchByType = 'all'
        elif index == 1:
            self.searchByType = 'artist'
        else:
            self.searchByType = 'album'
        
    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)
            if page == (self.currentPage + 1):
                self.pageNum.setFocus()
                self.jumpNum.setText('%i'%page)
                return
            if page > self.pages or page < 1:
                self.jumpNum.setText('%s'%(self.currentPage + 1))
                QMessageBox.information(None, "提示", "页码范围1~%s"%self.pages)
                return
            self.jumpNum.setText('%i'%page)
        except ValueError :
            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.pageNum.setFocus()
    
    def search_musics(self, keyword):
        if not keyword:
            QMessageBox.information(self, '提示', '请输入搜索关键词!')
            return False
        self.currentKeyword = keyword
        self.hit  =  self.show_musics(self.searchByType, self.currentKeyword, 0)
        if self.hit == Configures.UrlError:
            QMessageBox.critical(None, "错误", "联网出错!\n请检查网络连接是否正常!")     
            return False
        self.currentPage = 0
        if not self.hit:
            self.jumpNum.setText('0')
            self.pageNum.setText('/ 0')
            QMessageBox.warning(None, "错误", "未找到任何结果!")     
            return False
        self.pages = self.hit//Configures.NumSearchOneTime + 1
        self.jumpNum.setText('1')
        self.pageNum.setText('/ %s'%self.pages)
        return True
    
    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()
        songs, hit = SearchOnline.search_songs(searchByType, keyword, page)
        if hit == Configures.UrlError:
            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)
        return hit
        
    def jump_to_first_page(self):
        if not self.pages or self.currentPage ==0:
            return
        self.currentPage = 0
        self.show_musics(self.searchByType, self.currentKeyword, self.currentPage)
        self.jumpNum.setText('%s'%(self.currentPage + 1))
    
    def jump_to_last_page(self):
        if not self.pages or self.currentPage == self.pages - 1:
            return
        self.currentPage = self.pages - 1
        self.show_musics(self.searchByType, self.currentKeyword, self.currentPage)
        self.jumpNum.setText('%s'%(self.currentPage + 1))