From ceabeee3d97bca9c5f476d0aff432b76bd0a80e5 Mon Sep 17 00:00:00 2001 From: Hpero4 Date: Wed, 13 Sep 2023 22:22:28 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E9=BB=98=E8=AE=A4=E5=AF=B9=E5=B1=80?= =?UTF-8?q?=E6=95=B0=E9=87=8F=20"=E5=BA=94=E7=94=A8"=20=E6=8C=89=E9=92=AE?= =?UTF-8?q?=E7=82=B9=E5=87=BB=E6=97=B6=E5=8F=8D=E9=A6=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/view/setting_interface.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/view/setting_interface.py b/app/view/setting_interface.py index 96e00ac8..31c6c366 100644 --- a/app/view/setting_interface.py +++ b/app/view/setting_interface.py @@ -224,6 +224,8 @@ def __connectSignalToSlot(self): self.themeColorCard.colorChanged.connect(setThemeColor) cfg.appRestartSig.connect(self.__showRestartToolTip) + self.careerGamesCount.pushButton.clicked.connect( + self.__showUpdatedSuccessfullyToolTip) self.teamGamesNumberCard.pushButton.clicked.connect( self.__showUpdatedSuccessfullyToolTip) self.feedbackCard.clicked.connect( From ea3356e861bb596ec68d6b7b9a65bb9f93b9f0af Mon Sep 17 00:00:00 2001 From: Hpero4 Date: Wed, 13 Sep 2023 22:22:28 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E9=BB=98=E8=AE=A4=E5=AF=B9=E5=B1=80?= =?UTF-8?q?=E6=95=B0=E9=87=8F=20"=E5=BA=94=E7=94=A8"=20=E6=8C=89=E9=92=AE?= =?UTF-8?q?=E7=82=B9=E5=87=BB=E6=97=B6=E5=8F=8D=E9=A6=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/view/setting_interface.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/view/setting_interface.py b/app/view/setting_interface.py index 96e00ac8..31c6c366 100644 --- a/app/view/setting_interface.py +++ b/app/view/setting_interface.py @@ -224,6 +224,8 @@ def __connectSignalToSlot(self): self.themeColorCard.colorChanged.connect(setThemeColor) cfg.appRestartSig.connect(self.__showRestartToolTip) + self.careerGamesCount.pushButton.clicked.connect( + self.__showUpdatedSuccessfullyToolTip) self.teamGamesNumberCard.pushButton.clicked.connect( self.__showUpdatedSuccessfullyToolTip) self.feedbackCard.clicked.connect( From 00e158a93bbbcdb78e489ee01e163542e761a7f8 Mon Sep 17 00:00:00 2001 From: Hpero4 Date: Sat, 16 Sep 2023 20:00:20 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E5=AF=B9=E5=B1=80=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E9=A1=B5=E4=BD=BF=E7=94=A8=E8=8B=B1=E9=9B=84=E5=A4=B4=E5=83=8F?= =?UTF-8?q?=E6=9B=BF=E4=BB=A3=E5=8F=AC=E5=94=A4=E5=B8=88=E5=A4=B4=E5=83=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/components/profile_level_icon_widget.py | 14 +++++--- app/lol/connector.py | 9 ++++- app/lol/listener.py | 8 +++++ app/view/game_info_interface.py | 28 +++++++++++++-- app/view/main_window.py | 40 ++++++++++++++++++--- 5 files changed, 86 insertions(+), 13 deletions(-) diff --git a/app/components/profile_level_icon_widget.py b/app/components/profile_level_icon_widget.py index 696c74db..a390fd23 100644 --- a/app/components/profile_level_icon_widget.py +++ b/app/components/profile_level_icon_widget.py @@ -91,13 +91,17 @@ def paintEvent(self, event): painter.setClipPath(clipPath) painter.drawImage(self.sep // 2, self.sep // 2, scaledImage) - def updateIcon(self, icon, xpSinceLastLevel, xpUntilNextLevel, text=""): + def updateIcon(self, icon: str, xpSinceLastLevel=None, xpUntilNextLevel=None, text=""): self.image = QImage(icon) - self.xpSinceLastLevel = xpSinceLastLevel - self.xpUntilNextLevel = xpUntilNextLevel + if xpSinceLastLevel is None and xpUntilNextLevel is not None: + self.xpSinceLastLevel = xpSinceLastLevel + self.xpUntilNextLevel = xpUntilNextLevel + + self.setToolTip(f"Exp: {xpSinceLastLevel} / {xpUntilNextLevel}") + + if text: + self.progressRing.text = text - self.setToolTip(f"Exp: {xpSinceLastLevel} / {xpUntilNextLevel}") - self.progressRing.text = text self.repaint() diff --git a/app/lol/connector.py b/app/lol/connector.py index 3b2eeafd..12242075 100644 --- a/app/lol/connector.py +++ b/app/lol/connector.py @@ -163,7 +163,14 @@ def getSummonerSpellIcon(self, spellId): return icon @retry() - def getChampionIcon(self, championId): + def getChampionIcon(self, championId) -> str: + """ + + @param championId: + @return: path + @rtype: str + """ + if championId == -1: return "app/resource/images/champion-0.png" diff --git a/app/lol/listener.py b/app/lol/listener.py index b5c413ad..1c393cd2 100644 --- a/app/lol/listener.py +++ b/app/lol/listener.py @@ -51,6 +51,7 @@ def run(self): class LolClientEventListener(QThread): currentSummonerProfileChanged = pyqtSignal(dict) gameStatusChanged = pyqtSignal(str) + champSelectChanged = pyqtSignal(dict) def __init__(self, parent) -> None: super().__init__(parent) @@ -64,6 +65,9 @@ async def onCurrentSummonerProfileChanged(data): async def onGameFlowPhaseChanged(data): self.gameStatusChanged.emit(data["data"]) + async def onChampSelectChanged(data): + self.champSelectChanged.emit(data["data"]) + async def defaultHandler(data): print(data) @@ -84,6 +88,10 @@ async def main(): wllp.subscription_filter_endpoint( allEventSubscription, '/lol-gameflow/v1/gameflow-phase', onGameFlowPhaseChanged) + # 订阅英雄选择消息 + wllp.subscription_filter_endpoint( + allEventSubscription, '/lol-champ-select/v1/session', onChampSelectChanged) + # print("[INFO] Event listener initialized.") while True: await asyncio.sleep(10) diff --git a/app/view/game_info_interface.py b/app/view/game_info_interface.py index 383f4ab6..ca777128 100644 --- a/app/view/game_info_interface.py +++ b/app/view/game_info_interface.py @@ -1,8 +1,10 @@ -from PyQt5.QtCore import pyqtSignal, Qt +from typing import Dict + +from PyQt5.QtCore import pyqtSignal, Qt, QPropertyAnimation, QRect from PyQt5.QtWidgets import (QHBoxLayout, QLabel, QFrame, QVBoxLayout, QSpacerItem, QSizePolicy, QStackedWidget, - QGridLayout, QSplitter) -from PyQt5.QtGui import QPixmap, QFont, QPainter, QColor, QPalette + QGridLayout, QSplitter, QApplication) +from PyQt5.QtGui import QPixmap, QFont, QPainter, QColor, QPalette, QImage from qfluentwidgets import (SmoothScrollArea, TransparentTogglePushButton, ToolTipFilter, ToolTipPosition) @@ -21,14 +23,18 @@ class GameInfoInterface(SmoothScrollArea): enemySummonerInfoReady = pyqtSignal(dict) summonerViewClicked = pyqtSignal(str) summonerGamesClicked = pyqtSignal(str) + pageSwitchSignal = pyqtSignal() gameEnd = pyqtSignal() def __init__(self, parent=None): super().__init__(parent) + self.pageState = 1 + self.hBoxLayout = QHBoxLayout(self) self.summonersView = SummonersView() self.summonersGamesView = QStackedWidget() + # TODO 动画 行为 self.allySummonerGamesView = SummonersGamesView() self.enemySummonerGamesView = SummonersGamesView() @@ -186,6 +192,7 @@ class TeamSummoners(QFrame): def __init__(self, parent=None): super().__init__(parent) + self.items: Dict[str, SummonerInfoView] = {} self.vBoxLayout = QVBoxLayout(self) self.__initLayout() @@ -199,6 +206,7 @@ def updateSummoners(self, summoners): for summoner in summoners: summonerView = SummonerInfoView(summoner) + self.items[summoner["summonerId"]] = summonerView # 用 summonerId 避免空字符串 self.vBoxLayout.addWidget(summonerView, stretch=1) if len(summoners) < 5: @@ -396,6 +404,20 @@ def __setColor(self, teamId): background-color: rgba({r1}, {g1}, {b1}, 0.2); }}""") + def mousePressEvent(self, event): + if event.button() == Qt.LeftButton: + (self.parent().parent().parent().parent().parent().parent() + .parent().gameInfoInterface.pageSwitchSignal.emit()) + + def enterEvent(self, event): + QApplication.setOverrideCursor(Qt.PointingHandCursor) + + def leaveEvent(self, event): + QApplication.restoreOverrideCursor() + + def updateIcon(self, iconPath: str): + self.icon.updateIcon(iconPath) + class SummonersGamesView(QFrame): diff --git a/app/view/main_window.py b/app/view/main_window.py index 6978d165..08c966a4 100644 --- a/app/view/main_window.py +++ b/app/view/main_window.py @@ -1,10 +1,11 @@ +import json import os import sys import traceback import time from collections import Counter -from PyQt5.QtCore import Qt, pyqtSignal, QSize +from PyQt5.QtCore import Qt, pyqtSignal, QSize, QAbstractAnimation from PyQt5.QtGui import QIcon, QImage, QCursor from PyQt5.QtWidgets import QApplication, QSystemTrayIcon from qfluentwidgets import (NavigationItemPosition, InfoBar, InfoBarPosition, Action, @@ -126,6 +127,10 @@ def __conncetSignalToSlot(self): self.eventListener.gameStatusChanged.connect( self.__onGameStatusChanged) + self.eventListener.champSelectChanged.connect( + self.__onChampSelectChanged + ) + self.nameOrIconChanged.connect(self.__onNameOrIconChanged) self.lolInstallFolderChanged.connect(self.__onLolInstallFolderChanged) @@ -147,6 +152,8 @@ def __conncetSignalToSlot(self): self.__onSearchInterfaceSummonerNameClicked) self.gameInfoInterface.summonerGamesClicked.connect( self.__onGameInfoInterfaceGamesSummonerNameClicked) + self.gameInfoInterface.pageSwitchSignal.connect( + self.__onGameInfoPageSwitch) self.settingInterface.careerGamesCount.pushButton.clicked.connect( self.__onCareerInterfaceRefreshButtonClicked) self.settingInterface.micaCard.checkedChanged.connect( @@ -493,6 +500,14 @@ def __onGameInfoInterfaceGamesSummonerNameClicked(self, name): self.checkAndSwitchTo(self.searchInterface) + def __onGameInfoPageSwitch(self): + if self.gameInfoInterface.pageState == 1: + # TODO 动画 行为 + self.gameInfoInterface.pageState = 2 + else: + # TODO 动画 行为 + self.gameInfoInterface.pageState = 1 + def __onSearchInterfaceCareerButtonClicked(self): self.careerInterface.showLoadingPage.emit() name = self.searchInterface.currentSummonerName @@ -687,6 +702,16 @@ def _(): if switch: self.checkAndSwitchTo(self.careerInterface) + def __onChampSelectChanged(self, data): + for t in data["myTeam"]: + if t['championId']: + championIconPath = connector.getChampionIcon(t['championId']) + + # 控件可能未绘制, 判断一下避免报错 + summonersView = self.gameInfoInterface.summonersView.allySummoners.items.get(t["summonerId"]) + if summonersView: + summonersView.updateIcon(championIconPath) + def __onGameStatusChanged(self, status): title = None isGaming = False @@ -870,15 +895,22 @@ def _(): def process_item(item): # 跟 __onChampionSelectBegin 函数里面的处理方法一样,这里使用 puuid - puuid = item["puuid"] + puuid = item.get("puuid") + + # AI是没有该字段的, 避免报错 + if not puuid: + return None if puuid == '00000000-0000-0000-0000-000000000000': return None summoner = connector.getSummonerByPuuid(puuid) - iconId = summoner["profileIconId"] - icon = connector.getProfileIcon(iconId) + # iconId = summoner["profileIconId"] + # icon = connector.getProfileIcon(iconId) + + iconId = item["championId"] + icon = connector.getChampionIcon(iconId) origRankInfo = connector.getRankedStatsByPuuid(puuid) rankInfo = processRankInfo(origRankInfo) From e86545a2ff2849510bff65e9a6e8622a528e54d7 Mon Sep 17 00:00:00 2001 From: Hpero4 Date: Sat, 16 Sep 2023 20:01:39 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E6=96=B0=E5=A2=9Efixme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/view/main_window.py | 1 + 1 file changed, 1 insertion(+) diff --git a/app/view/main_window.py b/app/view/main_window.py index 08c966a4..78d32ea2 100644 --- a/app/view/main_window.py +++ b/app/view/main_window.py @@ -703,6 +703,7 @@ def _(): self.checkAndSwitchTo(self.careerInterface) def __onChampSelectChanged(self, data): + # FIXME 可能存在调用频繁影响性能, 可以通过判断当前IconId来避免重复更新 for t in data["myTeam"]: if t['championId']: championIconPath = connector.getChampionIcon(t['championId'])