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
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() |