Ez_Route ðŸ§
Lightweight routing system for Python GUI applications (Tkinter & PyQt6)
Ez_Route is a minimal routing library for GUI frameworks like Tkinter and PyQt6, offering path-based and named route navigation, nested routing, and parameter passing. Inspired by SPA routing frameworks, it brings a structured way to manage screen transitions in Python desktop apps.
✨ Features
- ✅ Simple route declaration and registration
- ✅ Named routes with path matching
- ✅ Dynamic segments (e.g.,
/user/:id) - ✅ Nested routes and history support
- ✅ GUI-agnostic: works with both Tkinter and PyQt6
- ✅ Customizable and extensible architecture
Get Started
Install
pip install ez-route
Example:
PyQt Usage
import sys
from PySide6.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QPushButton, QLabel, QWidget
from ez_route import Router, QtRoute, ServiceLocator
class AboutScreen(QWidget):
def __init__(self,):
super().__init__()
self.router = ServiceLocator.get("router")
self.setup_ui()
def setup_ui(self):
layout = QVBoxLayout()
title = QLabel("About Screen")
title.setStyleSheet("font-size: 24px;")
about_button = QPushButton("Go to Home Page")
about_button.clicked.connect(self.go_to_home)
layout.addWidget(title)
layout.addWidget(about_button)
self.setLayout(layout)
def go_to_home(self):
self.router.go_by_path('/home')
class HomeScreen(QWidget):
def __init__(self,):
super().__init__()
self.router = ServiceLocator.get("router")
self.setup_ui()
def setup_ui(self):
layout = QVBoxLayout()
title = QLabel("Home Screen")
title.setStyleSheet("font-size: 24px;")
about_button = QPushButton("Go to About Page")
about_button.clicked.connect(self.go_to_about)
layout.addWidget(title)
layout.addWidget(about_button)
self.setLayout(layout)
def go_to_about(self):
self.router.go_by_path('/about')
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
root = QtRoute(path='/', screen=self)
home = QtRoute(path='/home', screen=HomeScreen)
about = QtRoute(path='/about', screen=AboutScreen)
self.router = Router(self)
self.router.install_route(root)
self.router.install_route(home)
self.router.install_route(about)
ServiceLocator.provide("router", self.router)
self.router.go_by_path('/home')
if __name__ == "__main__":
app = QApplication([])
window = MainWindow()
window.show()
sys.exit(app.exec())
Tkinter Usage
import tkinter as tk
from ez_route import Router, TkRoute, ServiceLocator
class ProfileDetailPage(tk.Frame):
def __init__(self, main_frame):
super().__init__(main_frame)
self.router = ServiceLocator.get("router")
self.label = tk.Label(self, text="Profile Page", font=("Arial", 16))
self.label.pack(pady=10)
btn = tk.Button(self, text="Go to Home Page",
command= lambda: self.router.go_by_path("/home"))
btn.pack(pady=10)
def with_param(self, **params):
self.label = tk.Label(self, text=f"Profile Page - Params {params.get('id')}", font=("Arial", 16))
self.label.pack(pady=10)
class ProfilePage(tk.Frame):
def __init__(self, main_frame):
super().__init__(main_frame)
self.router = ServiceLocator.get("router")
self.label = tk.Label(self, text="Profile Page", font=("Arial", 16))
self.label.pack(pady=10)
btn = tk.Button(self, text="Go to Detial Page with Params",command= lambda: self.router.go_by_path("/profile/2893"))
btn.pack(pady=10)
class HomePage(tk.Frame):
def __init__(self, main_frame):
super().__init__(main_frame)
self.router = ServiceLocator.get("router")
self.label = tk.Label(self, text="Home Page", font=("Arial", 16))
self.label.pack(pady=10)
btn = tk.Button(self, text="Go to Profile Page",command= lambda: self.router.go_by_path("/profile"))
btn.pack(pady=10)
class App(tk.Tk):
def __init__(self):
super().__init__()
self.title("Tkinter Nested Pages with Parameters")
self.geometry("500x300")
container = tk.Frame(self)
container.pack(fill="both", expand=True)
self.router = Router(container)
ServiceLocator.provide("router", self.router)
home = TkRoute(path='/home', screen=HomePage)
profile = TkRoute(path='/profile', screen=ProfilePage)
profile_detail = TkRoute(path='/:id', screen=ProfileDetailPage, route_name="profile-detail")
profile.add_child_route(profile_detail)
self.router.install_route(home)
self.router.install_route(profile)
self.router.go_by_path("/home")
if __name__ == "__main__":
app = App()
app.mainloop()
🧩 Core Components
Router
Main entry point to register and navigate routes.
Router(main_frame: tk.Frame | QWidget)
Methods:
-
install_route(route: Route)
Register a new route and its children. -
go_by_name(name: str, params: dict = {})
Navigate to a route by its name and pass optional parameters. -
go_by_path(path: str)
Navigate to a route by its path.
🧠Route (Base Class)
Base class to define a route node.
Route(path: str, screen: Callable, route_name: Optional[str] = None)
Attributes:
-
path: str: Route path (can be dynamic like/:id) -
screen: Callable: A factory or class used to render the screen -
route_name: Optional[str]: Name of the route for name-based navigation -
children: List[Route]: Nested child routes
Methods:
add_child_route(child: Route)– Nest a child route under this route.add_children_routes(children: List[Route])– Nest a list of children routes under this route.display(main_frame: tk.Frame | QWidget, **params)– This method is theabstract method
🧠TkRoute
A Route implementation for tkinter apps using tk.Frame.
TkRoute(path: str, screen: type[tk.Frame], route_name: str = None)
Attributes:
-
path: URL-style route path ("/home","/settings", etc.) -
screen: Thetk.Frame-based class to be shown -
route_name: Optional unique name for named navigation
Methods:
display(main_frame: tk.Frame, **params)
Shows the associated screen insidemain_frame. Callstkraise()and passesparamsif supported.
🧠QtRoute
A Route implementation for tkinter apps using QWidget.
QtRoute(path: str, screen: type[QWidget], route_name: str = None)
Attributes:
-
path: URL-style route path ("/home","/settings", etc.) -
screen: TheQWidget-based class to be shown -
route_name: Optional unique name for named navigation
Methods:
display(main_frame: QMainWindow, **params)
Shows the associated screen insidemain_frame. CallssetCentralWidgetand passesparamsif supported.
🧰 Service Locator
ServiceLocator
A global object registry for dependency injection (e.g., Router access from pages).
Methods:
provide(name: str, instance: Any)
get(name: str) -> Any
Used for accessing shared services like the router across screens.
Metadata
Release files for ez-route 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| ez_route-0.1.1.tar.gz | 10.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ez_route-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 22.2 kB
Release files / ez_route-0.1.1.tar.gz
| Download URL | ez_route-0.1.1.tar.gz |
|---|---|
| Size | 10.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6e17c951ddbaf0e77dda7f15ff1b42429b8b6a992fce9825c1322254914840c8
|
|
BLAKE2b-256 checksum How to use checksums |
c461aa27b943aed81b529d9f14a7eb24ab228e8f60c2c2fee20e4ba5cea0bf96
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.3
|
Release files / ez_route-0.1.1-py3-none-any.whl
| Download URL | ez_route-0.1.1-py3-none-any.whl |
|---|---|
| Size | 11.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3a1e1bdfe7fcd2432720a75601de4fd22c05e2d3a0d822ad5559d275e948e624
|
|
BLAKE2b-256 checksum How to use checksums |
42224c3b09948a840a89b57c8fe4089c8cd6ee8a918430e032146ad7515d9775
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.3
|