Example #1
0
    def setup_ui(self):
        self.setObjectName('playbackPage')

        #歌手信息页
        self.artistHeadLabel = QLabel(self)
        self.artistHeadLabel.setFixedSize(QSize(90, 90))
        self.artistHeadLabel.setScaledContents(True)
        self.artistName = NewLabel(self, True)
        self.artistName.setFixedSize(QSize(90, 30))
        self.artistGender = QLabel("性别:未知", self)
        self.artistBirthday = QLabel("生日:未知", self)
        self.artistConstellation = QLabel("星座:未知", self)
        self.artistLanguage = QLabel("语言:未知", self)
        self.artistBirthplace = QLabel("出生地:未知", self)
        self.artistDetail = MyTextEdit(self)

        #刷新歌手信息缓存按键
        self.refreshBtn = QPushButton(self)
        self.refreshBtn.setFocusPolicy(Qt.NoFocus)
        self.refreshBtn.setIcon(QIcon(IconsHub.Refresh))
        self.refreshBtn.setText('刷新')
        self.refreshBtn.setToolTip("刷新歌手信息")
        self.refreshBtn.setFixedSize(QSize(70, 30))

        vbox1 = QVBoxLayout()
        vbox1.setSpacing(10)
        vbox1.addWidget(self.artistHeadLabel)
        vbox1.addWidget(self.artistName)

        hbox1 = QHBoxLayout()
        hbox1.addWidget(self.artistGender)
        hbox1.addWidget(self.artistBirthday)

        hbox2 = QHBoxLayout()
        hbox2.addWidget(self.artistConstellation)
        hbox2.addWidget(self.artistLanguage)

        hbox3 = QHBoxLayout()
        hbox3.addWidget(self.artistBirthplace)
        hbox3.addWidget(self.refreshBtn)
        vbox2 = QVBoxLayout()
        vbox2.addLayout(hbox1)
        vbox2.addLayout(hbox2)
        vbox2.addLayout(hbox3)
        hbox4 = QHBoxLayout()
        hbox4.setSpacing(30)
        hbox4.addLayout(vbox1)
        hbox4.addLayout(vbox2)

        mainLayout = QVBoxLayout(self)
        mainLayout.addLayout(hbox4)
        mainLayout.addWidget(self.artistDetail)
    def setup_ui(self):
        self.setObjectName('playbackPage')

        #歌手信息页
        self.artistHeadLabel = QLabel(self)
        self.artistHeadLabel.setFixedSize(QSize(90, 90))
        self.artistHeadLabel.setScaledContents(True)
        self.artistName = NewLabel(self, True)
        self.artistName.setFixedSize(QSize(90, 30))
        self.artistGender = QLabel("性别:未知", self)
        self.artistBirthday = QLabel("生日:未知", self)
        self.artistConstellation = QLabel("星座:未知", self)
        self.artistLanguage = QLabel("语言:未知", self)
        self.artistBirthplace = QLabel("出生地:未知", self)
        self.artistDetail = MyTextEdit(self)
        
        #刷新歌手信息缓存按键
        self.refreshBtn = QPushButton(self)
        self.refreshBtn.setFocusPolicy(Qt.NoFocus)
        self.refreshBtn.setIcon(QIcon(IconsHub.Refresh))
        self.refreshBtn.setText('刷新')
        self.refreshBtn.setToolTip("刷新歌手信息")
        self.refreshBtn.setFixedSize(QSize(70, 30))
        
        vbox1 = QVBoxLayout()
        vbox1.setSpacing(10)
        vbox1.addWidget(self.artistHeadLabel)
        vbox1.addWidget(self.artistName)
        
        hbox1 = QHBoxLayout()
        hbox1.addWidget(self.artistGender)
        hbox1.addWidget(self.artistBirthday)
        
        hbox2 = QHBoxLayout()
        hbox2.addWidget(self.artistConstellation)
        hbox2.addWidget(self.artistLanguage)
        
        hbox3 = QHBoxLayout()
        hbox3.addWidget(self.artistBirthplace)
        hbox3.addWidget(self.refreshBtn)
        vbox2 = QVBoxLayout()
        vbox2.addLayout(hbox1)
        vbox2.addLayout(hbox2)
        vbox2.addLayout(hbox3)
        hbox4 = QHBoxLayout()
        hbox4.setSpacing(30)
        hbox4.addLayout(vbox1)
        hbox4.addLayout(vbox2)
        
        mainLayout = QVBoxLayout(self)
        mainLayout.addLayout(hbox4)
        mainLayout.addWidget(self.artistDetail)
class PlaybackPanel(SpecialLabel):
    desktop_lyric_state_changed_signal = pyqtSignal(bool)
    playmode_changed_signal = pyqtSignal(int, int)
    media_player_notify_signal = pyqtSignal(int)
    muted_changed_signal = pyqtSignal(int)
    mark_favorite_completed_signal = pyqtSignal()
    current_media_changed_signal = pyqtSignal()
    music_ended_signal = pyqtSignal()
    update_window_lyric_signal = pyqtSignal(str, str)
    show_artist_info_signal = pyqtSignal(str)
    dont_hide_main_window_signal = pyqtSignal()

    def __init__(self, parent=None):
        super(PlaybackPanel, self).__init__(parent)
        self.initial_mediaplayer()
        self.create_actions()
        self.setup_ui()
        self.create_connections()
        self.initial_params()

    def create_connections(self):
        self.artistHeadLabel.clicked.connect(self.show_artist_info)
        self.desktopLyric.hide_desktop_lyric_signal.connect(
            self.desktop_lyric_closed)
        self.seekSlider.valueChanged.connect(self.slider_value_changed)
        self.seekSlider.sliderPressed.connect(self.slider_pressed)
        self.seekSlider.sliderReleased.connect(self.seek)
        self.mediaPlayer.positionChanged.connect(self.tick)
        self.mediaPlayer.mutedChanged.connect(self.muted_changed_signal.emit)
        self.mediaPlayer.stateChanged.connect(self.state_changed)
        self.mediaPlayer.durationChanged.connect(self.duration_changed)
        self.mediaPlayer.mediaStatusChanged.connect(self.media_status_changed)
        self.mediaPlayer.currentMediaChanged.connect(
            self.current_media_changed)

    def initial_mediaplayer(self):
        self.mediaPlayer = QMediaPlayer()
        self.mediaPlayer.setNotifyInterval(500)
        self.set_volume(globalSettings.Volume)

    def initial_params(self):
        self.playlist = None
        self.artistName = 'Zheng-Yejian'
        self.clickPlayFlag = False  #用来标志一首歌是否是主动点击选中的
        self.timerFlag = False
        self.timeStart = 0
        self.timeSpan = 0
        self.sourcePath = ''
        self.errorType = Configures.NoError
        self.currentSourceRow = -1
        self.nearPlayedSongs = []
        self.downloadDir = globalSettings.DownloadfilesPath
        self.songinfosManager = SonginfosManager()
        self.totalTime = Configures.ZeroTime
        self.playmode = Configures.PlaymodeRandom  #播放模式指示器
        playlistTemp = Playlist()
        playlistTemp.fill_list(Configures.PlaylistFavorite)
        self.lovedSongs = playlistTemp.get_titles()

    def set_playlist(self, playlist):
        self.playlist = playlist
        self.currentSourceRow = self.playlist.get_current_row()

    def create_actions(self):
        self.nextAction = QAction(QIcon(IconsHub.ControlNext),
                                  "下一首",
                                  self,
                                  enabled=True,
                                  triggered=self.next_song)

        self.playAction = QAction(QIcon(IconsHub.ControlPlay),
                                  "播放/暂停",
                                  self,
                                  enabled=True,
                                  triggered=self.play_music)

        self.previousAction = QAction(QIcon(IconsHub.ControlPrevious),
                                      "上一首",
                                      self,
                                      enabled=True,
                                      triggered=self.previous_song)

        self.stopAction = QAction(QIcon(IconsHub.ControlStop),
                                  "停止",
                                  self,
                                  enabled=True,
                                  triggered=self.stop_music_but_timing)

    def get_play_button_action(self):
        return self.playAction

    def get_previous_button_action(self):
        return self.previousAction

    def get_next_button_action(self):
        return self.nextAction

    def get_stop_button_action(self):
        return self.stopAction

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

    def get_loved_songs(self):
        return self.lovedSongs

    def get_songinfos_manager(self):
        return self.songinfosManager

    def setup_ui(self):
        self.setFixedHeight(50)
        #桌面歌词标签
        self.desktopLyric = desktop_lyric.DesktopLyric()
        self.desktopLyric.set_color(globalSettings.DesktoplyricColors)
        #3个标签
        self.artistHeadLabel = LabelButton()
        self.artistHeadLabel.setToolTip(self.tr('查看歌手信息'))
        self.artistHeadLabel.setFixedSize(QSize(42, 42))
        self.artistHeadLabel.setScaledContents(True)
        self.artistHeadLabel.setPixmap(QPixmap(IconsHub.Anonymous))

        self.musicTitleLabel = NewLabel()
        self.musicTitleLabel.setObjectName('musicTitleLabel')
        self.musicTitleLabel.setFixedSize(QSize(370, 20))
        self.musicTitleLabel.setText("Zheng-Yejian._.XYPLAYER")
        self.timeLabel = QLabel("00:00/00:00")
        self.timeLabel.setObjectName('timeLabel')
        self.timeLabel.setFixedHeight(20)
        self.timeLabel.setAlignment(Qt.AlignRight and Qt.AlignVCenter)

        #五个基本按键
        self.playmodeButton = QToolButton(clicked=self.change_playmode)
        self.playmodeButton.setFocusPolicy(Qt.NoFocus)

        self.playmodeButton.setIcon(QIcon(IconsHub.PlaymodeRandom))
        self.playmodeButton.setIconSize(QSize(25, 25))
        self.playmodeButton.setToolTip('随机播放')

        self.favoriteButton = QToolButton(clicked=self.mark_as_favorite)
        self.favoriteButton.setFocusPolicy(Qt.NoFocus)
        self.favoriteButton.setToolTip('收藏')
        self.favoriteButton.setIcon(QIcon(IconsHub.Favorites))
        self.favoriteButton.setIconSize(QSize(20, 20))

        self.previousButton = QToolButton()
        self.previousButton.setFocusPolicy(Qt.NoFocus)
        self.previousButton.setIconSize(QSize(40, 40))
        self.previousButton.setShortcut(QKeySequence("Ctrl + Left"))
        self.previousButton.setDefaultAction(self.previousAction)

        self.playButton = QToolButton()
        self.playButton.setFocusPolicy(Qt.NoFocus)
        self.playButton.setIconSize(QSize(40, 40))
        self.playButton.setShortcut(QKeySequence("Ctrl + Down"))
        self.playButton.setDefaultAction(self.playAction)

        self.nextButton = QToolButton()
        self.nextButton.setFocusPolicy(Qt.NoFocus)
        self.nextButton.setIconSize(QSize(40, 40))
        self.nextButton.setFocusPolicy(Qt.NoFocus)
        self.nextButton.setShortcut(QKeySequence("Ctrl + Right"))
        self.nextButton.setDefaultAction(self.nextAction)

        self.desktopLyricButton = QToolButton(clicked=self.show_desktop_lyric)
        self.desktopLyricButton.setToolTip(self.tr("桌面歌词"))
        self.desktopLyricButton.setFocusPolicy(Qt.NoFocus)
        self.desktopLyricButton.setIcon(QIcon(IconsHub.DesktopLyric))
        self.desktopLyricButton.setIconSize(QSize(25, 25))

        self.seekSlider = QSlider(Qt.Horizontal)
        self.seekSlider.setObjectName('seekSlider')
        self.seekSlider.setFixedHeight(20)
        self.seekSlider.setFocusPolicy(Qt.NoFocus)
        self.seekSlider.setRange(0, 0)

        hbox1 = QHBoxLayout()
        hbox1.addWidget(self.favoriteButton)
        hbox1.addWidget(self.musicTitleLabel)
        hbox1.addStretch()
        hbox1.addWidget(self.timeLabel)
        vbox1 = QVBoxLayout()
        vbox1.addLayout(hbox1)
        vbox1.setSpacing(5)
        vbox1.addWidget(self.seekSlider)

        mainLayout = QHBoxLayout(self)
        mainLayout.setContentsMargins(2, 0, 0, 0)
        mainLayout.addWidget(self.artistHeadLabel)
        mainLayout.addWidget(self.previousButton)
        mainLayout.addWidget(self.playButton)
        mainLayout.addWidget(self.nextButton)
        mainLayout.addLayout(vbox1)
        mainLayout.addWidget(self.playmodeButton)
        mainLayout.addWidget(self.desktopLyricButton)

    def show_desktop_lyric(self):
        if self.desktopLyric.isHidden():
            beToOff = True
            self.desktopLyric.show()
            self.desktopLyric.original_place()
        else:
            beToOff = False
            self.desktopLyric.hide()
        self.desktop_lyric_state_changed_signal.emit(beToOff)

    def desktop_lyric_closed(self):
        self.desktop_lyric_state_changed_signal.emit(False)

    def change_playmode(self):
        oldPlaymode = self.playmode
        if self.playmode == Configures.PlaymodeRandom:
            self.set_new_playmode(Configures.PlaymodeOrder)
        elif self.playmode == Configures.PlaymodeOrder:
            self.set_new_playmode(Configures.PlaymodeSingle)
        elif self.playmode == Configures.PlaymodeSingle:
            self.set_new_playmode(Configures.PlaymodeRandom)
        self.playmode_changed_signal.emit(oldPlaymode, self.playmode)

    def set_new_playmode(self, playmode):
        self.playmode = playmode
        if playmode == Configures.PlaymodeRandom:
            iconPath = IconsHub.PlaymodeRandom
            toolTip = Configures.PlaymodeRandomText
        elif playmode == Configures.PlaymodeOrder:
            iconPath = IconsHub.PlaymodeOrder
            toolTip = Configures.PlaymodeOrderText
        else:
            iconPath = IconsHub.PlaymodeSingle
            toolTip = Configures.PlaymodeSingleText
        self.playmodeButton.setIcon(QIcon(iconPath))
        self.playmodeButton.setToolTip(toolTip)

    def ui_initial(self):
        self.mediaPlayer.stop()
        self.totalTime = '00:00'
        self.playAction.setIcon(QIcon(IconsHub.ControlPlay))
        self.musicTitleLabel.setText("Zheng-Yejian._.XYPLAYER")
        self.artistName = 'Zheng-Yejian'
        self.artistHeadLabel.setPixmap(QPixmap(IconsHub.Anonymous))
        self.seekSlider.setRange(0, 0)
        self.favoriteButton.setIcon(QIcon(IconsHub.Favorites))
        self.favoriteButton.setToolTip('收藏')
        self.timeLabel.setText("00:00/00:00")

    def set_volume(self, volume):
        self.mediaPlayer.setVolume(volume)

    def set_muted(self, muted):
        self.mediaPlayer.setMuted(muted)

    def tick(self):
        currentTime = self.mediaPlayer.position()
        self.seekSlider.setValue(currentTime)
        cTime = format_position_to_mmss(currentTime // 1000)
        self.timeLabel.setText(cTime + '/' + self.totalTime)
        self.media_player_notify_signal.emit(currentTime)

    def slider_value_changed(self, value):
        cTime = format_position_to_mmss(value // 1000)
        self.timeLabel.setText('%s/%s' % (cTime, self.totalTime))
        self.media_player_notify_signal.emit(value)

    def slider_pressed(self):
        self.mediaPlayer.positionChanged.disconnect(self.tick)

    def seek(self):
        if self.mediaPlayer.state() == QMediaPlayer.StoppedState:
            self.mediaPlayer.play()
            self.mediaPlayer.setPosition(self.seekSlider.value())
        else:
            self.mediaPlayer.setPosition(self.seekSlider.value())
            self.mediaPlayer.play()
        self.mediaPlayer.positionChanged.connect(self.tick)

    def duration_changed(self, duration):
        self.seekSlider.setMaximum(duration)
        exactTotalTime = format_position_to_mmss(self.mediaPlayer.duration() //
                                                 1000)
        self.timeLabel.setText('%s/%s' % (Configures.ZeroTime, exactTotalTime))
        if self.totalTime != exactTotalTime:
            self.totalTime = exactTotalTime
            self.playlist.set_music_time_at(self.currentSourceRow,
                                            exactTotalTime)

    def check_favorite(self):
        if self.currentSourceRow >= 0:
            if self.playlist.get_music_title_at(
                    self.currentSourceRow) in self.lovedSongs:
                self.favoriteButton.setIcon(QIcon(IconsHub.Favorites))
                self.favoriteButton.setToolTip('取消收藏')
            else:
                self.favoriteButton.setIcon(QIcon(IconsHub.FavoritesNo))
                self.favoriteButton.setToolTip('收藏')
            if self.playlist.get_name() == Configures.PlaylistFavorite:
                self.favoriteButton.setToolTip('收藏')

    def mark_as_favorite(self):
        if self.playlist.get_name(
        ) == Configures.PlaylistFavorite or not self.playlist.length(
        ) or self.currentSourceRow < 0:
            return
        path = self.playlist.get_music_path_at(self.currentSourceRow)
        title = self.playlist.get_music_title_at(self.currentSourceRow)
        if self.playlist.get_name() == Configures.PlaylistOnline:
            musicName = get_full_music_name_from_title(title)
            musicPath = os.path.join(self.downloadDir, musicName)
            musicPathO = os.path.join(Configures.MusicsDir, musicName)
            if not os.path.exists(musicPath) and not os.path.exists(
                    musicPathO):
                QMessageBox.information(self, '提示', '请先下载该歌曲再添加喜欢!')
                return
            if os.path.exists(musicPath):
                path = musicPath
            else:
                path = musicPathO
        elif not os.path.exists(path):
            QMessageBox.information(self, "提示",
                                    "路径'" + "%s" % path + "'无效,无法标记喜欢!")
            return
        playlistTemp = Playlist()
        playlistTemp.fill_list(Configures.PlaylistFavorite)
        if title in self.lovedSongs:
            playlistTemp.remove_item_at(self.lovedSongs.index(title))
            playlistTemp.commit_records()
            self.lovedSongs.remove(title)
            self.favoriteButton.setIcon(QIcon(IconsHub.FavoritesNo))
            self.favoriteButton.setToolTip("收藏")
        else:
            playlistTemp.add_item_from_path(path)
            playlistTemp.commit_records()
            self.lovedSongs.append(title)
            self.favoriteButton.setIcon(QIcon(IconsHub.Favorites))
            self.favoriteButton.setToolTip("取消收藏")
        self.mark_favorite_completed_signal.emit()

    def show_artist_info(self):
        if self.artistName:
            self.show_artist_info_signal.emit(self.artistName)

    def decide_to_play_or_pause(self, row):
        if row != self.currentSourceRow:
            self.set_media_source_at_row(row, clickPlayFlag=True)
        elif self.mediaPlayer.state() in (QMediaPlayer.PausedState,
                                          QMediaPlayer.StoppedState):
            self.mediaPlayer.play()
        elif self.mediaPlayer.state() == QMediaPlayer.PlayingState:
            self.mediaPlayer.pause()

    def set_media_source_at_row(self, row, clickPlayFlag=False):
        if not self.playlist.length() or row < 0:
            return
        self.stop_music()
        self.clickPlayFlag = clickPlayFlag
        self.playlist.set_current_row(row)
        sourcePath = self.playlist.get_music_path_at(row)
        self.title = self.playlist.get_music_title_at(row)
        self.sourceTrace = 'local' if self.playlist.get_music_id_at(
            row) == Configures.LocalMusicId else 'online'
        self.artistName, self.musicName = get_artist_and_musicname_from_title(
            self.title)
        self.playlistName = self.playlist.get_name()
        self.totalTime = self.playlist.get_music_time_at(row)
        self.album = self.playlist.get_music_album_at(row)
        self.errorType = Configures.NoError
        isAnUrl = False
        if not os.path.exists(sourcePath):
            if self.playlist.get_name() == Configures.PlaylistOnline:
                if sourcePath == Configures.NoLink:
                    musicId = self.playlist.get_music_id_at(row)
                    sourcePath = SearchOnline.get_song_link(musicId)
                    if sourcePath:
                        self.playlist.set_music_path_at(row, sourcePath)
                    else:
                        self.errorType = Configures.UrlError
                isAnUrl = True
            else:
                self.errorType = Configures.PathError
                sourcePath = "/usr/share/sounds/error_happened.ogg"
        if self.errorType == Configures.NoError:
            self.sourcePath = sourcePath
            self.musicFileName = get_base_name_from_path(sourcePath)
            self.playedDate = get_time_of_now()
            self.songinfosManager.update_datas_of_item(
                self.musicFileName, self.playedDate, self.musicName,
                self.artistName, self.totalTime, self.album, self.playlistName)
            if not self.timerFlag:
                self.timerFlag = True
                self.timeSpan = 0
            if isAnUrl:
                url = QUrl(sourcePath)
            else:
                url = QUrl.fromLocalFile(sourcePath)
            self.play_from_url(url)
        else:
            self.timerFlag = False
            self.dont_hide_main_window_signal.emit()
            if self.errorType == Configures.DisnetError:
                QMessageBox.critical(
                    self, "错误", "联网出错!\n无法联网播放歌曲'%s'!\n您最好在网络畅通时下载该曲目!" %
                    self.playlist.get_music_title_at(row))
            elif self.errorType == Configures.PathError:
                QMessageBox.information(
                    self, "提示", "路径'%s'无效,请尝试重新下载并添加对应歌曲!" %
                    self.playlist.get_music_path_at(row))

    def play_from_url(self, url):
        mediaContent = QMediaContent(url)
        self.mediaPlayer.setMedia(mediaContent)
        self.mediaPlayer.play()

    def state_changed(self, newState):
        if self and newState in [
                QMediaPlayer.PlayingState, QMediaPlayer.PausedState,
                QMediaPlayer.StoppedState
        ]:
            if not self.playlist.length():
                return
            iconPath = IconsHub.ControlPause
            if newState in [
                    QMediaPlayer.StoppedState, QMediaPlayer.PausedState
            ]:
                iconPath = IconsHub.ControlPlay
            icon = QIcon(iconPath)
            self.playAction.setIcon(icon)
            if self.timerFlag:
                if newState == QMediaPlayer.PlayingState:
                    self.timeStart = time.time()
                else:
                    self.timeSpan += (time.time() - self.timeStart)

    def media_status_changed(self, status):
        if status == QMediaPlayer.EndOfMedia:
            self.music_finished()

    def music_finished(self):
        if self.errorType == Configures.NoError:
            self.next_song()

    def play_music(self):
        if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
            self.mediaPlayer.pause()
        else:
            self.mediaPlayer.play()

    def stop_music_but_timing(self):
        self.mediaPlayer.stop()
        self.seekSlider.setValue(0)
        self.media_player_notify_signal.emit(-0.5)

    def stop_music(self):
        self.stop_music_but_timing()
        if self.timerFlag:
            self.timerFlag = False
            InfosList = [
                self.playedDate, self.musicFileName, self.musicName,
                self.artistName, self.album,
                '%i' % change_mmss_to_seconds(self.totalTime),
                '%.1f' % self.timeSpan, self.playlistName, self.sourcePath,
                '%i' % (self.title in self.lovedSongs), self.sourceTrace,
                Configures.Playmodes[self.playmode],
                '%i' % self.clickPlayFlag
            ]
            log_playback_history(organized_list_as_str(InfosList))
            self.songinfosManager.update_time_span_relate_of_item(
                self.musicFileName, self.timeSpan, self.clickPlayFlag)
            self.clickPlayFlag = False

    def get_next_random_row(self):
        listTemp = list(self.playlist.get_ids() - set(self.nearPlayedSongs))
        ran = random.randint(0, len(listTemp) - 1)
        return self.playlist.get_items_queue().index(listTemp[ran])

    def get_next_single_row(self):
        nextRow = self.currentSourceRow
        if nextRow < 0:
            nextRow = 0
        return nextRow

    def get_next_order_row(self, reverse=False):
        if reverse:
            if self.currentSourceRow < 0:
                self.currentSourceRow = 0
            return (self.currentSourceRow - 1) % self.playlist.length()
        return (self.currentSourceRow + 1) % self.playlist.length()

    def previous_song(self):
        self.play_source_on_next_row(reverse=True)

    def next_song(self):
        self.play_source_on_next_row()

    def play_source_on_next_row(self, reverse=False):
        if not self.playlist.length():
            return
        if self.mediaPlayer.position() > 20:
            self.music_ended_signal.emit()
        nextRow = 0
        if self.playmode == Configures.PlaymodeRandom:
            nextRow = self.get_next_random_row()
        elif self.playmode == Configures.PlaymodeOrder:
            nextRow = self.get_next_order_row(reverse)
        elif self.playmode == Configures.PlaymodeSingle:
            nextRow = self.get_next_single_row()
        self.set_media_source_at_row(nextRow)

    def current_media_changed(self):
        if not self.playlist.length():
            return
        self.current_media_changed_signal.emit()
        self.update_parameters()
        self.update_near_played_queue()
        self.check_favorite()

    def update_parameters(self):
        self.currentSourceRow = self.playlist.get_current_row()
        self.musicTitleLabel.setText(self.title)
        self.playAction.setText(self.musicName)
        imagePath = SearchOnline.get_artist_image_path(self.artistName)
        if imagePath:
            pixmap = QPixmap(imagePath)
        else:
            pixmap = QPixmap(IconsHub.Anonymous)
        self.artistHeadLabel.setPixmap(pixmap)
        musicId = self.playlist.get_music_id_at(self.currentSourceRow)
        self.update_window_lyric_signal.emit(self.title, musicId)

    def update_near_played_queue(self):
        self.currentSourceId = self.playlist.get_music_path_at(
            self.currentSourceRow)
        if self.playlist.get_name() == Configures.PlaylistOnline:
            self.currentSourceId = self.playlist.get_music_id_at(
                self.currentSourceRow)
        if self.currentSourceId not in self.nearPlayedSongs:
            self.nearPlayedSongs.append(self.currentSourceId)
        while len(self.nearPlayedSongs) >= self.playlist.length() * 4 / 5:
            del self.nearPlayedSongs[0]

    def add_title_into_loved_songs(self, title):
        self.lovedSongs.append(title)
    def setup_ui(self):
        self.setFixedHeight(50)
        #桌面歌词标签
        self.desktopLyric = desktop_lyric.DesktopLyric()
        self.desktopLyric.set_color(globalSettings.DesktoplyricColors)
        #3个标签
        self.artistHeadLabel = LabelButton()
        self.artistHeadLabel.setToolTip(self.tr('查看歌手信息'))
        self.artistHeadLabel.setFixedSize(QSize(42, 42))
        self.artistHeadLabel.setScaledContents(True)
        self.artistHeadLabel.setPixmap(QPixmap(IconsHub.Anonymous))

        self.musicTitleLabel = NewLabel()
        self.musicTitleLabel.setObjectName('musicTitleLabel')
        self.musicTitleLabel.setFixedSize(QSize(370, 20))
        self.musicTitleLabel.setText("Zheng-Yejian._.XYPLAYER")
        self.timeLabel = QLabel("00:00/00:00")
        self.timeLabel.setObjectName('timeLabel')
        self.timeLabel.setFixedHeight(20)
        self.timeLabel.setAlignment(Qt.AlignRight and Qt.AlignVCenter)

        #五个基本按键
        self.playmodeButton = QToolButton(clicked=self.change_playmode)
        self.playmodeButton.setFocusPolicy(Qt.NoFocus)

        self.playmodeButton.setIcon(QIcon(IconsHub.PlaymodeRandom))
        self.playmodeButton.setIconSize(QSize(25, 25))
        self.playmodeButton.setToolTip('随机播放')

        self.favoriteButton = QToolButton(clicked=self.mark_as_favorite)
        self.favoriteButton.setFocusPolicy(Qt.NoFocus)
        self.favoriteButton.setToolTip('收藏')
        self.favoriteButton.setIcon(QIcon(IconsHub.Favorites))
        self.favoriteButton.setIconSize(QSize(20, 20))

        self.previousButton = QToolButton()
        self.previousButton.setFocusPolicy(Qt.NoFocus)
        self.previousButton.setIconSize(QSize(40, 40))
        self.previousButton.setShortcut(QKeySequence("Ctrl + Left"))
        self.previousButton.setDefaultAction(self.previousAction)

        self.playButton = QToolButton()
        self.playButton.setFocusPolicy(Qt.NoFocus)
        self.playButton.setIconSize(QSize(40, 40))
        self.playButton.setShortcut(QKeySequence("Ctrl + Down"))
        self.playButton.setDefaultAction(self.playAction)

        self.nextButton = QToolButton()
        self.nextButton.setFocusPolicy(Qt.NoFocus)
        self.nextButton.setIconSize(QSize(40, 40))
        self.nextButton.setFocusPolicy(Qt.NoFocus)
        self.nextButton.setShortcut(QKeySequence("Ctrl + Right"))
        self.nextButton.setDefaultAction(self.nextAction)

        self.desktopLyricButton = QToolButton(clicked=self.show_desktop_lyric)
        self.desktopLyricButton.setToolTip(self.tr("桌面歌词"))
        self.desktopLyricButton.setFocusPolicy(Qt.NoFocus)
        self.desktopLyricButton.setIcon(QIcon(IconsHub.DesktopLyric))
        self.desktopLyricButton.setIconSize(QSize(25, 25))

        self.seekSlider = QSlider(Qt.Horizontal)
        self.seekSlider.setObjectName('seekSlider')
        self.seekSlider.setFixedHeight(20)
        self.seekSlider.setFocusPolicy(Qt.NoFocus)
        self.seekSlider.setRange(0, 0)

        hbox1 = QHBoxLayout()
        hbox1.addWidget(self.favoriteButton)
        hbox1.addWidget(self.musicTitleLabel)
        hbox1.addStretch()
        hbox1.addWidget(self.timeLabel)
        vbox1 = QVBoxLayout()
        vbox1.addLayout(hbox1)
        vbox1.setSpacing(5)
        vbox1.addWidget(self.seekSlider)

        mainLayout = QHBoxLayout(self)
        mainLayout.setContentsMargins(2, 0, 0, 0)
        mainLayout.addWidget(self.artistHeadLabel)
        mainLayout.addWidget(self.previousButton)
        mainLayout.addWidget(self.playButton)
        mainLayout.addWidget(self.nextButton)
        mainLayout.addLayout(vbox1)
        mainLayout.addWidget(self.playmodeButton)
        mainLayout.addWidget(self.desktopLyricButton)
class PlaybackPanel(SpecialLabel):
    desktop_lyric_state_changed_signal = pyqtSignal(bool)
    playmode_changed_signal = pyqtSignal(int, int)
    media_player_notify_signal = pyqtSignal(int)
    muted_changed_signal = pyqtSignal(int)
    mark_favorite_completed_signal = pyqtSignal()
    current_media_changed_signal = pyqtSignal()
    music_ended_signal = pyqtSignal()
    update_window_lyric_signal = pyqtSignal(str, str)
    show_artist_info_signal = pyqtSignal(str)
    dont_hide_main_window_signal = pyqtSignal()

    def __init__(self, parent=None):
        super(PlaybackPanel, self).__init__(parent)
        self.initial_mediaplayer()
        self.create_actions()
        self.setup_ui()
        self.create_connections()
        self.initial_params()

    def create_connections(self):
        self.artistHeadLabel.clicked.connect(self.show_artist_info)
        self.desktopLyric.hide_desktop_lyric_signal.connect(self.desktop_lyric_closed)
        self.seekSlider.valueChanged.connect(self.slider_value_changed)
        self.seekSlider.sliderPressed.connect(self.slider_pressed)
        self.seekSlider.sliderReleased.connect(self.seek)
        self.mediaPlayer.positionChanged.connect(self.tick)
        self.mediaPlayer.mutedChanged.connect(self.muted_changed_signal.emit)
        self.mediaPlayer.stateChanged.connect(self.state_changed)
        self.mediaPlayer.durationChanged.connect(self.duration_changed)
        self.mediaPlayer.mediaStatusChanged.connect(self.media_status_changed)
        self.mediaPlayer.currentMediaChanged.connect(self.current_media_changed)

    def initial_mediaplayer(self):
        self.mediaPlayer = QMediaPlayer()
        self.mediaPlayer.setNotifyInterval(500)
        self.set_volume(globalSettings.Volume)

    def initial_params(self):
        self.playlist = None
        self.artistName = "Zheng-Yejian"
        self.clickPlayFlag = False  # 用来标志一首歌是否是主动点击选中的
        self.timerFlag = False
        self.timeStart = 0
        self.timeSpan = 0
        self.sourcePath = ""
        self.errorType = Configures.NoError
        self.currentSourceRow = -1
        self.nearPlayedSongs = []
        self.downloadDir = globalSettings.DownloadfilesPath
        self.songinfosManager = SonginfosManager()
        self.totalTime = Configures.ZeroTime
        self.playmode = Configures.PlaymodeRandom  # 播放模式指示器
        playlistTemp = Playlist()
        playlistTemp.fill_list(Configures.PlaylistFavorite)
        self.lovedSongs = playlistTemp.get_titles()

    def set_playlist(self, playlist):
        self.playlist = playlist
        self.currentSourceRow = self.playlist.get_current_row()

    def create_actions(self):
        self.nextAction = QAction(QIcon(IconsHub.ControlNext), "下一首", self, enabled=True, triggered=self.next_song)

        self.playAction = QAction(QIcon(IconsHub.ControlPlay), "播放/暂停", self, enabled=True, triggered=self.play_music)

        self.previousAction = QAction(
            QIcon(IconsHub.ControlPrevious), "上一首", self, enabled=True, triggered=self.previous_song
        )

        self.stopAction = QAction(
            QIcon(IconsHub.ControlStop), "停止", self, enabled=True, triggered=self.stop_music_but_timing
        )

    def get_play_button_action(self):
        return self.playAction

    def get_previous_button_action(self):
        return self.previousAction

    def get_next_button_action(self):
        return self.nextAction

    def get_stop_button_action(self):
        return self.stopAction

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

    def get_loved_songs(self):
        return self.lovedSongs

    def get_songinfos_manager(self):
        return self.songinfosManager

    def setup_ui(self):
        self.setFixedHeight(50)
        # 桌面歌词标签
        self.desktopLyric = desktop_lyric.DesktopLyric()
        self.desktopLyric.set_color(globalSettings.DesktoplyricColors)
        # 3个标签
        self.artistHeadLabel = LabelButton()
        self.artistHeadLabel.setToolTip(self.tr("查看歌手信息"))
        self.artistHeadLabel.setFixedSize(QSize(42, 42))
        self.artistHeadLabel.setScaledContents(True)
        self.artistHeadLabel.setPixmap(QPixmap(IconsHub.Anonymous))

        self.musicTitleLabel = NewLabel()
        self.musicTitleLabel.setObjectName("musicTitleLabel")
        self.musicTitleLabel.setFixedSize(QSize(370, 20))
        self.musicTitleLabel.setText("Zheng-Yejian._.XYPLAYER")
        self.timeLabel = QLabel("00:00/00:00")
        self.timeLabel.setObjectName("timeLabel")
        self.timeLabel.setFixedHeight(20)
        self.timeLabel.setAlignment(Qt.AlignRight and Qt.AlignVCenter)

        # 五个基本按键
        self.playmodeButton = QToolButton(clicked=self.change_playmode)
        self.playmodeButton.setFocusPolicy(Qt.NoFocus)

        self.playmodeButton.setIcon(QIcon(IconsHub.PlaymodeRandom))
        self.playmodeButton.setIconSize(QSize(25, 25))
        self.playmodeButton.setToolTip("随机播放")

        self.favoriteButton = QToolButton(clicked=self.mark_as_favorite)
        self.favoriteButton.setFocusPolicy(Qt.NoFocus)
        self.favoriteButton.setToolTip("收藏")
        self.favoriteButton.setIcon(QIcon(IconsHub.Favorites))
        self.favoriteButton.setIconSize(QSize(20, 20))

        self.previousButton = QToolButton()
        self.previousButton.setFocusPolicy(Qt.NoFocus)
        self.previousButton.setIconSize(QSize(40, 40))
        self.previousButton.setShortcut(QKeySequence("Ctrl + Left"))
        self.previousButton.setDefaultAction(self.previousAction)

        self.playButton = QToolButton()
        self.playButton.setFocusPolicy(Qt.NoFocus)
        self.playButton.setIconSize(QSize(40, 40))
        self.playButton.setShortcut(QKeySequence("Ctrl + Down"))
        self.playButton.setDefaultAction(self.playAction)

        self.nextButton = QToolButton()
        self.nextButton.setFocusPolicy(Qt.NoFocus)
        self.nextButton.setIconSize(QSize(40, 40))
        self.nextButton.setFocusPolicy(Qt.NoFocus)
        self.nextButton.setShortcut(QKeySequence("Ctrl + Right"))
        self.nextButton.setDefaultAction(self.nextAction)

        self.desktopLyricButton = QToolButton(clicked=self.show_desktop_lyric)
        self.desktopLyricButton.setToolTip(self.tr("桌面歌词"))
        self.desktopLyricButton.setFocusPolicy(Qt.NoFocus)
        self.desktopLyricButton.setIcon(QIcon(IconsHub.DesktopLyric))
        self.desktopLyricButton.setIconSize(QSize(25, 25))

        self.seekSlider = QSlider(Qt.Horizontal)
        self.seekSlider.setObjectName("seekSlider")
        self.seekSlider.setFixedHeight(20)
        self.seekSlider.setFocusPolicy(Qt.NoFocus)
        self.seekSlider.setRange(0, 0)

        hbox1 = QHBoxLayout()
        hbox1.addWidget(self.favoriteButton)
        hbox1.addWidget(self.musicTitleLabel)
        hbox1.addStretch()
        hbox1.addWidget(self.timeLabel)
        vbox1 = QVBoxLayout()
        vbox1.addLayout(hbox1)
        vbox1.setSpacing(5)
        vbox1.addWidget(self.seekSlider)

        mainLayout = QHBoxLayout(self)
        mainLayout.setContentsMargins(2, 0, 0, 0)
        mainLayout.addWidget(self.artistHeadLabel)
        mainLayout.addWidget(self.previousButton)
        mainLayout.addWidget(self.playButton)
        mainLayout.addWidget(self.nextButton)
        mainLayout.addLayout(vbox1)
        mainLayout.addWidget(self.playmodeButton)
        mainLayout.addWidget(self.desktopLyricButton)

    def show_desktop_lyric(self):
        if self.desktopLyric.isHidden():
            beToOff = True
            self.desktopLyric.show()
            self.desktopLyric.original_place()
        else:
            beToOff = False
            self.desktopLyric.hide()
        self.desktop_lyric_state_changed_signal.emit(beToOff)

    def desktop_lyric_closed(self):
        self.desktop_lyric_state_changed_signal.emit(False)

    def change_playmode(self):
        oldPlaymode = self.playmode
        if self.playmode == Configures.PlaymodeRandom:
            self.set_new_playmode(Configures.PlaymodeOrder)
        elif self.playmode == Configures.PlaymodeOrder:
            self.set_new_playmode(Configures.PlaymodeSingle)
        elif self.playmode == Configures.PlaymodeSingle:
            self.set_new_playmode(Configures.PlaymodeRandom)
        self.playmode_changed_signal.emit(oldPlaymode, self.playmode)

    def set_new_playmode(self, playmode):
        self.playmode = playmode
        if playmode == Configures.PlaymodeRandom:
            iconPath = IconsHub.PlaymodeRandom
            toolTip = Configures.PlaymodeRandomText
        elif playmode == Configures.PlaymodeOrder:
            iconPath = IconsHub.PlaymodeOrder
            toolTip = Configures.PlaymodeOrderText
        else:
            iconPath = IconsHub.PlaymodeSingle
            toolTip = Configures.PlaymodeSingleText
        self.playmodeButton.setIcon(QIcon(iconPath))
        self.playmodeButton.setToolTip(toolTip)

    def ui_initial(self):
        self.mediaPlayer.stop()
        self.totalTime = "00:00"
        self.playAction.setIcon(QIcon(IconsHub.ControlPlay))
        self.musicTitleLabel.setText("Zheng-Yejian._.XYPLAYER")
        self.artistName = "Zheng-Yejian"
        self.artistHeadLabel.setPixmap(QPixmap(IconsHub.Anonymous))
        self.seekSlider.setRange(0, 0)
        self.favoriteButton.setIcon(QIcon(IconsHub.Favorites))
        self.favoriteButton.setToolTip("收藏")
        self.timeLabel.setText("00:00/00:00")

    def set_volume(self, volume):
        self.mediaPlayer.setVolume(volume)

    def set_muted(self, muted):
        self.mediaPlayer.setMuted(muted)

    def tick(self):
        currentTime = self.mediaPlayer.position()
        self.seekSlider.setValue(currentTime)
        cTime = format_position_to_mmss(currentTime // 1000)
        self.timeLabel.setText(cTime + "/" + self.totalTime)
        self.media_player_notify_signal.emit(currentTime)

    def slider_value_changed(self, value):
        cTime = format_position_to_mmss(value // 1000)
        self.timeLabel.setText("%s/%s" % (cTime, self.totalTime))
        self.media_player_notify_signal.emit(value)

    def slider_pressed(self):
        self.mediaPlayer.positionChanged.disconnect(self.tick)

    def seek(self):
        if self.mediaPlayer.state() == QMediaPlayer.StoppedState:
            self.mediaPlayer.play()
            self.mediaPlayer.setPosition(self.seekSlider.value())
        else:
            self.mediaPlayer.setPosition(self.seekSlider.value())
            self.mediaPlayer.play()
        self.mediaPlayer.positionChanged.connect(self.tick)

    def duration_changed(self, duration):
        self.seekSlider.setMaximum(duration)
        exactTotalTime = format_position_to_mmss(self.mediaPlayer.duration() // 1000)
        self.timeLabel.setText("%s/%s" % (Configures.ZeroTime, exactTotalTime))
        if self.totalTime != exactTotalTime:
            self.totalTime = exactTotalTime
            self.playlist.set_music_time_at(self.currentSourceRow, exactTotalTime)

    def check_favorite(self):
        if self.currentSourceRow >= 0:
            if self.playlist.get_music_title_at(self.currentSourceRow) in self.lovedSongs:
                self.favoriteButton.setIcon(QIcon(IconsHub.Favorites))
                self.favoriteButton.setToolTip("取消收藏")
            else:
                self.favoriteButton.setIcon(QIcon(IconsHub.FavoritesNo))
                self.favoriteButton.setToolTip("收藏")
            if self.playlist.get_name() == Configures.PlaylistFavorite:
                self.favoriteButton.setToolTip("收藏")

    def mark_as_favorite(self):
        if (
            self.playlist.get_name() == Configures.PlaylistFavorite
            or not self.playlist.length()
            or self.currentSourceRow < 0
        ):
            return
        path = self.playlist.get_music_path_at(self.currentSourceRow)
        title = self.playlist.get_music_title_at(self.currentSourceRow)
        if self.playlist.get_name() == Configures.PlaylistOnline:
            musicName = get_full_music_name_from_title(title)
            musicPath = os.path.join(self.downloadDir, musicName)
            musicPathO = os.path.join(Configures.MusicsDir, musicName)
            if not os.path.exists(musicPath) and not os.path.exists(musicPathO):
                QMessageBox.information(self, "提示", "请先下载该歌曲再添加喜欢!")
                return
            if os.path.exists(musicPath):
                path = musicPath
            else:
                path = musicPathO
        elif not os.path.exists(path):
            QMessageBox.information(self, "提示", "路径'" + "%s" % path + "'无效,无法标记喜欢!")
            return
        playlistTemp = Playlist()
        playlistTemp.fill_list(Configures.PlaylistFavorite)
        if title in self.lovedSongs:
            playlistTemp.remove_item_at(self.lovedSongs.index(title))
            playlistTemp.commit_records()
            self.lovedSongs.remove(title)
            self.favoriteButton.setIcon(QIcon(IconsHub.FavoritesNo))
            self.favoriteButton.setToolTip("收藏")
        else:
            playlistTemp.add_item_from_path(path)
            playlistTemp.commit_records()
            self.lovedSongs.append(title)
            self.favoriteButton.setIcon(QIcon(IconsHub.Favorites))
            self.favoriteButton.setToolTip("取消收藏")
        self.mark_favorite_completed_signal.emit()

    def show_artist_info(self):
        if self.artistName:
            self.show_artist_info_signal.emit(self.artistName)

    def decide_to_play_or_pause(self, row):
        if row != self.currentSourceRow:
            self.set_media_source_at_row(row, clickPlayFlag=True)
        elif self.mediaPlayer.state() in (QMediaPlayer.PausedState, QMediaPlayer.StoppedState):
            self.mediaPlayer.play()
        elif self.mediaPlayer.state() == QMediaPlayer.PlayingState:
            self.mediaPlayer.pause()

    def set_media_source_at_row(self, row, clickPlayFlag=False):
        if not self.playlist.length() or row < 0:
            return
        self.stop_music()
        self.clickPlayFlag = clickPlayFlag
        self.playlist.set_current_row(row)
        sourcePath = self.playlist.get_music_path_at(row)
        self.title = self.playlist.get_music_title_at(row)
        self.sourceTrace = "local" if self.playlist.get_music_id_at(row) == Configures.LocalMusicId else "online"
        self.artistName, self.musicName = get_artist_and_musicname_from_title(self.title)
        self.playlistName = self.playlist.get_name()
        self.totalTime = self.playlist.get_music_time_at(row)
        self.album = self.playlist.get_music_album_at(row)
        self.errorType = Configures.NoError
        isAnUrl = False
        if not os.path.exists(sourcePath):
            if self.playlist.get_name() == Configures.PlaylistOnline:
                if sourcePath == Configures.NoLink:
                    musicId = self.playlist.get_music_id_at(row)
                    sourcePath = SearchOnline.get_song_link(musicId)
                    if sourcePath:
                        self.playlist.set_music_path_at(row, sourcePath)
                    else:
                        self.errorType = Configures.UrlError
                isAnUrl = True
            else:
                self.errorType = Configures.PathError
                sourcePath = "/usr/share/sounds/error_happened.ogg"
        if self.errorType == Configures.NoError:
            self.sourcePath = sourcePath
            self.musicFileName = get_base_name_from_path(sourcePath)
            self.playedDate = get_time_of_now()
            self.songinfosManager.update_datas_of_item(
                self.musicFileName,
                self.playedDate,
                self.musicName,
                self.artistName,
                self.totalTime,
                self.album,
                self.playlistName,
            )
            if not self.timerFlag:
                self.timerFlag = True
                self.timeSpan = 0
            if isAnUrl:
                url = QUrl(sourcePath)
            else:
                url = QUrl.fromLocalFile(sourcePath)
            self.play_from_url(url)
        else:
            self.timerFlag = False
            self.dont_hide_main_window_signal.emit()
            if self.errorType == Configures.DisnetError:
                QMessageBox.critical(
                    self, "错误", "联网出错!\n无法联网播放歌曲'%s'!\n您最好在网络畅通时下载该曲目!" % self.playlist.get_music_title_at(row)
                )
            elif self.errorType == Configures.PathError:
                QMessageBox.information(self, "提示", "路径'%s'无效,请尝试重新下载并添加对应歌曲!" % self.playlist.get_music_path_at(row))

    def play_from_url(self, url):
        mediaContent = QMediaContent(url)
        self.mediaPlayer.setMedia(mediaContent)
        self.mediaPlayer.play()

    def state_changed(self, newState):
        if self and newState in [QMediaPlayer.PlayingState, QMediaPlayer.PausedState, QMediaPlayer.StoppedState]:
            if not self.playlist.length():
                return
            iconPath = IconsHub.ControlPause
            if newState in [QMediaPlayer.StoppedState, QMediaPlayer.PausedState]:
                iconPath = IconsHub.ControlPlay
            icon = QIcon(iconPath)
            self.playAction.setIcon(icon)
            if self.timerFlag:
                if newState == QMediaPlayer.PlayingState:
                    self.timeStart = time.time()
                else:
                    self.timeSpan += time.time() - self.timeStart

    def media_status_changed(self, status):
        if status == QMediaPlayer.EndOfMedia:
            self.music_finished()

    def music_finished(self):
        if self.errorType == Configures.NoError:
            self.next_song()

    def play_music(self):
        if self.mediaPlayer.state() == QMediaPlayer.PlayingState:
            self.mediaPlayer.pause()
        else:
            self.mediaPlayer.play()

    def stop_music_but_timing(self):
        self.mediaPlayer.stop()
        self.seekSlider.setValue(0)
        self.media_player_notify_signal.emit(-0.5)

    def stop_music(self):
        self.stop_music_but_timing()
        if self.timerFlag:
            self.timerFlag = False
            InfosList = [
                self.playedDate,
                self.musicFileName,
                self.musicName,
                self.artistName,
                self.album,
                "%i" % change_mmss_to_seconds(self.totalTime),
                "%.1f" % self.timeSpan,
                self.playlistName,
                self.sourcePath,
                "%i" % (self.title in self.lovedSongs),
                self.sourceTrace,
                Configures.Playmodes[self.playmode],
                "%i" % self.clickPlayFlag,
            ]
            log_playback_history(organized_list_as_str(InfosList))
            self.songinfosManager.update_time_span_relate_of_item(self.musicFileName, self.timeSpan, self.clickPlayFlag)
            self.clickPlayFlag = False

    def get_next_random_row(self):
        listTemp = list(self.playlist.get_ids() - set(self.nearPlayedSongs))
        ran = random.randint(0, len(listTemp) - 1)
        return self.playlist.get_items_queue().index(listTemp[ran])

    def get_next_single_row(self):
        nextRow = self.currentSourceRow
        if nextRow < 0:
            nextRow = 0
        return nextRow

    def get_next_order_row(self, reverse=False):
        if reverse:
            if self.currentSourceRow < 0:
                self.currentSourceRow = 0
            return (self.currentSourceRow - 1) % self.playlist.length()
        return (self.currentSourceRow + 1) % self.playlist.length()

    def previous_song(self):
        self.play_source_on_next_row(reverse=True)

    def next_song(self):
        self.play_source_on_next_row()

    def play_source_on_next_row(self, reverse=False):
        if not self.playlist.length():
            return
        if self.mediaPlayer.position() > 20:
            self.music_ended_signal.emit()
        nextRow = 0
        if self.playmode == Configures.PlaymodeRandom:
            nextRow = self.get_next_random_row()
        elif self.playmode == Configures.PlaymodeOrder:
            nextRow = self.get_next_order_row(reverse)
        elif self.playmode == Configures.PlaymodeSingle:
            nextRow = self.get_next_single_row()
        self.set_media_source_at_row(nextRow)

    def current_media_changed(self):
        if not self.playlist.length():
            return
        self.current_media_changed_signal.emit()
        self.update_parameters()
        self.update_near_played_queue()
        self.check_favorite()

    def update_parameters(self):
        self.currentSourceRow = self.playlist.get_current_row()
        self.musicTitleLabel.setText(self.title)
        self.playAction.setText(self.musicName)
        imagePath = SearchOnline.get_artist_image_path(self.artistName)
        if imagePath:
            pixmap = QPixmap(imagePath)
        else:
            pixmap = QPixmap(IconsHub.Anonymous)
        self.artistHeadLabel.setPixmap(pixmap)
        musicId = self.playlist.get_music_id_at(self.currentSourceRow)
        self.update_window_lyric_signal.emit(self.title, musicId)

    def update_near_played_queue(self):
        self.currentSourceId = self.playlist.get_music_path_at(self.currentSourceRow)
        if self.playlist.get_name() == Configures.PlaylistOnline:
            self.currentSourceId = self.playlist.get_music_id_at(self.currentSourceRow)
        if self.currentSourceId not in self.nearPlayedSongs:
            self.nearPlayedSongs.append(self.currentSourceId)
        while len(self.nearPlayedSongs) >= self.playlist.length() * 4 / 5:
            del self.nearPlayedSongs[0]

    def add_title_into_loved_songs(self, title):
        self.lovedSongs.append(title)
    def setup_ui(self):
        self.setFixedHeight(50)
        # 桌面歌词标签
        self.desktopLyric = desktop_lyric.DesktopLyric()
        self.desktopLyric.set_color(globalSettings.DesktoplyricColors)
        # 3个标签
        self.artistHeadLabel = LabelButton()
        self.artistHeadLabel.setToolTip(self.tr("查看歌手信息"))
        self.artistHeadLabel.setFixedSize(QSize(42, 42))
        self.artistHeadLabel.setScaledContents(True)
        self.artistHeadLabel.setPixmap(QPixmap(IconsHub.Anonymous))

        self.musicTitleLabel = NewLabel()
        self.musicTitleLabel.setObjectName("musicTitleLabel")
        self.musicTitleLabel.setFixedSize(QSize(370, 20))
        self.musicTitleLabel.setText("Zheng-Yejian._.XYPLAYER")
        self.timeLabel = QLabel("00:00/00:00")
        self.timeLabel.setObjectName("timeLabel")
        self.timeLabel.setFixedHeight(20)
        self.timeLabel.setAlignment(Qt.AlignRight and Qt.AlignVCenter)

        # 五个基本按键
        self.playmodeButton = QToolButton(clicked=self.change_playmode)
        self.playmodeButton.setFocusPolicy(Qt.NoFocus)

        self.playmodeButton.setIcon(QIcon(IconsHub.PlaymodeRandom))
        self.playmodeButton.setIconSize(QSize(25, 25))
        self.playmodeButton.setToolTip("随机播放")

        self.favoriteButton = QToolButton(clicked=self.mark_as_favorite)
        self.favoriteButton.setFocusPolicy(Qt.NoFocus)
        self.favoriteButton.setToolTip("收藏")
        self.favoriteButton.setIcon(QIcon(IconsHub.Favorites))
        self.favoriteButton.setIconSize(QSize(20, 20))

        self.previousButton = QToolButton()
        self.previousButton.setFocusPolicy(Qt.NoFocus)
        self.previousButton.setIconSize(QSize(40, 40))
        self.previousButton.setShortcut(QKeySequence("Ctrl + Left"))
        self.previousButton.setDefaultAction(self.previousAction)

        self.playButton = QToolButton()
        self.playButton.setFocusPolicy(Qt.NoFocus)
        self.playButton.setIconSize(QSize(40, 40))
        self.playButton.setShortcut(QKeySequence("Ctrl + Down"))
        self.playButton.setDefaultAction(self.playAction)

        self.nextButton = QToolButton()
        self.nextButton.setFocusPolicy(Qt.NoFocus)
        self.nextButton.setIconSize(QSize(40, 40))
        self.nextButton.setFocusPolicy(Qt.NoFocus)
        self.nextButton.setShortcut(QKeySequence("Ctrl + Right"))
        self.nextButton.setDefaultAction(self.nextAction)

        self.desktopLyricButton = QToolButton(clicked=self.show_desktop_lyric)
        self.desktopLyricButton.setToolTip(self.tr("桌面歌词"))
        self.desktopLyricButton.setFocusPolicy(Qt.NoFocus)
        self.desktopLyricButton.setIcon(QIcon(IconsHub.DesktopLyric))
        self.desktopLyricButton.setIconSize(QSize(25, 25))

        self.seekSlider = QSlider(Qt.Horizontal)
        self.seekSlider.setObjectName("seekSlider")
        self.seekSlider.setFixedHeight(20)
        self.seekSlider.setFocusPolicy(Qt.NoFocus)
        self.seekSlider.setRange(0, 0)

        hbox1 = QHBoxLayout()
        hbox1.addWidget(self.favoriteButton)
        hbox1.addWidget(self.musicTitleLabel)
        hbox1.addStretch()
        hbox1.addWidget(self.timeLabel)
        vbox1 = QVBoxLayout()
        vbox1.addLayout(hbox1)
        vbox1.setSpacing(5)
        vbox1.addWidget(self.seekSlider)

        mainLayout = QHBoxLayout(self)
        mainLayout.setContentsMargins(2, 0, 0, 0)
        mainLayout.addWidget(self.artistHeadLabel)
        mainLayout.addWidget(self.previousButton)
        mainLayout.addWidget(self.playButton)
        mainLayout.addWidget(self.nextButton)
        mainLayout.addLayout(vbox1)
        mainLayout.addWidget(self.playmodeButton)
        mainLayout.addWidget(self.desktopLyricButton)
Example #7
0
 def setup_ui(self):
     self.setWindowTitle('歌曲信息')
     label1 = QLabel('歌手:')
     label2 = QLabel('曲名:')
     label3 = QLabel('专辑:')
     label4 = QLabel('路径:')
     label4.setFixedWidth(40)
     self.artistEdit = QLineEdit()
     self.musicEdit = QLineEdit()
     self.albumEdit = QLineEdit()
     self.timeLabel = QLabel('时长: 00:00')
     self.sizeLabel = QLabel('大小: 0.00 MB')
     self.pathLabel = NewLabel()
     self.playlistInfoLabel = QLabel('位置: 默认列表  ( 1 / 100 )')
     self.countInfoLabel = QLabel('播放次数: n次')
     self.addTimeLabel = QLabel('添加时间: 2015年12月30日')
     self.modifyTimeLabel = QLabel('修改时间: 2015年12月31日')
     self.favorInfoLabel = QLabel('收藏情况: 未收藏')
     self.traceInfoLabel = QLabel('歌曲来源: 本地添加')
     self.nearPlaylistLabel = QLabel('最近播放位置: 默认列表')
     self.nearPlayedDateLabel = QLabel('最近播放时间: 2016年1月1日')
     self.applyButton = QPushButton('应用', clicked=self.apply)
     self.applyButton.setFocusPolicy(Qt.NoFocus)
     self.cancelButton = QPushButton('取消', clicked=self.cancel)
     self.cancelButton.setFocusPolicy(Qt.NoFocus)
     self.refreshButton = QPushButton('刷新',
                                      clicked=self.refresh_infos_on_page)
     self.refreshButton.setFocusPolicy(Qt.NoFocus)
     self.importlyricButton = QPushButton('导入歌词', clicked=self.import_lyric)
     self.importlyricButton.setFocusPolicy(Qt.NoFocus)
     hbox0 = QHBoxLayout()
     hbox0.addWidget(label4)
     hbox0.addWidget(self.pathLabel)
     hbox1 = QHBoxLayout()
     hbox1.addWidget(label1)
     hbox1.addWidget(self.artistEdit)
     hbox2 = QHBoxLayout()
     hbox2.addWidget(label2)
     hbox2.addWidget(self.musicEdit)
     hbox3 = QHBoxLayout()
     hbox3.addWidget(label3)
     hbox3.addWidget(self.albumEdit)
     hbox4 = QHBoxLayout()
     hbox4.addWidget(self.importlyricButton)
     hbox4.addStretch()
     hbox4.addWidget(self.applyButton)
     hbox4.addWidget(self.cancelButton)
     hbox4.addWidget(self.refreshButton)
     hbox5 = QHBoxLayout()
     hbox5.addWidget(self.timeLabel)
     hbox5.addWidget(self.sizeLabel)
     hbox5.addWidget(self.traceInfoLabel)
     hbox6 = QHBoxLayout()
     hbox6.setContentsMargins(0, 0, 20, 0)
     hbox6.addWidget(self.playlistInfoLabel)
     hbox6.addStretch()
     hbox6.addWidget(self.favorInfoLabel)
     mainLayout = QVBoxLayout(self)
     mainLayout.setSpacing(10)
     mainLayout.addLayout(hbox0)
     mainLayout.addLayout(hbox6)
     mainLayout.addLayout(hbox1)
     mainLayout.addLayout(hbox2)
     mainLayout.addLayout(hbox3)
     mainLayout.addLayout(hbox5)
     mainLayout.addWidget(self.countInfoLabel)
     mainLayout.addWidget(self.nearPlaylistLabel)
     mainLayout.addWidget(self.nearPlayedDateLabel)
     mainLayout.addWidget(self.addTimeLabel)
     mainLayout.addWidget(self.modifyTimeLabel)
     mainLayout.addLayout(hbox4)
Example #8
0
class SongInfoPage(QWidget):
    tag_values_changed_signal = pyqtSignal(int, str, str, str)
    refresh_infos_on_page_signal = pyqtSignal(int)

    def __init__(self, parent=None):
        super(SongInfoPage, self).__init__(parent)
        self.row = 0
        self.artist = ''
        self.musicName = ''
        self.album = ''
        self.title = ''
        self.path = ''
        self.lovedSongs = None
        self.songinfosManager = None
        self.setup_ui()

    def setup_ui(self):
        self.setWindowTitle('歌曲信息')
        label1 = QLabel('歌手:')
        label2 = QLabel('曲名:')
        label3 = QLabel('专辑:')
        label4 = QLabel('路径:')
        label4.setFixedWidth(40)
        self.artistEdit = QLineEdit()
        self.musicEdit = QLineEdit()
        self.albumEdit = QLineEdit()
        self.timeLabel = QLabel('时长: 00:00')
        self.sizeLabel = QLabel('大小: 0.00 MB')
        self.pathLabel = NewLabel()
        self.playlistInfoLabel = QLabel('位置: 默认列表  ( 1 / 100 )')
        self.countInfoLabel = QLabel('播放次数: n次')
        self.addTimeLabel = QLabel('添加时间: 2015年12月30日')
        self.modifyTimeLabel = QLabel('修改时间: 2015年12月31日')
        self.favorInfoLabel = QLabel('收藏情况: 未收藏')
        self.traceInfoLabel = QLabel('歌曲来源: 本地添加')
        self.nearPlaylistLabel = QLabel('最近播放位置: 默认列表')
        self.nearPlayedDateLabel = QLabel('最近播放时间: 2016年1月1日')
        self.applyButton = QPushButton('应用', clicked=self.apply)
        self.applyButton.setFocusPolicy(Qt.NoFocus)
        self.cancelButton = QPushButton('取消', clicked=self.cancel)
        self.cancelButton.setFocusPolicy(Qt.NoFocus)
        self.refreshButton = QPushButton('刷新',
                                         clicked=self.refresh_infos_on_page)
        self.refreshButton.setFocusPolicy(Qt.NoFocus)
        self.importlyricButton = QPushButton('导入歌词', clicked=self.import_lyric)
        self.importlyricButton.setFocusPolicy(Qt.NoFocus)
        hbox0 = QHBoxLayout()
        hbox0.addWidget(label4)
        hbox0.addWidget(self.pathLabel)
        hbox1 = QHBoxLayout()
        hbox1.addWidget(label1)
        hbox1.addWidget(self.artistEdit)
        hbox2 = QHBoxLayout()
        hbox2.addWidget(label2)
        hbox2.addWidget(self.musicEdit)
        hbox3 = QHBoxLayout()
        hbox3.addWidget(label3)
        hbox3.addWidget(self.albumEdit)
        hbox4 = QHBoxLayout()
        hbox4.addWidget(self.importlyricButton)
        hbox4.addStretch()
        hbox4.addWidget(self.applyButton)
        hbox4.addWidget(self.cancelButton)
        hbox4.addWidget(self.refreshButton)
        hbox5 = QHBoxLayout()
        hbox5.addWidget(self.timeLabel)
        hbox5.addWidget(self.sizeLabel)
        hbox5.addWidget(self.traceInfoLabel)
        hbox6 = QHBoxLayout()
        hbox6.setContentsMargins(0, 0, 20, 0)
        hbox6.addWidget(self.playlistInfoLabel)
        hbox6.addStretch()
        hbox6.addWidget(self.favorInfoLabel)
        mainLayout = QVBoxLayout(self)
        mainLayout.setSpacing(10)
        mainLayout.addLayout(hbox0)
        mainLayout.addLayout(hbox6)
        mainLayout.addLayout(hbox1)
        mainLayout.addLayout(hbox2)
        mainLayout.addLayout(hbox3)
        mainLayout.addLayout(hbox5)
        mainLayout.addWidget(self.countInfoLabel)
        mainLayout.addWidget(self.nearPlaylistLabel)
        mainLayout.addWidget(self.nearPlayedDateLabel)
        mainLayout.addWidget(self.addTimeLabel)
        mainLayout.addWidget(self.modifyTimeLabel)
        mainLayout.addLayout(hbox4)

    def set_editable(self, editable):
        self.artistEdit.setReadOnly(not editable)
        self.musicEdit.setReadOnly(not editable)
        self.albumEdit.setReadOnly(not editable)
        self.applyButton.setEnabled(editable)
        self.cancelButton.setEnabled(editable)

    def set_basic_infos(self, title, totalTime, album, path, size, musicId):
        artist, musicName = get_artist_and_musicname_from_title(title)
        self.title = title
        self.artist = artist
        self.musicName = musicName
        self.album = album
        self.path = path
        self.artistEdit.setText(artist)
        self.musicEdit.setText(musicName)
        self.albumEdit.setText(album)
        self.timeLabel.setText('时长: %s' % totalTime)
        self.sizeLabel.setText('大小: %.2f MB' % convert_B_to_MB(size))
        self.pathLabel.setText(path)
        trace = '线上资源'
        if musicId == Configures.LocalMusicId:
            trace = '本地资源'
        self.traceInfoLabel.setText('歌曲来源: %s' % trace)
        self.set_favorite_info(title in self.lovedSongs)
        item = get_base_name_from_path(path)
        freq, totalSpan, spanMax, nearPlaylistName, nearPlayedDate, nearPlayedTime = self.songinfosManager.get_statistic_infos_of_item(
            item)
        if freq:
            countInfos = '播放次数: %i 次#平均播放时长: %.1f 秒#最长播放时长: %.1f 秒' % (
                freq, totalSpan / freq, spanMax)
            nearPlaylistInfo = '最近播放位置: %s#最近播放时长: %.1f 秒' % (nearPlaylistName,
                                                              nearPlayedTime)
            nearPlayedDateInfo = '最近播放: %s' % format_time_str_with_weekday(
                nearPlayedDate)
        else:
            countInfos = '播放次数: 0 次'
            nearPlaylistInfo = '最近播放位置: 未曾播放'
            nearPlayedDateInfo = '最近播放: 未曾播放'
        self.countInfoLabel.setText(countInfos.replace('#', ' ' * 15))
        self.nearPlaylistLabel.setText(nearPlaylistInfo.replace('#', ' ' * 15))
        self.nearPlayedDateLabel.setText(nearPlayedDateInfo)

    def set_playlist_infos(self, playlistName, playlistLength, row):
        self.row = row
        self.playlistInfoLabel.setText('位置: %s    ( 第%i首 / 共%i首 )' %
                                       (playlistName, row + 1, playlistLength))

    def set_loved_songs(self, lovedSongs):
        self.lovedSongs = lovedSongs

    def set_songinfos_manager(self, sim):
        self.songinfosManager = sim

    def set_favorite_info(self, loved):
        text = '未收藏'
        if loved:
            text = '已收藏'
        self.favorInfoLabel.setText('收藏情况: %s' % text)

    def set_time_infos(self, addedTime, modifiedTime):
        self.addTimeLabel.setText('添加时间: %s' %
                                  format_time_str_with_weekday(addedTime))
        self.modifyTimeLabel.setText(
            '修改时间: %s' % format_time_str_with_weekday(modifiedTime))

    def apply(self):
        if self.check_validity() and (self.artist, self.musicName,
                                      self.album) != (self.artistEdit.text(),
                                                      self.musicEdit.text(),
                                                      self.albumEdit.text()):
            self.artist, self.musicName, self.album = self.artistEdit.text(
            ), self.musicEdit.text(), self.albumEdit.text()
            self.title = connect_as_title(self.artist, self.musicName)
            write_tags(self.path, self.title, self.album)
            modifiedTime = get_time_of_now()
            self.modifyTimeLabel.setText(
                '修改时间: %s' % format_time_str_with_weekday(modifiedTime))
            self.tag_values_changed_signal.emit(self.row, self.title,
                                                self.album, modifiedTime)

    def cancel(self):
        if (self.artist, self.musicName,
                self.album) != (self.artistEdit.text(), self.musicEdit.text(),
                                self.albumEdit.text()):
            self.artistEdit.setText(self.artist)
            self.musicEdit.setText(self.musicName)
            self.albumEdit.setText(self.album)

    def check_validity(self):
        text = ''
        valid = False
        if not self.artistEdit.text():
            text = self.tr('歌手名')
            self.artistEdit.setText(self.artist)
        elif not self.musicEdit.text():
            text = self.tr('歌曲名')
            self.musicEdit.setText(self.musicName)
        elif not self.albumEdit.text():
            text = self.tr('专辑')
            self.albumEdit.setText(self.album)
        else:
            valid = True
        if not valid:
            QMessageBox.information(self, "歌曲详细信息", '%s不能为空!' % text)
        return valid

    def import_lyric(self):
        lrcFile = QFileDialog.getOpenFileName(self, "选择音乐文件",
                                              Configures.HomeDir,
                                              self.tr("*.lrc"))[0]
        if lrcFile:
            import_a_lyric(lrcFile, self.title)

    def refresh_infos_on_page(self):
        self.refresh_infos_on_page_signal.emit(self.row)
Example #9
0
class ArtistInfoPage(QWidget):
    def __init__(self, parent=None):
        super(ArtistInfoPage, self).__init__(parent)
        self.setup_ui()
        self.create_connections()

    def setup_ui(self):
        self.setObjectName('playbackPage')

        #歌手信息页
        self.artistHeadLabel = QLabel(self)
        self.artistHeadLabel.setFixedSize(QSize(90, 90))
        self.artistHeadLabel.setScaledContents(True)
        self.artistName = NewLabel(self, True)
        self.artistName.setFixedSize(QSize(90, 30))
        self.artistGender = QLabel("性别:未知", self)
        self.artistBirthday = QLabel("生日:未知", self)
        self.artistConstellation = QLabel("星座:未知", self)
        self.artistLanguage = QLabel("语言:未知", self)
        self.artistBirthplace = QLabel("出生地:未知", self)
        self.artistDetail = MyTextEdit(self)

        #刷新歌手信息缓存按键
        self.refreshBtn = QPushButton(self)
        self.refreshBtn.setFocusPolicy(Qt.NoFocus)
        self.refreshBtn.setIcon(QIcon(IconsHub.Refresh))
        self.refreshBtn.setText('刷新')
        self.refreshBtn.setToolTip("刷新歌手信息")
        self.refreshBtn.setFixedSize(QSize(70, 30))

        vbox1 = QVBoxLayout()
        vbox1.setSpacing(10)
        vbox1.addWidget(self.artistHeadLabel)
        vbox1.addWidget(self.artistName)

        hbox1 = QHBoxLayout()
        hbox1.addWidget(self.artistGender)
        hbox1.addWidget(self.artistBirthday)

        hbox2 = QHBoxLayout()
        hbox2.addWidget(self.artistConstellation)
        hbox2.addWidget(self.artistLanguage)

        hbox3 = QHBoxLayout()
        hbox3.addWidget(self.artistBirthplace)
        hbox3.addWidget(self.refreshBtn)
        vbox2 = QVBoxLayout()
        vbox2.addLayout(hbox1)
        vbox2.addLayout(hbox2)
        vbox2.addLayout(hbox3)
        hbox4 = QHBoxLayout()
        hbox4.setSpacing(30)
        hbox4.addLayout(vbox1)
        hbox4.addLayout(vbox2)

        mainLayout = QVBoxLayout(self)
        mainLayout.addLayout(hbox4)
        mainLayout.addWidget(self.artistDetail)

    def create_connections(self):
        self.refreshBtn.clicked.connect(self.update_infofile_cached)

    def set_artist_info(self, artist):
        if artist == 'Zheng-Yejian':
            self.ui_initial()
        elif artist != self.artistName.text():
            infoPath = SearchOnline.get_artist_info_path(artist)
            infoDict = parse_artist_info(infoPath)
            self.artistName.setText(artist)
            self.artistBirthday.setText('生日:%s' % infoDict['birthday'])
            self.artistBirthplace.setText('出生地:%s' % infoDict['birthplace'])
            self.artistLanguage.setText('语言:%s' % infoDict['language'])
            self.artistGender.setText('性别:%s' % infoDict['gender'])
            self.artistConstellation.setText('星座:%s' %
                                             infoDict['constellation'])
            self.artistDetail.clear()
            self.artistDetail.setAlignment(Qt.AlignHCenter)
            self.artistDetail.setHtml(
                self.get_artist_detail_style_text(infoDict['info']))
            imagePath = SearchOnline.get_artist_image_path(artist)
            if imagePath:
                pixmap = QPixmap(imagePath)
            else:
                pixmap = QPixmap(IconsHub.Anonymous)
            self.artistHeadLabel.setPixmap(pixmap)

    def update_artist_info(self, title):
        artist, musicName = get_artist_and_musicname_from_title(title)
        return self.set_artist_info(artist)

    def update_infofile_cached(self):
        artist = self.artistName.text()
        if artist != '未知':
            infoPath = SearchOnline.get_local_artist_info_path(artist)
            if os.path.exists(infoPath):
                os.remove(infoPath)
                self.set_artist_info(artist)

    def ui_initial(self):
        self.artistHeadLabel.setPixmap(QPixmap(IconsHub.Anonymous))
        self.artistName.setText("Zheng-Yejian")
        self.artistBirthday.setText("生日:1992.10.18")
        self.artistBirthplace.setText("出生地:福建")
        self.artistLanguage.setText("语言:国语")
        self.artistGender.setText("性别:男")
        self.artistConstellation.setText("星座:天秤座")
        self.artistDetail.setHtml(
            self.get_artist_detail_style_text('大家好,我是作者!!!'))

    def get_artist_detail_style_text(self, text):
        return "<p style='color:black;font-size:16px;'>%s</p>" % text
class SongInfoPage(QWidget):
    tag_values_changed_signal = pyqtSignal(int, str, str, str)
    refresh_infos_on_page_signal = pyqtSignal(int)
    def __init__(self, parent=None):
        super(SongInfoPage, self).__init__(parent)
        self.row = 0
        self.artist = ''
        self.musicName = ''
        self.album = ''
        self.title = ''
        self.path = ''
        self.lovedSongs = None
        self.songinfosManager = None
        self.setup_ui()
    
    def setup_ui(self):
        self.setWindowTitle('歌曲信息')
        label1 = QLabel('歌手:')
        label2 = QLabel('曲名:')
        label3 = QLabel('专辑:')
        label4 = QLabel('路径:')
        label4.setFixedWidth(40)
        self.artistEdit = QLineEdit()
        self.musicEdit = QLineEdit()
        self.albumEdit = QLineEdit()
        self.timeLabel = QLabel('时长: 00:00')
        self.sizeLabel = QLabel('大小: 0.00 MB')
        self.pathLabel = NewLabel()
        self.playlistInfoLabel = QLabel('位置: 默认列表  ( 1 / 100 )')
        self.countInfoLabel = QLabel('播放次数: n次')
        self.addTimeLabel = QLabel('添加时间: 2015年12月30日')
        self.modifyTimeLabel = QLabel('修改时间: 2015年12月31日')
        self.favorInfoLabel = QLabel('收藏情况: 未收藏')
        self.traceInfoLabel = QLabel('歌曲来源: 本地添加') 
        self.nearPlaylistLabel = QLabel('最近播放位置: 默认列表')
        self.nearPlayedDateLabel = QLabel('最近播放时间: 2016年1月1日')
        self.applyButton = QPushButton('应用', clicked=self.apply)
        self.applyButton.setFocusPolicy(Qt.NoFocus)
        self.cancelButton = QPushButton('取消', clicked=self.cancel)
        self.cancelButton.setFocusPolicy(Qt.NoFocus)
        self.refreshButton = QPushButton('刷新', clicked=self.refresh_infos_on_page)
        self.refreshButton.setFocusPolicy(Qt.NoFocus)
        self.importlyricButton = QPushButton('导入歌词', clicked=self.import_lyric)
        self.importlyricButton.setFocusPolicy(Qt.NoFocus)
        hbox0 = QHBoxLayout()
        hbox0.addWidget(label4)
        hbox0.addWidget(self.pathLabel)
        hbox1 = QHBoxLayout()
        hbox1.addWidget(label1)
        hbox1.addWidget(self.artistEdit)
        hbox2 = QHBoxLayout()
        hbox2.addWidget(label2)
        hbox2.addWidget(self.musicEdit)
        hbox3 = QHBoxLayout()
        hbox3.addWidget(label3)
        hbox3.addWidget(self.albumEdit)
        hbox4 = QHBoxLayout()
        hbox4.addWidget(self.importlyricButton)
        hbox4.addStretch()
        hbox4.addWidget(self.applyButton)
        hbox4.addWidget(self.cancelButton)
        hbox4.addWidget(self.refreshButton)
        hbox5 = QHBoxLayout()
        hbox5.addWidget(self.timeLabel)
        hbox5.addWidget(self.sizeLabel)
        hbox5.addWidget(self.traceInfoLabel)
        hbox6 = QHBoxLayout()
        hbox6.setContentsMargins(0, 0, 20, 0)
        hbox6.addWidget(self.playlistInfoLabel)
        hbox6.addStretch()
        hbox6.addWidget(self.favorInfoLabel)
        mainLayout = QVBoxLayout(self)
        mainLayout.setSpacing(10)
        mainLayout.addLayout(hbox0)
        mainLayout.addLayout(hbox6)
        mainLayout.addLayout(hbox1)
        mainLayout.addLayout(hbox2)
        mainLayout.addLayout(hbox3)
        mainLayout.addLayout(hbox5)
        mainLayout.addWidget(self.countInfoLabel)
        mainLayout.addWidget(self.nearPlaylistLabel)
        mainLayout.addWidget(self.nearPlayedDateLabel)
        mainLayout.addWidget(self.addTimeLabel)
        mainLayout.addWidget(self.modifyTimeLabel)
        mainLayout.addLayout(hbox4)
    
    def set_editable(self, editable):
        self.artistEdit.setReadOnly(not editable)
        self.musicEdit.setReadOnly(not editable)
        self.albumEdit.setReadOnly(not editable)
        self.applyButton.setEnabled(editable)
        self.cancelButton.setEnabled(editable)
    
    def set_basic_infos(self, title, totalTime, album, path, size, musicId):
        artist, musicName = get_artist_and_musicname_from_title(title)
        self.title = title
        self.artist = artist
        self.musicName = musicName
        self.album = album
        self.path = path
        self.artistEdit.setText(artist)
        self.musicEdit.setText(musicName)
        self.albumEdit.setText(album)
        self.timeLabel.setText('时长: %s'%totalTime)
        self.sizeLabel.setText('大小: %.2f MB'%convert_B_to_MB(size))
        self.pathLabel.setText(path)
        trace = '线上资源'
        if musicId == Configures.LocalMusicId:
            trace = '本地资源'
        self.traceInfoLabel.setText('歌曲来源: %s'%trace)
        self.set_favorite_info(title in self.lovedSongs)
        item = get_base_name_from_path(path)
        freq, totalSpan, spanMax, nearPlaylistName, nearPlayedDate, nearPlayedTime = self.songinfosManager.get_statistic_infos_of_item(item)
        if freq:
            countInfos = '播放次数: %i 次#平均播放时长: %.1f 秒#最长播放时长: %.1f 秒'%(freq, totalSpan/freq, spanMax)
            nearPlaylistInfo = '最近播放位置: %s#最近播放时长: %.1f 秒'%(nearPlaylistName,nearPlayedTime)
            nearPlayedDateInfo = '最近播放: %s'%format_time_str_with_weekday(nearPlayedDate)
        else:
            countInfos = '播放次数: 0 次'
            nearPlaylistInfo = '最近播放位置: 未曾播放'
            nearPlayedDateInfo = '最近播放: 未曾播放'
        self.countInfoLabel.setText(countInfos.replace('#', ' '*15))
        self.nearPlaylistLabel.setText(nearPlaylistInfo.replace('#', ' '*15))
        self.nearPlayedDateLabel.setText(nearPlayedDateInfo)
    
    def set_playlist_infos(self, playlistName, playlistLength, row):
        self.row = row
        self.playlistInfoLabel.setText('位置: %s    ( 第%i首 / 共%i首 )'%(playlistName, row+1, playlistLength))
    
    def set_loved_songs(self, lovedSongs):
        self.lovedSongs = lovedSongs
    
    def set_songinfos_manager(self, sim):
        self.songinfosManager = sim
    
    def set_favorite_info(self, loved):
        text = '未收藏'
        if loved:
            text = '已收藏'
        self.favorInfoLabel.setText('收藏情况: %s'%text)
        
    def set_time_infos(self, addedTime, modifiedTime):
        self.addTimeLabel.setText('添加时间: %s'%format_time_str_with_weekday(addedTime))
        self.modifyTimeLabel.setText('修改时间: %s'%format_time_str_with_weekday(modifiedTime))
        
    def apply(self):
        if  self.check_validity() and (self.artist, self.musicName, self.album) != (self.artistEdit.text(), self.musicEdit.text(), self.albumEdit.text()):
            self.artist, self.musicName, self.album = self.artistEdit.text(), self.musicEdit.text(), self.albumEdit.text()
            self.title = connect_as_title(self.artist, self.musicName)
            write_tags(self.path, self.title, self.album)
            modifiedTime = get_time_of_now()
            self.modifyTimeLabel.setText('修改时间: %s'%format_time_str_with_weekday(modifiedTime))
            self.tag_values_changed_signal.emit(self.row, self.title, self.album, modifiedTime)
    
    def cancel(self):
        if (self.artist, self.musicName, self.album) != (self.artistEdit.text(), self.musicEdit.text(), self.albumEdit.text()):
            self.artistEdit.setText(self.artist)
            self.musicEdit.setText(self.musicName)
            self.albumEdit.setText(self.album)

    def check_validity(self):
        text = ''
        valid = False
        if not self.artistEdit.text(): 
            text = self.tr('歌手名')
            self.artistEdit.setText(self.artist)
        elif not self.musicEdit.text():
            text = self.tr('歌曲名')
            self.musicEdit.setText(self.musicName)
        elif not self.albumEdit.text():
            text = self.tr('专辑')
            self.albumEdit.setText(self.album)
        else:
            valid = True
        if not valid:
            QMessageBox.information(self, "歌曲详细信息", '%s不能为空!'%text)
        return valid

    def import_lyric(self):
        lrcFile = QFileDialog.getOpenFileName(self, "选择音乐文件", Configures.HomeDir, self.tr("*.lrc"))[0]
        if lrcFile:
            import_a_lyric(lrcFile, self.title)

    def refresh_infos_on_page(self):
        self.refresh_infos_on_page_signal.emit(self.row)
 def setup_ui(self):
     self.setWindowTitle('歌曲信息')
     label1 = QLabel('歌手:')
     label2 = QLabel('曲名:')
     label3 = QLabel('专辑:')
     label4 = QLabel('路径:')
     label4.setFixedWidth(40)
     self.artistEdit = QLineEdit()
     self.musicEdit = QLineEdit()
     self.albumEdit = QLineEdit()
     self.timeLabel = QLabel('时长: 00:00')
     self.sizeLabel = QLabel('大小: 0.00 MB')
     self.pathLabel = NewLabel()
     self.playlistInfoLabel = QLabel('位置: 默认列表  ( 1 / 100 )')
     self.countInfoLabel = QLabel('播放次数: n次')
     self.addTimeLabel = QLabel('添加时间: 2015年12月30日')
     self.modifyTimeLabel = QLabel('修改时间: 2015年12月31日')
     self.favorInfoLabel = QLabel('收藏情况: 未收藏')
     self.traceInfoLabel = QLabel('歌曲来源: 本地添加') 
     self.nearPlaylistLabel = QLabel('最近播放位置: 默认列表')
     self.nearPlayedDateLabel = QLabel('最近播放时间: 2016年1月1日')
     self.applyButton = QPushButton('应用', clicked=self.apply)
     self.applyButton.setFocusPolicy(Qt.NoFocus)
     self.cancelButton = QPushButton('取消', clicked=self.cancel)
     self.cancelButton.setFocusPolicy(Qt.NoFocus)
     self.refreshButton = QPushButton('刷新', clicked=self.refresh_infos_on_page)
     self.refreshButton.setFocusPolicy(Qt.NoFocus)
     self.importlyricButton = QPushButton('导入歌词', clicked=self.import_lyric)
     self.importlyricButton.setFocusPolicy(Qt.NoFocus)
     hbox0 = QHBoxLayout()
     hbox0.addWidget(label4)
     hbox0.addWidget(self.pathLabel)
     hbox1 = QHBoxLayout()
     hbox1.addWidget(label1)
     hbox1.addWidget(self.artistEdit)
     hbox2 = QHBoxLayout()
     hbox2.addWidget(label2)
     hbox2.addWidget(self.musicEdit)
     hbox3 = QHBoxLayout()
     hbox3.addWidget(label3)
     hbox3.addWidget(self.albumEdit)
     hbox4 = QHBoxLayout()
     hbox4.addWidget(self.importlyricButton)
     hbox4.addStretch()
     hbox4.addWidget(self.applyButton)
     hbox4.addWidget(self.cancelButton)
     hbox4.addWidget(self.refreshButton)
     hbox5 = QHBoxLayout()
     hbox5.addWidget(self.timeLabel)
     hbox5.addWidget(self.sizeLabel)
     hbox5.addWidget(self.traceInfoLabel)
     hbox6 = QHBoxLayout()
     hbox6.setContentsMargins(0, 0, 20, 0)
     hbox6.addWidget(self.playlistInfoLabel)
     hbox6.addStretch()
     hbox6.addWidget(self.favorInfoLabel)
     mainLayout = QVBoxLayout(self)
     mainLayout.setSpacing(10)
     mainLayout.addLayout(hbox0)
     mainLayout.addLayout(hbox6)
     mainLayout.addLayout(hbox1)
     mainLayout.addLayout(hbox2)
     mainLayout.addLayout(hbox3)
     mainLayout.addLayout(hbox5)
     mainLayout.addWidget(self.countInfoLabel)
     mainLayout.addWidget(self.nearPlaylistLabel)
     mainLayout.addWidget(self.nearPlayedDateLabel)
     mainLayout.addWidget(self.addTimeLabel)
     mainLayout.addWidget(self.modifyTimeLabel)
     mainLayout.addLayout(hbox4)
class ArtistInfoPage(QWidget):
    def __init__(self, parent=None):
        super(ArtistInfoPage, self).__init__(parent)
        self.setup_ui()
        self.create_connections()
    
    def setup_ui(self):
        self.setObjectName('playbackPage')

        #歌手信息页
        self.artistHeadLabel = QLabel(self)
        self.artistHeadLabel.setFixedSize(QSize(90, 90))
        self.artistHeadLabel.setScaledContents(True)
        self.artistName = NewLabel(self, True)
        self.artistName.setFixedSize(QSize(90, 30))
        self.artistGender = QLabel("性别:未知", self)
        self.artistBirthday = QLabel("生日:未知", self)
        self.artistConstellation = QLabel("星座:未知", self)
        self.artistLanguage = QLabel("语言:未知", self)
        self.artistBirthplace = QLabel("出生地:未知", self)
        self.artistDetail = MyTextEdit(self)
        
        #刷新歌手信息缓存按键
        self.refreshBtn = QPushButton(self)
        self.refreshBtn.setFocusPolicy(Qt.NoFocus)
        self.refreshBtn.setIcon(QIcon(IconsHub.Refresh))
        self.refreshBtn.setText('刷新')
        self.refreshBtn.setToolTip("刷新歌手信息")
        self.refreshBtn.setFixedSize(QSize(70, 30))
        
        vbox1 = QVBoxLayout()
        vbox1.setSpacing(10)
        vbox1.addWidget(self.artistHeadLabel)
        vbox1.addWidget(self.artistName)
        
        hbox1 = QHBoxLayout()
        hbox1.addWidget(self.artistGender)
        hbox1.addWidget(self.artistBirthday)
        
        hbox2 = QHBoxLayout()
        hbox2.addWidget(self.artistConstellation)
        hbox2.addWidget(self.artistLanguage)
        
        hbox3 = QHBoxLayout()
        hbox3.addWidget(self.artistBirthplace)
        hbox3.addWidget(self.refreshBtn)
        vbox2 = QVBoxLayout()
        vbox2.addLayout(hbox1)
        vbox2.addLayout(hbox2)
        vbox2.addLayout(hbox3)
        hbox4 = QHBoxLayout()
        hbox4.setSpacing(30)
        hbox4.addLayout(vbox1)
        hbox4.addLayout(vbox2)
        
        mainLayout = QVBoxLayout(self)
        mainLayout.addLayout(hbox4)
        mainLayout.addWidget(self.artistDetail)
    
    def create_connections(self):
        self.refreshBtn.clicked.connect(self.update_infofile_cached)
    
    def set_artist_info(self, artist):
        if artist == 'Zheng-Yejian':
            self.ui_initial()
        elif artist != self.artistName.text():
            infoPath = SearchOnline.get_artist_info_path(artist)
            infoDict = parse_artist_info(infoPath)
            self.artistName.setText(artist)
            self.artistBirthday.setText('生日:%s'%infoDict['birthday'])
            self.artistBirthplace.setText('出生地:%s'%infoDict['birthplace'])
            self.artistLanguage.setText('语言:%s'%infoDict['language'])
            self.artistGender.setText('性别:%s'%infoDict['gender'])
            self.artistConstellation.setText('星座:%s'%infoDict['constellation'])
            self.artistDetail.clear()
            self.artistDetail.setAlignment(Qt.AlignHCenter)
            self.artistDetail.setHtml(self.get_artist_detail_style_text(infoDict['info']))
            imagePath = SearchOnline.get_artist_image_path(artist)
            if imagePath:
                pixmap = QPixmap(imagePath)
            else:
                pixmap = QPixmap(IconsHub.Anonymous)
            self.artistHeadLabel.setPixmap(pixmap)
    
    def update_artist_info(self, title):
        artist, musicName = get_artist_and_musicname_from_title(title)
        return self.set_artist_info(artist)
    
    def update_infofile_cached(self):
        artist = self.artistName.text()
        if artist != '未知':
            infoPath = SearchOnline.get_local_artist_info_path(artist)
            if os.path.exists(infoPath):
                os.remove(infoPath)
                self.set_artist_info(artist)
    
    def ui_initial(self):
        self.artistHeadLabel.setPixmap(QPixmap(IconsHub.Anonymous))
        self.artistName.setText("Zheng-Yejian")
        self.artistBirthday.setText("生日:1992.10.18")
        self.artistBirthplace.setText("出生地:福建")
        self.artistLanguage.setText("语言:国语")
        self.artistGender.setText("性别:男")
        self.artistConstellation.setText("星座:天秤座")
        self.artistDetail.setHtml(self.get_artist_detail_style_text('大家好,我是作者!!!'))
    
    def get_artist_detail_style_text(self, text):
        return "<p style='color:black;font-size:16px;'>%s</p>"%text