Skip to content

Commit cee9722

Browse files
committed
preact sample works
1 parent 2d8bbed commit cee9722

File tree

2 files changed

+180
-1
lines changed

2 files changed

+180
-1
lines changed

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,13 +340,16 @@ python -m build -n -w
340340
- [x] Publish to PyPI
341341
- [x] Setup GitHub Actions for CI/CD
342342
- [x] Add async function support
343-
- [ ] Add preact example
343+
- [x] Add preact example
344344
- [ ] Add three.js example
345345
- [ ] Add three.js fiber example
346346
- [ ] Add screen saver 4 window example
347347
- [ ] Add MRI principle demo example by three.js fiber
348348
- [ ] Add screen saver 4 windows with MRI principle demo example by three.js fiber
349349

350+
## TBD
351+
- [x] CTRL-C support
352+
350353
## References
351354

352355
- [Webview](https://github.com/webview/webview)

examples/preact_simple_example.py

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
from webview.webview import Webview, Size, SizeHint
2+
from urllib.parse import quote
3+
import json
4+
5+
# 创建Webview实例
6+
webview = Webview(debug=True)
7+
webview.title = "Preact与Python交互示例"
8+
webview.size = Size(800, 600, SizeHint.NONE)
9+
10+
# 初始计数器值
11+
count = 0
12+
13+
# Python函数: 获取当前计数
14+
def get_count():
15+
return count
16+
17+
# Python函数: 增加计数
18+
def increment():
19+
global count
20+
count += 1
21+
return count
22+
23+
# Python函数: 减少计数
24+
def decrement():
25+
global count
26+
count -= 1
27+
return count
28+
29+
# 绑定Python函数
30+
webview.bind("getCount", get_count)
31+
webview.bind("increment", increment)
32+
webview.bind("decrement", decrement)
33+
34+
# HTML内容
35+
html = """
36+
<!DOCTYPE html>
37+
<html lang="en">
38+
<head>
39+
<meta charset="UTF-8">
40+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
41+
<title>Preact与Python交互示例</title>
42+
<style>
43+
body {
44+
font-family: system-ui, sans-serif;
45+
max-width: 500px;
46+
margin: 0 auto;
47+
padding: 2rem;
48+
text-align: center;
49+
}
50+
button {
51+
margin: 0 0.5rem;
52+
padding: 0.5rem 1rem;
53+
font-size: 1rem;
54+
cursor: pointer;
55+
}
56+
.counter {
57+
font-size: 2rem;
58+
margin: 2rem 0;
59+
}
60+
.loading {
61+
opacity: 0.5;
62+
}
63+
.error {
64+
color: red;
65+
margin: 1rem 0;
66+
}
67+
</style>
68+
</head>
69+
<body>
70+
<div id="app"></div>
71+
72+
<script type="module">
73+
import { h, render } from 'https://esm.sh/preact';
74+
import { useState, useEffect } from 'https://esm.sh/preact/hooks';
75+
import htm from 'https://esm.sh/htm';
76+
77+
// 初始化htm与Preact
78+
const html = htm.bind(h);
79+
80+
function Counter() {
81+
const [count, setCount] = useState(null);
82+
const [loading, setLoading] = useState(true);
83+
const [updating, setUpdating] = useState(false);
84+
const [error, setError] = useState(null);
85+
86+
// 从Python获取计数
87+
const fetchCount = async () => {
88+
try {
89+
setLoading(true);
90+
setError(null);
91+
const result = await getCount();
92+
setCount(result);
93+
} catch (err) {
94+
setError('获取计数失败: ' + err.message);
95+
console.error('获取计数错误:', err);
96+
} finally {
97+
setLoading(false);
98+
}
99+
};
100+
101+
// 初始加载
102+
useEffect(() => {
103+
fetchCount();
104+
}, []);
105+
106+
// 增加计数 - 处理异步
107+
const handleIncrement = async () => {
108+
try {
109+
setUpdating(true);
110+
setError(null);
111+
const newCount = await increment();
112+
setCount(newCount);
113+
} catch (err) {
114+
setError('增加计数失败: ' + err.message);
115+
console.error('增加计数错误:', err);
116+
} finally {
117+
setUpdating(false);
118+
}
119+
};
120+
121+
// 减少计数 - 处理异步
122+
const handleDecrement = async () => {
123+
try {
124+
setUpdating(true);
125+
setError(null);
126+
const newCount = await decrement();
127+
setCount(newCount);
128+
} catch (err) {
129+
setError('减少计数失败: ' + err.message);
130+
console.error('减少计数错误:', err);
131+
} finally {
132+
setUpdating(false);
133+
}
134+
};
135+
136+
// 显示加载状态
137+
if (loading) {
138+
return html`<div>加载中...</div>`;
139+
}
140+
141+
return html`
142+
<div class=${updating ? 'loading' : ''}>
143+
<h1>Preact计数器示例</h1>
144+
<p>通过Python后端管理状态(异步通信)</p>
145+
146+
<div class="counter">${count !== null ? count : '...'}</div>
147+
148+
${error && html`<div class="error">${error}</div>`}
149+
150+
<div>
151+
<button
152+
onClick=${handleDecrement}
153+
disabled=${updating}
154+
>
155+
减少
156+
</button>
157+
<button
158+
onClick=${handleIncrement}
159+
disabled=${updating}
160+
>
161+
增加
162+
</button>
163+
</div>
164+
</div>
165+
`;
166+
}
167+
168+
// 渲染应用
169+
render(html`<${Counter} />`, document.getElementById('app'));
170+
</script>
171+
</body>
172+
</html>
173+
"""
174+
175+
webview.navigate(f"data:text/html,{quote(html)}")
176+
webview.run()

0 commit comments

Comments
 (0)