class NavigationMenu(NavigationWidget): """ 导航菜单 """ def __init__(self, parent=None): super().__init__(parent) # 是否削减设置按钮底部空白标志位 self.__isShowBottomSpacing = False self.__ani = QPropertyAnimation(self, b"geometry") # 才叫你窗口效果 self.windowEffect = WindowEffect() self.__initWidget() def __initWidget(self): """ 初始化小部件 """ self.resize(60, 800) self.setAttribute(Qt.WA_TranslucentBackground) self.setWindowFlags(Qt.NoDropShadowWindowHint | Qt.Popup) # self.hWnd = HWND(int(self.winId())) self.windowEffect.setAcrylicEffect(self.winId(), "F2F2F299", False) def resizeEvent(self, e): """ 调整小部件尺寸 """ super().resizeEvent(e) self.settingButton.move( 0, self.height() - 62 - 10 - self.__isShowBottomSpacing * 115 ) self.searchLineEdit.resize(self.width() - 30, self.searchLineEdit.height()) def aniShow(self): """ 动画显示 """ super().show() self.__ani.setStartValue(QRect(self.x(), self.y(), 60, self.height())) self.__ani.setEndValue(QRect(self.x(), self.y(), 400, self.height())) self.__ani.setDuration(85) self.__ani.start() self.__ani.setEasingCurve(QEasingCurve.InOutQuad) def aniHide(self): """ 动画隐藏 """ self.__ani.setStartValue(QRect(self.x(), self.y(), 400, self.height())) self.__ani.setEndValue(QRect(self.x(), self.y(), 60, self.height())) self.__ani.finished.connect(self.__hideAniFinishedSlot) self.__ani.setDuration(85) self.__ani.start() def __hideAniFinishedSlot(self): """ 隐藏窗体的动画结束 """ super().hide() self.resize(60, self.height()) self.__ani.disconnect() def setBottomSpacingVisible(self, isBottomSpacingVisible: bool): """ 是否削减设置按钮底部空白 """ self.__isShowBottomSpacing = isBottomSpacingVisible @property def isShowBottomSpacing(self): return self.__isShowBottomSpacing
class NavigationMenu(QWidget): """ 导航菜单 """ def __init__(self, parent=None): super().__init__(parent=parent) # 创建按钮 self.navigationButton = QToolButton(self) self.boardButton = NavigationButton(self.tr('Chess board'), ':images/navigation_menu/棋盘.png', True, self) self.settingButton = NavigationButton( self.tr('Settings'), ':images/navigation_menu/设置.png', False, self) self.button_list = [self.boardButton, self.settingButton] # 实例化窗口特效和动画 self.windowEffect = WindowEffect() self.__ani = QPropertyAnimation(self, b'geometry') # 初始化界面 self.__initWidget() def __initWidget(self): """ 初始化界面 """ self.resize(320, 755) self.setAttribute(Qt.WA_TranslucentBackground) self.setWindowFlags(Qt.NoDropShadowWindowHint | Qt.Popup) self.windowEffect.setAcrylicEffect(self.winId(), "E9ECED99", False) self.boardButton.move(0, 50) self.settingButton.move(0, self.height() - 60) self.navigationButton.setFixedSize(50, 50) self.navigationButton.setIcon( Icon(':images/navigation_menu/显示导航菜单.png')) def aniShow(self): """ 动画显示 """ super().show() self.__ani.setStartValue(QRect(self.x(), self.y(), 50, self.height())) self.__ani.setEndValue(QRect(self.x(), self.y(), 320, self.height())) self.__ani.setEasingCurve(QEasingCurve.InOutQuad) self.__ani.setDuration(85) self.__ani.start() def aniHide(self): """ 动画隐藏 """ self.__ani.setStartValue(QRect(self.x(), self.y(), 320, self.height())) self.__ani.setEndValue(QRect(self.x(), self.y(), 50, self.height())) self.__ani.finished.connect(self.__onHideAniFinished) self.__ani.setDuration(85) self.__ani.start() def __onHideAniFinished(self): """ 隐藏窗体的动画结束 """ super().hide() self.resize(1, self.height()) self.__ani.disconnect() def paintEvent(self, e): """ 绘制分隔符 """ painter = QPainter(self) pen = QPen(QColor(0, 0, 0, 30)) painter.setPen(pen) painter.drawLine(15, self.settingButton.y() - 1, self.width() - 15, self.settingButton.y() - 1) def setSelectedButton(self, index: int): """ 设置选中的按钮 """ for i, button in enumerate(self.button_list): button.setSelected(i == index)
class SongInfoCard(QWidget): """ 歌曲信息卡 """ def __init__(self, songInfo: dict = None, parent=None): super().__init__(parent) self.resize(320, 55) # 创建小部件 self.songNameLabel = QLabel(self) self.songerNameLabel = QLabel(self) self.opacityEffect = QGraphicsOpacityEffect(self) self.ani = QPropertyAnimation(self.opacityEffect, b"opacity") # 初始化 self.__initWidget() # 设置窗口信息 self.updateCard(songInfo) def __initWidget(self): """ 初始化小部件 """ self.setFixedHeight(55) self.opacityEffect.setOpacity(1) self.setGraphicsEffect(self.opacityEffect) self.setAttribute(Qt.WA_TranslucentBackground) self.songNameLabel.setProperty("name", "smallestModeSongNameLabel") self.songerNameLabel.setProperty("name", "smallestModeSongerNameLabel") def __setSongInfo(self, songInfo: dict): """ 设置标签信息 """ if not songInfo: songInfo = {} self.songName = songInfo.get("songName", "未知歌曲") # type:str self.songerName = songInfo.get("songer", "未知歌手") # type:str self.songNameLabel.setText(self.songName) self.songerNameLabel.setText(self.songerName) def updateCard(self, songInfo: dict): """ 更新窗口 """ self.__setSongInfo(songInfo) self.__adjustLabel() def __adjustLabel(self): """ 根据当前窗口的宽度设置标签文本和位置 """ fontMetrics = QFontMetrics(QFont("Microsoft YaHei", 12, 75)) # 字符串的最大宽度 maxWidth = self.width() - 30 songNameWidth, songerNameWidth = 0, 0 # 调整歌名 for index, char in enumerate(self.songName): if songNameWidth + fontMetrics.width(char) > maxWidth: self.songNameLabel.setText(self.songName[:index]) break songNameWidth += fontMetrics.width(char) self.songNameLabel.setFixedWidth(songNameWidth) # 调整歌手名 fontMetrics = QFontMetrics(QFont("Microsoft YaHei", 11)) for index, char in enumerate(self.songerName): if songerNameWidth + fontMetrics.width(char) > maxWidth: self.songerNameLabel.setText(self.songerName[:index]) break songerNameWidth += fontMetrics.width(char) self.songerNameLabel.setFixedWidth(songerNameWidth) # 调整标签位置 self.songNameLabel.move(int(self.width() / 2 - songNameWidth / 2), 0) self.songerNameLabel.move(int(self.width() / 2 - songerNameWidth / 2), 30) def resizeEvent(self, e): """ 改变窗口大小时调整标签 """ super().resizeEvent(e) self.__adjustLabel() def aniHide(self): """ 淡出 """ self.ani.setStartValue(1) self.ani.setEndValue(0) self.ani.setDuration(150) self.ani.finished.connect(self.__hideAniSlot) self.ani.start() def aniShow(self): """ 淡入 """ super().show() self.ani.setStartValue(0) self.ani.setEndValue(1) self.ani.setDuration(150) self.ani.start() def __hideAniSlot(self): """ 淡出动画完成的槽函数 """ self.ani.disconnect() super().hide()