easypyui 2.4.0__tar.gz → 3.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: easypyui
3
- Version: 2.4.0
3
+ Version: 3.0.0
4
4
  Summary: A simple and modern Python GUI library built on tkinter and ttk
5
5
  Author: EasyPyUI
6
6
  License: MIT
@@ -123,7 +123,7 @@ MIT License
123
123
 
124
124
  ## Version
125
125
 
126
- Current release: **2.4.0**
126
+ Current release: **3.0.0**
127
127
 
128
128
  2.2.1 is a PyPI metadata and documentation update for the 2.2 series.
129
129
 
@@ -197,3 +197,50 @@ table.set_rows([
197
197
  ("Daniel", 95),
198
198
  ])
199
199
  ```
200
+
201
+
202
+ # EasyPyUI 3.0
203
+
204
+ EasyPyUI 3.0 moves beyond a tkinter helper toward a small application framework.
205
+
206
+ ## Reactive UI
207
+
208
+ ```python
209
+ name = state("Noah")
210
+ upper = computed(lambda: name.get().upper(), name)
211
+
212
+ field = minput("Name")
213
+ bind(field, name)
214
+ text_widget = text("")
215
+ upper.bind_text(text_widget)
216
+ ```
217
+
218
+ ## AppShell
219
+
220
+ ```python
221
+ ui = shell("My App")
222
+
223
+ ui.page("home", "Home", lambda parent: __import__("tkinter").Label(parent, text="Home").pack())
224
+ ui.page("settings", "Settings", lambda parent: __import__("tkinter").Label(parent, text="Settings").pack())
225
+ ui.start("home")
226
+ ```
227
+
228
+ ## Design Tokens
229
+
230
+ ```python
231
+ design(radius=12, spacing=10, font="Segoe UI", title_size=24)
232
+ ```
233
+
234
+ ## CLI
235
+
236
+ ```bash
237
+ easypyui new my_app
238
+ cd my_app
239
+ python app.py
240
+ ```
241
+
242
+ ## Included from 2.x
243
+
244
+ Modern widgets, animations, routing, background tasks, forms and validators,
245
+ state management, shortcuts, debounce/throttle, DataTable, Modal, Drawer,
246
+ Accordion, DatePicker and NotificationCenter remain available.
@@ -1,199 +1,226 @@
1
- Metadata-Version: 2.4
2
- Name: easypyui
3
- Version: 2.4.0
4
- Summary: A simple and modern Python GUI library built on tkinter and ttk
5
- Author: EasyPyUI
6
- License: MIT
7
- Project-URL: Homepage, https://pypi.org/project/easypyui/
8
- Keywords: gui,tkinter,ttk,desktop,ui,python-gui
9
- Classifier: Development Status :: 4 - Beta
10
- Classifier: Intended Audience :: Developers
11
- Classifier: License :: OSI Approved :: MIT License
12
- Classifier: Operating System :: OS Independent
13
- Classifier: Programming Language :: Python :: 3
14
- Classifier: Programming Language :: Python :: 3 :: Only
15
- Classifier: Topic :: Software Development :: User Interfaces
16
- Requires-Python: >=3.9
17
- Description-Content-Type: text/markdown
18
- License-File: LICENSE
19
- Dynamic: license-file
20
-
21
- # EasyPyUI
22
-
23
- **Build modern Python desktop GUIs with much less code than raw tkinter.**
24
-
25
- EasyPyUI is a lightweight GUI library built on Python's standard `tkinter` and `ttk`.
26
- It provides a short beginner-friendly API while keeping access to native Tk widgets.
27
-
28
- ## Installation
29
-
30
- ```bash
31
- pip install easypyui
32
- ```
33
-
34
- ## Quick Start
35
-
36
- ```python
37
- from easypyui import *
38
-
39
- app("Hello EasyPyUI", 500, 400, appearance="dark")
40
- title("Hello!")
41
-
42
- name = minput("Name", placeholder="Your name")
43
- mbutton("Say hello", lambda: notify("Hello " + name.get()))
44
-
45
- fade_in(400)
46
- run()
47
- ```
48
-
49
- ## Modern UI
50
-
51
- EasyPyUI 2.x includes `mbutton()`, `minput()`, `mswitch()`, `mcard()`,
52
- Light/Dark appearance and custom accent colors.
53
-
54
- ```python
55
- app("Dashboard", 700, 500, appearance="dark", accent="#8b5cf6")
56
- ```
57
-
58
- ## Animation
59
-
60
- ```python
61
- ring = progress_ring(20, size=110)
62
- mbutton("Start", lambda: ring.animate_to(100, 1000))
63
- fade_in(500)
64
- ```
65
-
66
- Easing modes: `linear`, `ease_in`, `ease_out`, `ease_in_out`.
67
-
68
- ## Pages / Router
69
-
70
- ```python
71
- from easypyui import *
72
-
73
- app("Pages", 500, 350)
74
-
75
- def home(ui):
76
- title("Home")
77
- on("Settings", lambda: go("settings"))
78
-
79
- def settings(ui):
80
- title("Settings")
81
- on("Back", lambda: go("home"))
82
-
83
- route("home", home)
84
- route("settings", settings)
85
- go("home")
86
- run()
87
- ```
88
-
89
- ## Background Tasks
90
-
91
- ```python
92
- def work():
93
- import time
94
- time.sleep(2)
95
- return "Done!"
96
-
97
- run_task(work, done=lambda result: notify(result), loading_text="Working...")
98
- ```
99
-
100
- ## Native tkinter access
101
-
102
- Most EasyPyUI wrapper objects expose `.tk`:
103
-
104
- ```python
105
- btn = mbutton("Test", lambda: print("clicked"))
106
- btn.tk.bind("<Button-2>", lambda event: print("middle click"))
107
- ```
108
-
109
- ## Classic API
110
-
111
- The older API remains available, including `window()`, `text()`, `inputbox()`,
112
- `button()`, `table()`, `canvas()` and `start()`.
113
-
114
- ## Requirements
115
-
116
- - Python 3.9+
117
- - tkinter support in your Python installation
118
- - No mandatory third-party runtime GUI dependency
119
-
120
- ## License
121
-
122
- MIT License
123
-
124
- ## Version
125
-
126
- Current release: **2.4.0**
127
-
128
- 2.2.1 is a PyPI metadata and documentation update for the 2.2 series.
129
-
130
-
131
- ## 2.3 Productivity APIs
132
-
133
- ### Form validation
134
-
135
- ```python
136
- f = form()
137
-
138
- email = f.add(
139
- "Email",
140
- minput("Email"),
141
- [Validator.required(), Validator.email()]
142
- )
143
-
144
- password_box = f.add(
145
- "Password",
146
- minput("Password", password=True),
147
- [Validator.required(), Validator.min_length(8)]
148
- )
149
-
150
- def submit():
151
- ok, errors = f.validate()
152
- if ok:
153
- notify(str(f.values()))
154
-
155
- mbutton("Submit", submit)
156
- ```
157
-
158
- ### Reactive State
159
-
160
- ```python
161
- count = state(0)
162
-
163
- label_widget = text("0")
164
- count.bind_text(label_widget)
165
-
166
- mbutton("+1", lambda: count.update(lambda n: n + 1))
167
- ```
168
-
169
- ### Keyboard shortcuts
170
-
171
- ```python
172
- shortcut("ctrl+s", save)
173
- shortcut("ctrl+q", close)
174
- ```
175
-
176
- ### Debounce / Throttle
177
-
178
- ```python
179
- search = debounce(300, do_search)
180
- resize_handler = throttle(100, update_layout)
181
- ```
182
-
183
-
184
- ## 2.4 Large Application Widgets
185
-
186
- - `datatable()` — search, sorting and pagination
187
- - `modal()` — modal window
188
- - `drawer()` — collapsible side drawer
189
- - `accordion()` — expandable sections
190
- - `datepicker()` — date value input
191
- - `notifications()` — notification center
192
-
193
- ```python
194
- table = datatable(["name", "score"], ["Name", "Score"], page_size=5)
195
- table.set_rows([
196
- ("Noah", 100),
197
- ("Daniel", 95),
198
- ])
199
- ```
1
+ # EasyPyUI
2
+
3
+ **Build modern Python desktop GUIs with much less code than raw tkinter.**
4
+
5
+ EasyPyUI is a lightweight GUI library built on Python's standard `tkinter` and `ttk`.
6
+ It provides a short beginner-friendly API while keeping access to native Tk widgets.
7
+
8
+ ## Installation
9
+
10
+ ```bash
11
+ pip install easypyui
12
+ ```
13
+
14
+ ## Quick Start
15
+
16
+ ```python
17
+ from easypyui import *
18
+
19
+ app("Hello EasyPyUI", 500, 400, appearance="dark")
20
+ title("Hello!")
21
+
22
+ name = minput("Name", placeholder="Your name")
23
+ mbutton("Say hello", lambda: notify("Hello " + name.get()))
24
+
25
+ fade_in(400)
26
+ run()
27
+ ```
28
+
29
+ ## Modern UI
30
+
31
+ EasyPyUI 2.x includes `mbutton()`, `minput()`, `mswitch()`, `mcard()`,
32
+ Light/Dark appearance and custom accent colors.
33
+
34
+ ```python
35
+ app("Dashboard", 700, 500, appearance="dark", accent="#8b5cf6")
36
+ ```
37
+
38
+ ## Animation
39
+
40
+ ```python
41
+ ring = progress_ring(20, size=110)
42
+ mbutton("Start", lambda: ring.animate_to(100, 1000))
43
+ fade_in(500)
44
+ ```
45
+
46
+ Easing modes: `linear`, `ease_in`, `ease_out`, `ease_in_out`.
47
+
48
+ ## Pages / Router
49
+
50
+ ```python
51
+ from easypyui import *
52
+
53
+ app("Pages", 500, 350)
54
+
55
+ def home(ui):
56
+ title("Home")
57
+ on("Settings", lambda: go("settings"))
58
+
59
+ def settings(ui):
60
+ title("Settings")
61
+ on("Back", lambda: go("home"))
62
+
63
+ route("home", home)
64
+ route("settings", settings)
65
+ go("home")
66
+ run()
67
+ ```
68
+
69
+ ## Background Tasks
70
+
71
+ ```python
72
+ def work():
73
+ import time
74
+ time.sleep(2)
75
+ return "Done!"
76
+
77
+ run_task(work, done=lambda result: notify(result), loading_text="Working...")
78
+ ```
79
+
80
+ ## Native tkinter access
81
+
82
+ Most EasyPyUI wrapper objects expose `.tk`:
83
+
84
+ ```python
85
+ btn = mbutton("Test", lambda: print("clicked"))
86
+ btn.tk.bind("<Button-2>", lambda event: print("middle click"))
87
+ ```
88
+
89
+ ## Classic API
90
+
91
+ The older API remains available, including `window()`, `text()`, `inputbox()`,
92
+ `button()`, `table()`, `canvas()` and `start()`.
93
+
94
+ ## Requirements
95
+
96
+ - Python 3.9+
97
+ - tkinter support in your Python installation
98
+ - No mandatory third-party runtime GUI dependency
99
+
100
+ ## License
101
+
102
+ MIT License
103
+
104
+ ## Version
105
+
106
+ Current release: **3.0.0**
107
+
108
+ 2.2.1 is a PyPI metadata and documentation update for the 2.2 series.
109
+
110
+
111
+ ## 2.3 Productivity APIs
112
+
113
+ ### Form validation
114
+
115
+ ```python
116
+ f = form()
117
+
118
+ email = f.add(
119
+ "Email",
120
+ minput("Email"),
121
+ [Validator.required(), Validator.email()]
122
+ )
123
+
124
+ password_box = f.add(
125
+ "Password",
126
+ minput("Password", password=True),
127
+ [Validator.required(), Validator.min_length(8)]
128
+ )
129
+
130
+ def submit():
131
+ ok, errors = f.validate()
132
+ if ok:
133
+ notify(str(f.values()))
134
+
135
+ mbutton("Submit", submit)
136
+ ```
137
+
138
+ ### Reactive State
139
+
140
+ ```python
141
+ count = state(0)
142
+
143
+ label_widget = text("0")
144
+ count.bind_text(label_widget)
145
+
146
+ mbutton("+1", lambda: count.update(lambda n: n + 1))
147
+ ```
148
+
149
+ ### Keyboard shortcuts
150
+
151
+ ```python
152
+ shortcut("ctrl+s", save)
153
+ shortcut("ctrl+q", close)
154
+ ```
155
+
156
+ ### Debounce / Throttle
157
+
158
+ ```python
159
+ search = debounce(300, do_search)
160
+ resize_handler = throttle(100, update_layout)
161
+ ```
162
+
163
+
164
+ ## 2.4 Large Application Widgets
165
+
166
+ - `datatable()` — search, sorting and pagination
167
+ - `modal()` — modal window
168
+ - `drawer()` — collapsible side drawer
169
+ - `accordion()` — expandable sections
170
+ - `datepicker()` — date value input
171
+ - `notifications()` — notification center
172
+
173
+ ```python
174
+ table = datatable(["name", "score"], ["Name", "Score"], page_size=5)
175
+ table.set_rows([
176
+ ("Noah", 100),
177
+ ("Daniel", 95),
178
+ ])
179
+ ```
180
+
181
+
182
+ # EasyPyUI 3.0
183
+
184
+ EasyPyUI 3.0 moves beyond a tkinter helper toward a small application framework.
185
+
186
+ ## Reactive UI
187
+
188
+ ```python
189
+ name = state("Noah")
190
+ upper = computed(lambda: name.get().upper(), name)
191
+
192
+ field = minput("Name")
193
+ bind(field, name)
194
+ text_widget = text("")
195
+ upper.bind_text(text_widget)
196
+ ```
197
+
198
+ ## AppShell
199
+
200
+ ```python
201
+ ui = shell("My App")
202
+
203
+ ui.page("home", "Home", lambda parent: __import__("tkinter").Label(parent, text="Home").pack())
204
+ ui.page("settings", "Settings", lambda parent: __import__("tkinter").Label(parent, text="Settings").pack())
205
+ ui.start("home")
206
+ ```
207
+
208
+ ## Design Tokens
209
+
210
+ ```python
211
+ design(radius=12, spacing=10, font="Segoe UI", title_size=24)
212
+ ```
213
+
214
+ ## CLI
215
+
216
+ ```bash
217
+ easypyui new my_app
218
+ cd my_app
219
+ python app.py
220
+ ```
221
+
222
+ ## Included from 2.x
223
+
224
+ Modern widgets, animations, routing, background tasks, forms and validators,
225
+ state management, shortcuts, debounce/throttle, DataTable, Modal, Drawer,
226
+ Accordion, DatePicker and NotificationCenter remain available.
@@ -1,6 +1,6 @@
1
1
  from .core import App, Value, Widget, Table, Canvas, Container, Row
2
2
 
3
- __version__ = "2.4.0"
3
+ __version__ = "3.0.0"
4
4
 
5
5
  _current = None
6
6
 
@@ -119,3 +119,9 @@ def accordion(*a, **k): return _app().accordion(*a, **k)
119
119
  def datatable(*a, **k): return _app().datatable(*a, **k)
120
120
  def datepicker(*a, **k): return _app().datepicker(*a, **k)
121
121
  def notifications(): return _app().notifications()
122
+
123
+ from .reactive import ComputedState, computed, bind
124
+ from .shell import AppShell
125
+ from .theme3 import ThemeConfig, DEFAULT_TOKENS
126
+ def shell(*a, **k): return _app().shell(*a, **k)
127
+ def design(**tokens): return _app().design(**tokens)
@@ -0,0 +1,2 @@
1
+ from .cli import main
2
+ raise SystemExit(main())
@@ -0,0 +1,27 @@
1
+ import argparse
2
+ from pathlib import Path
3
+
4
+ TEMPLATE = """from easypyui import *
5
+
6
+ app("{title}", 720, 480, appearance="dark")
7
+ title("{title}")
8
+ label("Created with EasyPyUI 3.0")
9
+ mbutton("Hello", lambda: notify("Hello EasyPyUI!"))
10
+ run()
11
+ """
12
+
13
+ def main(argv=None):
14
+ parser=argparse.ArgumentParser(prog="easypyui",description="EasyPyUI project tools")
15
+ sub=parser.add_subparsers(dest="command")
16
+ new=sub.add_parser("new",help="Create a new EasyPyUI project")
17
+ new.add_argument("name"); new.add_argument("--title",default=None)
18
+ args=parser.parse_args(argv)
19
+ if args.command=="new":
20
+ root=Path(args.name); root.mkdir(parents=True,exist_ok=True)
21
+ (root/"app.py").write_text(TEMPLATE.format(title=args.title or args.name),encoding="utf-8")
22
+ (root/"README.md").write_text(f"# {args.name}\\n\\nRun with `python app.py`.\\n",encoding="utf-8")
23
+ print(f"Created {root.resolve()}")
24
+ return 0
25
+ parser.print_help(); return 0
26
+
27
+ if __name__=="__main__": raise SystemExit(main())
@@ -1196,3 +1196,8 @@ install_productivity_api(App, _Builder)
1196
1196
 
1197
1197
  from .largeapp import install_largeapp_api
1198
1198
  install_largeapp_api(App, _Builder)
1199
+
1200
+ from .shell import install_shell_api
1201
+ install_shell_api(App, _Builder)
1202
+ from .theme3 import install_theme3_api
1203
+ install_theme3_api(App, _Builder)
@@ -0,0 +1,43 @@
1
+ class ComputedState:
2
+ def __init__(self, func, *deps):
3
+ self.func=func; self._listeners=[]
4
+ self._value=func()
5
+ for dep in deps:
6
+ dep.watch(lambda _v, self=self: self._refresh())
7
+ def _refresh(self):
8
+ new=self.func()
9
+ if new != self._value:
10
+ self._value=new
11
+ for cb in list(self._listeners): cb(new)
12
+ def get(self): return self._value
13
+ def watch(self, callback, immediate=False):
14
+ self._listeners.append(callback)
15
+ if immediate: callback(self._value)
16
+ return lambda: self.unwatch(callback)
17
+ def unwatch(self, callback):
18
+ if callback in self._listeners: self._listeners.remove(callback)
19
+ def bind_text(self, widget):
20
+ def apply(v):
21
+ try: widget.set(v)
22
+ except Exception:
23
+ try: widget.config(text=str(v))
24
+ except Exception: pass
25
+ self.watch(apply, True); return self
26
+
27
+ def computed(func, *deps): return ComputedState(func, *deps)
28
+
29
+ def bind(widget, state, event="<KeyRelease>"):
30
+ try: widget.set(state.get())
31
+ except Exception: pass
32
+ def from_state(v):
33
+ try:
34
+ if widget.get() != v: widget.set(v)
35
+ except Exception: pass
36
+ state.watch(from_state)
37
+ tkobj=getattr(widget,"tk",widget)
38
+ def from_widget(_event=None):
39
+ try: state.set(widget.get())
40
+ except Exception: pass
41
+ try: tkobj.bind(event,from_widget,add="+")
42
+ except Exception: pass
43
+ return widget
@@ -0,0 +1,34 @@
1
+ import tkinter as tk
2
+ from tkinter import ttk
3
+
4
+ class AppShell:
5
+ def __init__(self, app, title="EasyPyUI", sidebar_width=210):
6
+ self.app=app; self.pages={}; self.buttons={}; self.current=None
7
+ try: app.clear_body()
8
+ except Exception: pass
9
+ self.frame=ttk.Frame(app.body); self.frame.pack(fill="both",expand=True)
10
+ self.sidebar=tk.Frame(self.frame,width=sidebar_width)
11
+ self.sidebar.pack(side="left",fill="y"); self.sidebar.pack_propagate(False)
12
+ self.main=ttk.Frame(self.frame); self.main.pack(side="left",fill="both",expand=True)
13
+ tk.Label(self.sidebar,text=title,font=("",16,"bold"),anchor="w",padx=14,pady=14).pack(fill="x")
14
+ self.content=ttk.Frame(self.main,padding=16); self.content.pack(fill="both",expand=True)
15
+ self.tk=self.frame
16
+ def page(self,name,label=None,builder=None):
17
+ self.pages[name]=builder
18
+ b=tk.Button(self.sidebar,text=label or name,anchor="w",relief="flat",
19
+ command=lambda:self.go(name),padx=14,pady=8)
20
+ b.pack(fill="x"); self.buttons[name]=b; return self
21
+ def go(self,name):
22
+ if name not in self.pages: raise KeyError(name)
23
+ for child in self.content.winfo_children(): child.destroy()
24
+ self.current=name
25
+ builder=self.pages[name]
26
+ if builder: builder(self.content)
27
+ return self
28
+ def start(self,name=None):
29
+ target=name or (next(iter(self.pages)) if self.pages else None)
30
+ if target: self.go(target)
31
+ return self
32
+
33
+ def install_shell_api(App,Builder):
34
+ App.shell=lambda self,*a,**k: AppShell(self,*a,**k)
@@ -0,0 +1,15 @@
1
+ DEFAULT_TOKENS = {
2
+ "radius": 10, "spacing": 8, "font": "Segoe UI", "font_size": 10,
3
+ "title_size": 22, "control_height": 36
4
+ }
5
+ class ThemeConfig:
6
+ def __init__(self, **tokens):
7
+ self.tokens=dict(DEFAULT_TOKENS); self.tokens.update(tokens)
8
+ def get(self,key,default=None): return self.tokens.get(key,default)
9
+ def update(self,**tokens): self.tokens.update(tokens); return self
10
+
11
+ def install_theme3_api(App,Builder):
12
+ def design(self,**tokens):
13
+ if not hasattr(self,"_design_tokens"): self._design_tokens=ThemeConfig()
14
+ self._design_tokens.update(**tokens); return self._design_tokens
15
+ App.design=design
@@ -1,179 +1,246 @@
1
- # EasyPyUI
2
-
3
- **Build modern Python desktop GUIs with much less code than raw tkinter.**
4
-
5
- EasyPyUI is a lightweight GUI library built on Python's standard `tkinter` and `ttk`.
6
- It provides a short beginner-friendly API while keeping access to native Tk widgets.
7
-
8
- ## Installation
9
-
10
- ```bash
11
- pip install easypyui
12
- ```
13
-
14
- ## Quick Start
15
-
16
- ```python
17
- from easypyui import *
18
-
19
- app("Hello EasyPyUI", 500, 400, appearance="dark")
20
- title("Hello!")
21
-
22
- name = minput("Name", placeholder="Your name")
23
- mbutton("Say hello", lambda: notify("Hello " + name.get()))
24
-
25
- fade_in(400)
26
- run()
27
- ```
28
-
29
- ## Modern UI
30
-
31
- EasyPyUI 2.x includes `mbutton()`, `minput()`, `mswitch()`, `mcard()`,
32
- Light/Dark appearance and custom accent colors.
33
-
34
- ```python
35
- app("Dashboard", 700, 500, appearance="dark", accent="#8b5cf6")
36
- ```
37
-
38
- ## Animation
39
-
40
- ```python
41
- ring = progress_ring(20, size=110)
42
- mbutton("Start", lambda: ring.animate_to(100, 1000))
43
- fade_in(500)
44
- ```
45
-
46
- Easing modes: `linear`, `ease_in`, `ease_out`, `ease_in_out`.
47
-
48
- ## Pages / Router
49
-
50
- ```python
51
- from easypyui import *
52
-
53
- app("Pages", 500, 350)
54
-
55
- def home(ui):
56
- title("Home")
57
- on("Settings", lambda: go("settings"))
58
-
59
- def settings(ui):
60
- title("Settings")
61
- on("Back", lambda: go("home"))
62
-
63
- route("home", home)
64
- route("settings", settings)
65
- go("home")
66
- run()
67
- ```
68
-
69
- ## Background Tasks
70
-
71
- ```python
72
- def work():
73
- import time
74
- time.sleep(2)
75
- return "Done!"
76
-
77
- run_task(work, done=lambda result: notify(result), loading_text="Working...")
78
- ```
79
-
80
- ## Native tkinter access
81
-
82
- Most EasyPyUI wrapper objects expose `.tk`:
83
-
84
- ```python
85
- btn = mbutton("Test", lambda: print("clicked"))
86
- btn.tk.bind("<Button-2>", lambda event: print("middle click"))
87
- ```
88
-
89
- ## Classic API
90
-
91
- The older API remains available, including `window()`, `text()`, `inputbox()`,
92
- `button()`, `table()`, `canvas()` and `start()`.
93
-
94
- ## Requirements
95
-
96
- - Python 3.9+
97
- - tkinter support in your Python installation
98
- - No mandatory third-party runtime GUI dependency
99
-
100
- ## License
101
-
102
- MIT License
103
-
104
- ## Version
105
-
106
- Current release: **2.4.0**
107
-
108
- 2.2.1 is a PyPI metadata and documentation update for the 2.2 series.
109
-
110
-
111
- ## 2.3 Productivity APIs
112
-
113
- ### Form validation
114
-
115
- ```python
116
- f = form()
117
-
118
- email = f.add(
119
- "Email",
120
- minput("Email"),
121
- [Validator.required(), Validator.email()]
122
- )
123
-
124
- password_box = f.add(
125
- "Password",
126
- minput("Password", password=True),
127
- [Validator.required(), Validator.min_length(8)]
128
- )
129
-
130
- def submit():
131
- ok, errors = f.validate()
132
- if ok:
133
- notify(str(f.values()))
134
-
135
- mbutton("Submit", submit)
136
- ```
137
-
138
- ### Reactive State
139
-
140
- ```python
141
- count = state(0)
142
-
143
- label_widget = text("0")
144
- count.bind_text(label_widget)
145
-
146
- mbutton("+1", lambda: count.update(lambda n: n + 1))
147
- ```
148
-
149
- ### Keyboard shortcuts
150
-
151
- ```python
152
- shortcut("ctrl+s", save)
153
- shortcut("ctrl+q", close)
154
- ```
155
-
156
- ### Debounce / Throttle
157
-
158
- ```python
159
- search = debounce(300, do_search)
160
- resize_handler = throttle(100, update_layout)
161
- ```
162
-
163
-
164
- ## 2.4 Large Application Widgets
165
-
166
- - `datatable()` — search, sorting and pagination
167
- - `modal()` — modal window
168
- - `drawer()` — collapsible side drawer
169
- - `accordion()` — expandable sections
170
- - `datepicker()` — date value input
171
- - `notifications()` — notification center
172
-
173
- ```python
174
- table = datatable(["name", "score"], ["Name", "Score"], page_size=5)
175
- table.set_rows([
176
- ("Noah", 100),
177
- ("Daniel", 95),
178
- ])
179
- ```
1
+ Metadata-Version: 2.4
2
+ Name: easypyui
3
+ Version: 3.0.0
4
+ Summary: A simple and modern Python GUI library built on tkinter and ttk
5
+ Author: EasyPyUI
6
+ License: MIT
7
+ Project-URL: Homepage, https://pypi.org/project/easypyui/
8
+ Keywords: gui,tkinter,ttk,desktop,ui,python-gui
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Operating System :: OS Independent
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3 :: Only
15
+ Classifier: Topic :: Software Development :: User Interfaces
16
+ Requires-Python: >=3.9
17
+ Description-Content-Type: text/markdown
18
+ License-File: LICENSE
19
+ Dynamic: license-file
20
+
21
+ # EasyPyUI
22
+
23
+ **Build modern Python desktop GUIs with much less code than raw tkinter.**
24
+
25
+ EasyPyUI is a lightweight GUI library built on Python's standard `tkinter` and `ttk`.
26
+ It provides a short beginner-friendly API while keeping access to native Tk widgets.
27
+
28
+ ## Installation
29
+
30
+ ```bash
31
+ pip install easypyui
32
+ ```
33
+
34
+ ## Quick Start
35
+
36
+ ```python
37
+ from easypyui import *
38
+
39
+ app("Hello EasyPyUI", 500, 400, appearance="dark")
40
+ title("Hello!")
41
+
42
+ name = minput("Name", placeholder="Your name")
43
+ mbutton("Say hello", lambda: notify("Hello " + name.get()))
44
+
45
+ fade_in(400)
46
+ run()
47
+ ```
48
+
49
+ ## Modern UI
50
+
51
+ EasyPyUI 2.x includes `mbutton()`, `minput()`, `mswitch()`, `mcard()`,
52
+ Light/Dark appearance and custom accent colors.
53
+
54
+ ```python
55
+ app("Dashboard", 700, 500, appearance="dark", accent="#8b5cf6")
56
+ ```
57
+
58
+ ## Animation
59
+
60
+ ```python
61
+ ring = progress_ring(20, size=110)
62
+ mbutton("Start", lambda: ring.animate_to(100, 1000))
63
+ fade_in(500)
64
+ ```
65
+
66
+ Easing modes: `linear`, `ease_in`, `ease_out`, `ease_in_out`.
67
+
68
+ ## Pages / Router
69
+
70
+ ```python
71
+ from easypyui import *
72
+
73
+ app("Pages", 500, 350)
74
+
75
+ def home(ui):
76
+ title("Home")
77
+ on("Settings", lambda: go("settings"))
78
+
79
+ def settings(ui):
80
+ title("Settings")
81
+ on("Back", lambda: go("home"))
82
+
83
+ route("home", home)
84
+ route("settings", settings)
85
+ go("home")
86
+ run()
87
+ ```
88
+
89
+ ## Background Tasks
90
+
91
+ ```python
92
+ def work():
93
+ import time
94
+ time.sleep(2)
95
+ return "Done!"
96
+
97
+ run_task(work, done=lambda result: notify(result), loading_text="Working...")
98
+ ```
99
+
100
+ ## Native tkinter access
101
+
102
+ Most EasyPyUI wrapper objects expose `.tk`:
103
+
104
+ ```python
105
+ btn = mbutton("Test", lambda: print("clicked"))
106
+ btn.tk.bind("<Button-2>", lambda event: print("middle click"))
107
+ ```
108
+
109
+ ## Classic API
110
+
111
+ The older API remains available, including `window()`, `text()`, `inputbox()`,
112
+ `button()`, `table()`, `canvas()` and `start()`.
113
+
114
+ ## Requirements
115
+
116
+ - Python 3.9+
117
+ - tkinter support in your Python installation
118
+ - No mandatory third-party runtime GUI dependency
119
+
120
+ ## License
121
+
122
+ MIT License
123
+
124
+ ## Version
125
+
126
+ Current release: **3.0.0**
127
+
128
+ 2.2.1 is a PyPI metadata and documentation update for the 2.2 series.
129
+
130
+
131
+ ## 2.3 Productivity APIs
132
+
133
+ ### Form validation
134
+
135
+ ```python
136
+ f = form()
137
+
138
+ email = f.add(
139
+ "Email",
140
+ minput("Email"),
141
+ [Validator.required(), Validator.email()]
142
+ )
143
+
144
+ password_box = f.add(
145
+ "Password",
146
+ minput("Password", password=True),
147
+ [Validator.required(), Validator.min_length(8)]
148
+ )
149
+
150
+ def submit():
151
+ ok, errors = f.validate()
152
+ if ok:
153
+ notify(str(f.values()))
154
+
155
+ mbutton("Submit", submit)
156
+ ```
157
+
158
+ ### Reactive State
159
+
160
+ ```python
161
+ count = state(0)
162
+
163
+ label_widget = text("0")
164
+ count.bind_text(label_widget)
165
+
166
+ mbutton("+1", lambda: count.update(lambda n: n + 1))
167
+ ```
168
+
169
+ ### Keyboard shortcuts
170
+
171
+ ```python
172
+ shortcut("ctrl+s", save)
173
+ shortcut("ctrl+q", close)
174
+ ```
175
+
176
+ ### Debounce / Throttle
177
+
178
+ ```python
179
+ search = debounce(300, do_search)
180
+ resize_handler = throttle(100, update_layout)
181
+ ```
182
+
183
+
184
+ ## 2.4 Large Application Widgets
185
+
186
+ - `datatable()` — search, sorting and pagination
187
+ - `modal()` — modal window
188
+ - `drawer()` — collapsible side drawer
189
+ - `accordion()` — expandable sections
190
+ - `datepicker()` — date value input
191
+ - `notifications()` — notification center
192
+
193
+ ```python
194
+ table = datatable(["name", "score"], ["Name", "Score"], page_size=5)
195
+ table.set_rows([
196
+ ("Noah", 100),
197
+ ("Daniel", 95),
198
+ ])
199
+ ```
200
+
201
+
202
+ # EasyPyUI 3.0
203
+
204
+ EasyPyUI 3.0 moves beyond a tkinter helper toward a small application framework.
205
+
206
+ ## Reactive UI
207
+
208
+ ```python
209
+ name = state("Noah")
210
+ upper = computed(lambda: name.get().upper(), name)
211
+
212
+ field = minput("Name")
213
+ bind(field, name)
214
+ text_widget = text("")
215
+ upper.bind_text(text_widget)
216
+ ```
217
+
218
+ ## AppShell
219
+
220
+ ```python
221
+ ui = shell("My App")
222
+
223
+ ui.page("home", "Home", lambda parent: __import__("tkinter").Label(parent, text="Home").pack())
224
+ ui.page("settings", "Settings", lambda parent: __import__("tkinter").Label(parent, text="Settings").pack())
225
+ ui.start("home")
226
+ ```
227
+
228
+ ## Design Tokens
229
+
230
+ ```python
231
+ design(radius=12, spacing=10, font="Segoe UI", title_size=24)
232
+ ```
233
+
234
+ ## CLI
235
+
236
+ ```bash
237
+ easypyui new my_app
238
+ cd my_app
239
+ python app.py
240
+ ```
241
+
242
+ ## Included from 2.x
243
+
244
+ Modern widgets, animations, routing, background tasks, forms and validators,
245
+ state management, shortcuts, debounce/throttle, DataTable, Modal, Drawer,
246
+ Accordion, DatePicker and NotificationCenter remain available.
@@ -2,12 +2,19 @@ LICENSE
2
2
  README.md
3
3
  pyproject.toml
4
4
  easypyui/__init__.py
5
+ easypyui/__main__.py
5
6
  easypyui/animation.py
7
+ easypyui/cli.py
6
8
  easypyui/core.py
7
9
  easypyui/largeapp.py
8
10
  easypyui/modern.py
9
11
  easypyui/productivity.py
12
+ easypyui/reactive.py
13
+ easypyui/shell.py
14
+ easypyui/theme3.py
10
15
  easypyui.egg-info/PKG-INFO
11
16
  easypyui.egg-info/SOURCES.txt
12
17
  easypyui.egg-info/dependency_links.txt
13
- easypyui.egg-info/top_level.txt
18
+ easypyui.egg-info/entry_points.txt
19
+ easypyui.egg-info/top_level.txt
20
+ tests/test_public_api.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ easypyui = easypyui.cli:main
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "easypyui"
7
- version = "2.4.0"
7
+ version = "3.0.0"
8
8
  description = "A simple and modern Python GUI library built on tkinter and ttk"
9
9
  readme = {file = "README.md", content-type = "text/markdown"}
10
10
  requires-python = ">=3.9"
@@ -27,3 +27,6 @@ Homepage = "https://pypi.org/project/easypyui/"
27
27
  [tool.setuptools.packages.find]
28
28
  where = ["."]
29
29
  include = ["easypyui*"]
30
+
31
+ [project.scripts]
32
+ easypyui = "easypyui.cli:main"
@@ -0,0 +1,5 @@
1
+ import easypyui
2
+
3
+ def test_api():
4
+ for name in ["run_task","state","computed","bind","shell","datatable","modal","design"]:
5
+ assert hasattr(easypyui,name), name
File without changes
File without changes
File without changes
File without changes
File without changes