You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

133 lines
3.6 KiB

# coding:utf-8
from typing import Dict, List
from itertools import groupby
from PySide6.QtCore import Qt, QObject, Signal
from PySide6.QtWidgets import QWidget, QStackedWidget
class RouteItem:
""" Route item """
def __init__(self, stacked: QStackedWidget, routeKey: str):
self.stacked = stacked
self.routeKey = routeKey
def __eq__(self, other):
if other is None:
return False
return other.stacked is self.stacked and self.routeKey == other.routeKey
class StackedHistory:
""" Stacked history """
def __init__(self, stacked: QStackedWidget):
self.stacked = stacked
self.defaultRouteKey = None # type: str
self.history = [self.defaultRouteKey] # type: List[str]
def __len__(self):
return len(self.history)
def isEmpty(self):
return len(self) <= 1
def push(self, routeKey: str):
if self.history[-1] == routeKey:
return False
self.history.append(routeKey)
return True
def pop(self):
if self.isEmpty():
return
self.history.pop()
self.goToTop()
def remove(self, routeKey: str):
if routeKey not in self.history:
return
self.history[1:] = [i for i in self.history[1:] if i != routeKey]
self.history = [k for k, g in groupby(self.history)]
self.goToTop()
def top(self):
return self.history[-1]
def setDefaultRouteKey(self, routeKey: str):
self.defaultRouteKey = routeKey
self.history[0] = routeKey
def goToTop(self):
w = self.stacked.findChild(QWidget, self.top())
if w:
self.stacked.setCurrentWidget(w)
class Router(QObject):
""" Router """
emptyChanged = Signal(bool)
def __init__(self, parent=None):
super().__init__(parent=parent)
self.history = [] # type: List[RouteItem]
self.stackHistories = {} # type: Dict[QStackedWidget, StackedHistory]
def setDefaultRouteKey(self, stacked: QStackedWidget, routeKey: str):
""" set the default route key of stacked widget """
if stacked not in self.stackHistories:
self.stackHistories[stacked] = StackedHistory(stacked)
self.stackHistories[stacked].setDefaultRouteKey(routeKey)
def push(self, stacked: QStackedWidget, routeKey: str):
""" push history
Parameters
----------
stacked: QStackedWidget
stacked widget
routeKey: str
route key of sub insterface, it should be the object name of sub interface
"""
item = RouteItem(stacked, routeKey)
if stacked not in self.stackHistories:
self.stackHistories[stacked] = StackedHistory(stacked)
# don't add duplicated history
success = self.stackHistories[stacked].push(routeKey)
if success:
self.history.append(item)
self.emptyChanged.emit(not bool(self.history))
def pop(self):
""" pop history """
if not self.history:
return
item = self.history.pop()
self.emptyChanged.emit(not bool(self.history))
self.stackHistories[item.stacked].pop()
def remove(self, routeKey: str):
""" remove history """
self.history = [i for i in self.history if i.routeKey != routeKey]
self.history = [list(g)[0] for k, g in groupby(self.history, lambda i: i.routeKey)]
self.emptyChanged.emit(not bool(self.history))
for stacked, history in self.stackHistories.items():
w = stacked.findChild(QWidget, routeKey)
if w:
return history.remove(routeKey)
qrouter = Router()