From 458e9c9337c8f17e6e03aa8f252a41c0632609af Mon Sep 17 00:00:00 2001 From: Zzaphkiel Date: Sun, 30 Jun 2024 21:08:57 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BB=99=E8=87=AA=E5=8A=A8=20BP=20=E5=8D=A1?= =?UTF-8?q?=E7=89=87=E6=B7=BB=E5=8A=A0=E6=8F=90=E7=A4=BA=E6=96=87=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/common/icons.py | 1 + app/components/profile_level_icon_widget.py | 119 +--------- app/components/tool_tip.py | 147 ++++++++++++ app/resource/i18n/Seraphine.zh_CN.qm | Bin 31211 -> 31402 bytes app/resource/i18n/Seraphine.zh_CN.ts | 238 +++++++++++--------- app/resource/icons/QuestionCircle_black.svg | 5 + app/resource/icons/QuestionCircle_white.svg | 5 + app/view/auxiliary_interface.py | 40 +++- 8 files changed, 326 insertions(+), 229 deletions(-) create mode 100644 app/components/tool_tip.py create mode 100644 app/resource/icons/QuestionCircle_black.svg create mode 100644 app/resource/icons/QuestionCircle_white.svg diff --git a/app/common/icons.py b/app/common/icons.py index ae394a15..05885c78 100644 --- a/app/common/icons.py +++ b/app/common/icons.py @@ -59,6 +59,7 @@ class Icon(FluentIconBase, Enum): TEXTCHECK = 'TextCheck' DOCUMENT = 'Document' ARROWREPEAT = "ArrowRepeat" + QUESTION_CIRCLE = 'QuestionCircle' def path(self, theme=Theme.AUTO): return f'./app/resource/icons/{self.value}_{getIconColor(theme)}.svg' diff --git a/app/components/profile_level_icon_widget.py b/app/components/profile_level_icon_widget.py index 0358d5a3..1417f6fd 100644 --- a/app/components/profile_level_icon_widget.py +++ b/app/components/profile_level_icon_widget.py @@ -10,6 +10,7 @@ from app.common.qfluentwidgets import (ProgressRing, ToolTipFilter, ToolTipPosition, isDarkTheme, themeColor, FlyoutViewBase, TextWrap, FlyoutAnimationType) from app.components.color_label import ColorLabel +from app.components.tool_tip import CustomToolTip from app.common.style_sheet import StyleSheet @@ -139,13 +140,15 @@ def updateAramInfo(self, info): if not self.mFlyout or not info: return - self.mFlyout.updateInfo(info) + self.mFlyout.view.updateInfo(info) def enterEvent(self, a0): if not self.aramInfo or self.mFlyout: return - self.mFlyout = AramFlyout(self.aramInfo, self) + view = AramFlyoutView(self.aramInfo) + + self.mFlyout = CustomToolTip(view, self) self.mFlyout.show() super().enterEvent(a0) @@ -158,118 +161,6 @@ def leaveEvent(self, a0): self.mFlyout = None -class AramFlyout(QWidget): - def __init__(self, info, target: QWidget, parent=None): - super().__init__(parent) - self.target = target - - self.hBoxLayout = QHBoxLayout(self) - self.view = AramFlyoutView(info, parent) - self.setWindowFlags(Qt.ToolTip | Qt.FramelessWindowHint | - Qt.NoDropShadowWindowHint) - self.setAttribute(Qt.WA_TranslucentBackground) - - self.hBoxLayout.addWidget(self.view) - self.hBoxLayout.setContentsMargins(15, 8, 15, 20) - - self.__initShadowEffect() - self.__initAnimation() - - def __initShadowEffect(self, blurRadius=35, offset=(0, 8)): - color = QColor(0, 0, 0, 80 if isDarkTheme() else 30) - - self.shadowEffect = QGraphicsDropShadowEffect(self.view) - self.shadowEffect.setBlurRadius(blurRadius) - self.shadowEffect.setOffset(*offset) - self.shadowEffect.setColor(color) - - self.view.setGraphicsEffect(None) - self.view.setGraphicsEffect(self.shadowEffect) - - def __initAnimation(self): - self.inOpacityAni = QPropertyAnimation( - self, b'windowOpacity', self.parent()) - self.inSlideAni = QPropertyAnimation(self, b'pos', self.parent()) - - self.inOpacityAni.setDuration(187) - self.inSlideAni.setDuration(187) - - self.inOpacityAni.setEasingCurve(QEasingCurve.InOutQuad) - self.inSlideAni.setEasingCurve(QEasingCurve.InOutQuad) - - self.inOpacityAni.setStartValue(0) - self.inOpacityAni.setEndValue(1) - - self.inAniGroup = QParallelAnimationGroup(self) - self.inAniGroup.addAnimation(self.inOpacityAni) - self.inAniGroup.addAnimation(self.inSlideAni) - - self.outAniGroup = QParallelAnimationGroup(self) - - self.outOpacityAni = QPropertyAnimation( - self, b'windowOpacity', self.parent()) - self.outOpacityAni.setEasingCurve(QEasingCurve.InOutQuad) - self.outOpacityAni.setStartValue(1) - self.outOpacityAni.setEndValue(0) - self.outOpacityAni.setDuration(120) - - self.outSlideAni = QPropertyAnimation(self, b'pos', self.parent()) - self.outSlideAni.setEasingCurve(QEasingCurve.InOutQuad) - self.outSlideAni.setDuration(120) - - self.outAniGroup.addAnimation(self.outOpacityAni) - self.outAniGroup.addAnimation(self.outSlideAni) - - self.outAniGroup.finished.connect(self.close) - - def showEvent(self, e): - pos = self.getPosition() - - if self.animationType == FlyoutAnimationType.SLIDE_LEFT: - self.inSlideAni.setStartValue(pos + QPoint(10, 0)) - else: - self.inSlideAni.setStartValue(pos - QPoint(10, 0)) - - self.inSlideAni.setEndValue(pos) - self.inAniGroup.start() - - return super().showEvent(e) - - def fadeOut(self): - self.outSlideAni.setStartValue(self.pos()) - - if self.animationType == FlyoutAnimationType.SLIDE_LEFT: - self.outSlideAni.setEndValue(self.pos() + QPoint(10, 0)) - else: - self.outSlideAni.setEndValue(self.pos() - QPoint(10, 0)) - - self.outAniGroup.finished.connect(self.close) - self.outAniGroup.start() - - def getPosition(self): - pos = self.target.mapToGlobal(QPoint()) - x, y = pos.x(), pos.y() - - hintWidth = self.sizeHint().width() - hintHeight = self.sizeHint().height() - - x += self.target.width() // 2 - hintWidth // 2 - y += self.target.height() // 2 - hintHeight // 2 - - dx = -hintWidth // 2 - 45 - - self.animationType = FlyoutAnimationType.SLIDE_LEFT - - if x + dx < -15: - self.animationType = FlyoutAnimationType.SLIDE_RIGHT - dx = -dx - - return QPoint(x + dx, y) - - def updateInfo(self, info): - self.view.updateInfo(info) - - class AramFlyoutView(FlyoutViewBase): def __init__(self, info, parent=None): super().__init__(parent=parent) diff --git a/app/components/tool_tip.py b/app/components/tool_tip.py new file mode 100644 index 00000000..241f5494 --- /dev/null +++ b/app/components/tool_tip.py @@ -0,0 +1,147 @@ + +from PyQt5.QtCore import ( + Qt, QPoint, QPropertyAnimation, QParallelAnimationGroup, QEasingCurve, + QSize) +from PyQt5.QtGui import QColor +from PyQt5.QtWidgets import (QWidget, QHBoxLayout, + QGraphicsDropShadowEffect) + +from app.common.qfluentwidgets import (isDarkTheme, TransparentToolButton, + FlyoutAnimationType, FluentIcon) +from app.common.icons import Icon + + +class CustomToolTip(QWidget): + def __init__(self, view: QWidget, target: QWidget, parent=None): + super().__init__(parent) + self.target = target + + self.hBoxLayout = QHBoxLayout(self) + self.view = view + self.setWindowFlags(Qt.ToolTip | Qt.FramelessWindowHint | + Qt.NoDropShadowWindowHint) + self.setAttribute(Qt.WA_TranslucentBackground) + + self.hBoxLayout.addWidget(self.view) + self.hBoxLayout.setContentsMargins(15, 8, 15, 20) + + self.__initShadowEffect() + self.__initAnimation() + + def __initShadowEffect(self, blurRadius=35, offset=(0, 8)): + color = QColor(0, 0, 0, 80 if isDarkTheme() else 30) + + self.shadowEffect = QGraphicsDropShadowEffect(self.view) + self.shadowEffect.setBlurRadius(blurRadius) + self.shadowEffect.setOffset(*offset) + self.shadowEffect.setColor(color) + + self.view.setGraphicsEffect(None) + self.view.setGraphicsEffect(self.shadowEffect) + + def __initAnimation(self): + self.inOpacityAni = QPropertyAnimation( + self, b'windowOpacity', self.parent()) + self.inSlideAni = QPropertyAnimation(self, b'pos', self.parent()) + + self.inOpacityAni.setDuration(187) + self.inSlideAni.setDuration(187) + + self.inOpacityAni.setEasingCurve(QEasingCurve.InOutQuad) + self.inSlideAni.setEasingCurve(QEasingCurve.InOutQuad) + + self.inOpacityAni.setStartValue(0) + self.inOpacityAni.setEndValue(1) + + self.inAniGroup = QParallelAnimationGroup(self) + self.inAniGroup.addAnimation(self.inOpacityAni) + self.inAniGroup.addAnimation(self.inSlideAni) + + self.outAniGroup = QParallelAnimationGroup(self) + + self.outOpacityAni = QPropertyAnimation( + self, b'windowOpacity', self.parent()) + self.outOpacityAni.setEasingCurve(QEasingCurve.InOutQuad) + self.outOpacityAni.setStartValue(1) + self.outOpacityAni.setEndValue(0) + self.outOpacityAni.setDuration(120) + + self.outSlideAni = QPropertyAnimation(self, b'pos', self.parent()) + self.outSlideAni.setEasingCurve(QEasingCurve.InOutQuad) + self.outSlideAni.setDuration(120) + + self.outAniGroup.addAnimation(self.outOpacityAni) + self.outAniGroup.addAnimation(self.outSlideAni) + + self.outAniGroup.finished.connect(self.close) + + def showEvent(self, e): + pos = self.getPosition() + + if self.animationType == FlyoutAnimationType.SLIDE_LEFT: + self.inSlideAni.setStartValue(pos + QPoint(10, 0)) + else: + self.inSlideAni.setStartValue(pos - QPoint(10, 0)) + + self.inSlideAni.setEndValue(pos) + self.inAniGroup.start() + + return super().showEvent(e) + + def fadeOut(self): + self.outSlideAni.setStartValue(self.pos()) + + if self.animationType == FlyoutAnimationType.SLIDE_LEFT: + self.outSlideAni.setEndValue(self.pos() + QPoint(10, 0)) + else: + self.outSlideAni.setEndValue(self.pos() - QPoint(10, 0)) + + self.outAniGroup.finished.connect(self.close) + self.outAniGroup.start() + + def getPosition(self): + pos = self.target.mapToGlobal(QPoint()) + x, y = pos.x(), pos.y() + + hintWidth = self.sizeHint().width() + hintHeight = self.sizeHint().height() + + x += self.target.width() // 2 - hintWidth // 2 + y += self.target.height() // 2 - hintHeight // 2 + + dx = -hintWidth // 2 - 45 + + self.animationType = FlyoutAnimationType.SLIDE_LEFT + + if x + dx < -15: + self.animationType = FlyoutAnimationType.SLIDE_RIGHT + dx = -dx + + return QPoint(x + dx, y) + + +class HelpButton(TransparentToolButton): + def __init__(self, view: QWidget, parent: QWidget = None): + super().__init__(Icon.QUESTION_CIRCLE, parent=parent) + + self.setFixedSize(QSize(26, 26)) + self.setFixedSize(QSize(16, 16)) + + self.view = view + self.mToolTip = None + + def enterEvent(self, e): + if self.mToolTip: + return + + self.mToolTip = CustomToolTip(self.view, self) + self.mToolTip.show() + + return super().enterEvent(e) + + def leaveEvent(self, a0): + if not self.mToolTip: + return + + self.mToolTip.fadeOut() + self.mToolTip = None diff --git a/app/resource/i18n/Seraphine.zh_CN.qm b/app/resource/i18n/Seraphine.zh_CN.qm index 352ef0ebba15629deb3543bd001f9a8eb8c10495..eb57fc63f817a4815abf6bff9ba7cb3c7a50d179 100644 GIT binary patch delta 3769 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 IthL19zj*c>o&W#< delta 3567 zcmYk8d03Ry9>;$(?>fsngKX|GA|ME)Ac820vMY$}$`Zyhz))c>sF68tMJ2~o@Ce#g^upZmu=pZC0T-gAD-_xC%e@saBGpQ=iC ztIuCVYEL4c^WYUCmmZA1eHe?Hhy**LUjE<+qG6jDgJp0GQP?pslPI{E(NY0sW4#8< zttWDKV)RPEoCu8Zjg4M&iH0vCE4jb(>VdrQ!H7lp<2w+~?lnXqw(&F2HpWIHF&^jv z+QtuvM%l&*AjTeji9&50%Q&!%C^~|uu$U;uhp0z?#^_+8@iLL?bD|0Bt(dTuDDf{r0-ii2wJdDdB z{xs-%l5ub!;x7y(vb#$BZ*D|mo)O=Lu|M8Fv5rG%)g)*Tvamc70%44|6Jyj|5(*9x zr6rKC0t*IcNmv<4)VGL)+6bclKa;TQ2*wIyLWedo2-&V?L zhY&}sq8TGb5&4x-dEc9e;6kb>T}7l^rSe=tKtO6EUrQ|e>Thz zKT<7SfbDvGqgsCH43yELs(R*zcr>ckJ~;)|-BxWY9)}v>-d8mrSw>_cReSevWcq~a z#-kK$7_NHo6oC!js(M;+m8jcGbx-~zHi}ZarmKmPK37klV!=W?)$^~J2!*0v8nlJz z?OgS8YKNj8s2e(Wqu{hOf3Dr5pIhlU0a-AHVH# zcOs`j{B|F_9~s0LznHgP7#$6*?&e>dLhg+kM&D4uD_08-JA^^eMbLsq2;6!UhGq%F z8evdal@JrO5GfxmB))wB+W1;Xt3oaGI=~oI#u&X?NZSPiha@ltFBgg$VfaXuuq0&$ zQC^!>STPK__8!F;)hMipIz|-vJ7d&q!payF-D_pSx>J~!;v&?Az<`K+;hUElA~&6I zya66%O%d8wM-mN67TO07MXCl07aO4|$4KEy3g#DlDO^djt+So6Fho?H`xB9~-enK+ zK2Z~fTuxXlx}2N_RgV(;&4Y!-is&~npGaRIj`4!{obHHW_Yo;cV$>Fklj~4s{a%W1 zX~!ah`^BX%4Mc{4;xZE$x?Wrr0*CtT6gTK^5=|Z;ZasP*hPW_V3w{=xcL-3gJ!AG? z;=%j`SXRy`-4)w*(i0UyzcBb>h_$cl`fYyoOdofoX!40R*JdBUQGT%GCV}69PA{IGKA70 zR`SZl2N@C4kZ(*xG)oFNorF*aOMzXelE``~atRLQiE1fs`%FaYk(7{Bk5KESnJ9mf z7BXt@NV6B9A&qI3KFD^&|MR4IO<4b}sZzQ3XQ=%6VCsLP4+hCawupY4nu$K|~W zhX@>y_kM;C^nb`-4cP=w7sy|)IDvWg^3gND!Q*E6TbDQC>OQ%xp_M3Vy!`jE3>bW0 zqkZUr!@R$y+g2Dd=&Z&$_83x^pfNpPM3mj48TJF_8$Qv*Su4;&ec#h0-s~WXJ)ue3 zbO&eHP0fzZxiG9v(_DZYs}5)m=RsVi4o$my3sSOD^J~#obVx78=vKyTd(Cy@UUay6 zP1j&MwDL;LUlPjGeuUPi_$AKF0IlC}h))>8D8JBJV`k$6$NSpECgd(i(&pCT%Hbc) zm{X@UJ2+zF9BollK9QwGTi#R$gJQH>?9U;jmD-($cH)dXp*<9Ng-DmBeG7cGpQ6W~knxGqqlW0jG3+S>7w4YBbttc_Pj#CMUW4d(-M3nQ+*_)3|JJuc6EAh& zZGMWwBUE?E_Y96%Pe#q(x;y)kG9(p`MI+f|NdFw)7epG&ZYdDy7{ijOYNV*mQ0259k;yjHob5#Ci!n4MHKBaR z7!IVtfyf*~bBfgtu_HtC@56Bs$uJx~cnmFbg`u;452~Qd@YIYAbIu!k)s*8Ddyg@9 zx3T{Z5E*qEBf=lT@I{Pq?Z##Mk#m#=%<8NE8x(J4Te(! zrIKlawbb)}+YCxF=a=T0P2mZtrqby-g=SO1lxe1E=8}B#tKCw^{@=dXzDZTE)$zZT C>cVmW diff --git a/app/resource/i18n/Seraphine.zh_CN.ts b/app/resource/i18n/Seraphine.zh_CN.ts index c92abb2b..714b529e 100644 --- a/app/resource/i18n/Seraphine.zh_CN.ts +++ b/app/resource/i18n/Seraphine.zh_CN.ts @@ -42,37 +42,37 @@ AramFlyoutView - + Damage Dealt: 造成伤害: - + Damage Received: 承受伤害: - + Healing Increase: 治疗效果: - + Shield Increase: 护盾效果: - + Ability Haste: 技能急速: - + Tenacity: 韧性: - + Powered by: jddld.com 数据来源:jddld.com @@ -141,12 +141,12 @@ 已启用,自动禁用: - + Disabled 未启用 - + Enable: 启用自动 Ban: @@ -156,70 +156,79 @@ 若队友预选该英雄,则空 Ban: - + Ban after a delay of seconds: 在进入禁用阶段后 Ban 人的秒数: - + Default Configurations 默认设置 - + Default champions: 默认禁用英雄: - + Choose 选择 - + Rank Configurations 按照位置设置 - + Top: 上路: - + Juggle: 打野: - + Mid: 中路: - + Bottom: 下路: - + Support: 辅助: - + Prevent banning champions picked by teammates: 若队友预选该英雄,则空 Ban: - + Reset 恢复默认 - + Enabled 已启用 + + + Default settings must be set. + +If champions set by lane are not available, default settings will be used. + 必须设置默认英雄 + +若非排位模式或按位置设置英雄不可用,则将使用默认设置 + AutoSelectChampionCard @@ -234,7 +243,7 @@ 已启用,自动选择: - + Disabled 未启用 @@ -244,7 +253,7 @@ 将要自动亮起的英雄: - + Enable: 启用自动亮起: @@ -254,7 +263,7 @@ 在时间结束后确定选择(更换亮起英雄后无效) - + Completed before timeout: 在时间结束时确定选择: @@ -279,55 +288,64 @@ 默认设置 - + Default champions: 默认亮起英雄: - + Choose 选择 - + Rank Configurations 按照位置设置 - + Top: 上路: - + Juggle: 打野: - + Mid: 中路: - + Bottom: 下路: - + Support: 辅助: - + Enabled 已启用 - + Reset 恢复默认 + + + Default settings must be set. + +If champions set by lane are not available, default settings will be used. + 必须设置默认英雄 + +若非排位模式或按位置设置英雄不可用,则将使用默认设置 + AuxiliaryInterface @@ -941,17 +959,17 @@ GameTab - + remake 重开 - + win 胜利 - + lose 失败 @@ -1142,7 +1160,7 @@ 对局信息 - + Start LOL 启动游戏 @@ -1162,12 +1180,12 @@ 客户端已连接 - + Invalid path 路径非法 - + Please set the correct directory of the LOL client in the setting page 请在设置页面中设置正确的 LOL 客户端路径 @@ -1177,52 +1195,52 @@ 启动页 - + Start LOL successfully 启动客户端成功 - + Home 游戏大厅 - + Selecting Champions 英雄选择 - + Gaming 游戏中 - + Waiting for status 等待游戏结果 - + End of game 游戏结束 - + Lobby 房间组队中 - + Ready check 匹配确认 - + Match making 匹配中 - + Exception occurred 😥 程序出现异常 😥 @@ -1232,12 +1250,12 @@ 战绩查询 👀 - + Exit 直接退出 - + Minimize 最小化到任务栏 @@ -1247,7 +1265,7 @@ 退出 - + Do you wish to exit? 你第一次点击了关闭按钮 @@ -1288,17 +1306,17 @@ 客户端信息请求失败 - + Blue Team 蓝色方 - + Red Team 红色方 - + Waiting reconnect 等待重新连接 @@ -1338,22 +1356,22 @@ 请确保能连接至 GitHub - + ( - + ) - + , - + Choose action for close button (you can modify it at any time in the settings page) 请选择点击关闭按钮的默认行为 @@ -1983,82 +2001,82 @@ 客户端路径 - + Auto-start LOL 自动启动游戏 - + Launch LOL client upon opening Seraphine automatically 启动 Seraphine 时自动启动 LOL 客户端 - + Personalization 个性化 - + Application theme 应用主题 - + Change the appearance of Seraphine 调整 Seraphine 的外观主题 - + Light 浅色 - + Dark 深色 - + Use system setting 跟随系统设置 - + Theme color 主题色 - + Change the theme color of Seraphine 调整 Seraphine 的主题色 - + Interface zoom 界面缩放 - + Change the size of widgets and fonts 调整部件和字体的大小 - + Updated successfully 更新成功 - + Configuration takes effect after restart 设置在重启软件后生效 - + Language 语言 - + Set your preferred language for Seraphine 选择 Seraphine 所使用的语言 @@ -2089,52 +2107,52 @@ 在对局详情界面中显示段位图标,启动该选项将影响加载该界面的速度 - + About 关于 - + Provide feedback 提供反馈 - + Help us improve Seraphine by providing feedback 通过提供反馈帮助我们改善 Seraphine - + Copyright 版权所有 - + Version 当前版本 - + Delete 删除 - + Delete cache 清除缓存 - + Delete all game resources (Apply it when game resources update) 删除所有游戏资源的缓存(建议在游戏资源有更新时使用) - + View GitHub 查看 GitHub - + Really? 真的要删除吗? @@ -2146,32 +2164,32 @@ 这有可能会消耗更多的时间 - + Confirm delete 确定删除 - + Mica effect 云母效果 - + Apply semi transparent to windows and surfaces (only available on Win11) 窗口和表面显示半透明(仅在 Win11 上可用) - + Minimize to tray on close 最小化到任务栏托盘 - + Minimize to system tray when clicking close 点击右上角关闭时将程序最小化到托盘 - + Settings have been applied 设置已应用 @@ -2186,12 +2204,12 @@ 打开此选项后,当你在排位时,对局信息界面将只显示排位模式对局战绩 - + Check for updates 检查更新 - + Automatically check for updates when software starts 在 Seraphine 启动时自动检查更新 @@ -2203,20 +2221,20 @@ Minimize windows during game activities - 游戏进行时最小化 Seraphine 窗口 + 游戏进行时最小化 Seraphine 窗口 Reduce CPU usage for rendering UI during gaming - 在游戏时通过避免渲染窗口以减少 CPU 使用 + 在游戏时通过避免渲染窗口以减少 CPU 使用 - + Log Level 日志等级 - + The level of logging for Seraphine (take effect after restart) 修改 Seraphine 记录日志的等级(重启后生效) @@ -2226,12 +2244,12 @@ HTTP 代理 - + Using a proxy when connecting to GitHub 连接 GitHub 时启用 HTTP 代理 - + Update 软件更新 @@ -2251,17 +2269,17 @@ 该值越大数据加载速度越快,但越可能引起客户端闪退 - + Game tabs color 对局卡片颜色 - + Change the color of game tabs 改变对局卡片提示胜利 / 失败的颜色 - + HTTP proxy HTTP 代理 @@ -2271,22 +2289,22 @@ 在对局详情界面中显示段位图标,启动该选项将影响加载该界面的速度 - + Open 打开文件夹 - + Log file 日志文件 - + Open log directory 打开日志文件夹 - + Game resources will be downloaded again when they are used by Seraphine, which will cost more time 游戏资源将会在它们要被 Seraphine 使用时重新下载 @@ -2425,12 +2443,12 @@ when they are used by Seraphine, which will cost more time SummonerInfoView - + Ranked Solo / Duo 单 / 双排 - + Ranked Flex 灵活排位 diff --git a/app/resource/icons/QuestionCircle_black.svg b/app/resource/icons/QuestionCircle_black.svg new file mode 100644 index 00000000..bcf8c728 --- /dev/null +++ b/app/resource/icons/QuestionCircle_black.svg @@ -0,0 +1,5 @@ + + + \ No newline at end of file diff --git a/app/resource/icons/QuestionCircle_white.svg b/app/resource/icons/QuestionCircle_white.svg new file mode 100644 index 00000000..e910b09d --- /dev/null +++ b/app/resource/icons/QuestionCircle_white.svg @@ -0,0 +1,5 @@ + + + \ No newline at end of file diff --git a/app/view/auxiliary_interface.py b/app/view/auxiliary_interface.py index 81272bff..09d4a999 100644 --- a/app/view/auxiliary_interface.py +++ b/app/view/auxiliary_interface.py @@ -9,7 +9,7 @@ qconfig, IndicatorPosition, InfoBar, InfoBarPosition, SpinBox, ExpandGroupSettingCard, TransparentToolButton, FluentIcon, Flyout, FlyoutAnimationType, TeachingTip, - MessageBox, CheckBox) + MessageBox, CheckBox, ToolTipFilter, ToolTipPosition) from PyQt5.QtCore import Qt, pyqtSignal, QEvent, QSize from PyQt5.QtWidgets import (QWidget, QLabel, QCompleter, QVBoxLayout, QHBoxLayout, QGridLayout, @@ -1208,6 +1208,8 @@ def __init__(self, title, content=None, self.defaultCfgWidget = QWidget(self.view) self.defaultCfgLayout = QGridLayout(self.defaultCfgWidget) self.defaultHintLabel = QLabel(self.tr("Default Configurations")) + self.helpLayout = QHBoxLayout() + self.helpButotn = TransparentToolButton(Icon.QUESTION_CIRCLE) self.defaultLabel = QLabel(self.tr("Default champions: ")) self.defaultChampions = ChampionsCard() @@ -1251,6 +1253,14 @@ def __initWidget(self): self.defaultHintLabel.setStyleSheet("font: bold") self.rankLabel.setStyleSheet("font: bold") + self.helpButotn.setFixedSize(QSize(26, 26)) + self.helpButotn.setIconSize(QSize(16, 16)) + + self.helpButotn.setToolTip(self.tr( + "Default settings must be set.\n\nIf champions set by lane are not available, default settings will be used.")) + self.helpButotn.installEventFilter(ToolTipFilter( + self.helpButotn, 0, ToolTipPosition.RIGHT)) + # 逻辑是,必须要设置默认,才能设置具体分路和启动功能 selected = qconfig.get(self.defaultChampionsConfigItem) != [] checked = qconfig.get(self.enableConfigItem) @@ -1286,8 +1296,13 @@ def __initLayout(self): self.defaultCfgLayout.setContentsMargins(48, 18, 44, 18) self.defaultCfgLayout.setSizeConstraint(QHBoxLayout.SetMinimumSize) - self.defaultCfgLayout.addWidget( - self.defaultHintLabel, 0, 0, Qt.AlignLeft) + self.helpLayout.setContentsMargins(0, 0, 0, 0) + self.helpLayout.setSpacing(10) + self.helpLayout.addWidget(self.defaultHintLabel) + self.helpLayout.addWidget(self.helpButotn) + + self.defaultCfgLayout.addLayout( + self.helpLayout, 0, 0, Qt.AlignLeft) self.defaultCfgLayout.addWidget( self.defaultLabel, 1, 0, Qt.AlignLeft) @@ -1457,6 +1472,8 @@ def __init__(self, title, content=None, self.defaultCfgWidget = QWidget(self.view) self.defaultCfgLayout = QGridLayout(self.defaultCfgWidget) self.defaultHintLabel = QLabel(self.tr("Default Configurations")) + self.helpLayout = QHBoxLayout() + self.helpButotn = TransparentToolButton(Icon.QUESTION_CIRCLE) self.defaultLabel = QLabel(self.tr("Default champions: ")) self.defaultChampions = ChampionsCard() @@ -1508,6 +1525,14 @@ def __initWidget(self): delayTime = qconfig.get(self.delayTimeConfigItem) friendlyEnabled = qconfig.get(self.friendlyConfigItem) + self.helpButotn.setFixedSize(QSize(26, 26)) + self.helpButotn.setIconSize(QSize(16, 16)) + + self.helpButotn.setToolTip(self.tr( + "Default settings must be set.\n\nIf champions set by lane are not available, default settings will be used.")) + self.helpButotn.installEventFilter(ToolTipFilter( + self.helpButotn, 0, ToolTipPosition.RIGHT)) + for ty in ['default', 'top', 'jug', 'mid', 'bot', 'sup']: button: PushButton = getattr(self, f"{ty}SelectButton") button.setMinimumWidth(100) @@ -1545,8 +1570,13 @@ def __initLayout(self): self.defaultCfgLayout.setContentsMargins(48, 18, 44, 18) self.defaultCfgLayout.setSizeConstraint(QHBoxLayout.SetMinimumSize) - self.defaultCfgLayout.addWidget( - self.defaultHintLabel, 0, 0, Qt.AlignLeft) + self.helpLayout.setContentsMargins(0, 0, 0, 0) + self.helpLayout.setSpacing(10) + self.helpLayout.addWidget(self.defaultHintLabel) + self.helpLayout.addWidget(self.helpButotn) + + self.defaultCfgLayout.addLayout( + self.helpLayout, 0, 0, Qt.AlignLeft) self.defaultCfgLayout.addWidget( self.defaultLabel, 1, 0, Qt.AlignLeft)