Skip to main content

A lightweight routing system for GUI applications (PyQt, Tkinter, etc.)

Project description

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 the abstract 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: The tk.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 inside main_frame. Calls tkraise() and passes params if 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: The QWidget-based class to be shown

  • route_name: Optional unique name for named navigation

Methods:

  • display(main_frame: QMainWindow, **params)
    Shows the associated screen inside main_frame. Calls setCentralWidget and passes params if 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.


Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ez_route-0.1.1.tar.gz (10.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ez_route-0.1.1-py3-none-any.whl (11.4 kB view details)

Uploaded Python 3

File details

Details for the file ez_route-0.1.1.tar.gz.

File metadata

  • Download URL: ez_route-0.1.1.tar.gz
  • Upload date:
  • Size: 10.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for ez_route-0.1.1.tar.gz
Algorithm Hash digest
SHA256 6e17c951ddbaf0e77dda7f15ff1b42429b8b6a992fce9825c1322254914840c8
MD5 d6bd52d3dd04b1a255509b53e9304189
BLAKE2b-256 c461aa27b943aed81b529d9f14a7eb24ab228e8f60c2c2fee20e4ba5cea0bf96

See more details on using hashes here.

File details

Details for the file ez_route-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: ez_route-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 11.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for ez_route-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 3a1e1bdfe7fcd2432720a75601de4fd22c05e2d3a0d822ad5559d275e948e624
MD5 8b74df19ed84bf3b4e858691cf0145ca
BLAKE2b-256 42224c3b09948a840a89b57c8fe4089c8cd6ee8a918430e032146ad7515d9775

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page