汉字笔画生成
本帖最后由 liuchangng 于 2024-4-19 15:51 编辑一,简介
小孩上小学,学习汉字书写,为了掌握正确的书写顺序,编写了这个小工具.
二,代码展示
import logging
import os
import re
import time
import flet
from PIL import Image
from flet import (
Page,
UserControl,
Text,
ListView
)
from flet_core import AlertDialog, TextButton
from playwright.sync_api import sync_playwright# 下载浏览器 playwright install chromium
# 1. 初始化日志记录器
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
# 2. 定义浏览器User-Agent
USER_AGENT = \
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'
class ChineseBiHua(UserControl):
"""汉字笔划控件"""
def __init__(self, page: Page, persistent_browser: bool = True):
super().__init__(page)
self.page = page
self.persistent_browser = persistent_browser# 是否非无痕模式,默认无痕模式
# 3. 初始化汉字输入文本框
self.chinese_word_input = flet.TextField(
label='待输入汉字(可以空格分割;逗号分隔;不加任何符号.)',
value='无',
width=615,
max_lines=5,
border_radius=10
)
# 4. 初始化汉字图片排序下拉菜单
self.word_sort_dropdown = flet.Dropdown(
height=55,
width=150,
border_radius=20,
label="排序",
text_size=12,
hint_text="选择需要的顺序",
value="1",
options=[
flet.dropdown.Option(key="1", text="汉字顺序"),
flet.dropdown.Option(key="2", text="字典顺序"),
],
autofocus=True,
)
# 5. 定义显示笔划图片的控件,可以滚动
self.bihua_scroll_viewer = ListView(expand=1, controls=[flet.Image(
src='./images/笔画总表.png',
height=600,
fit=flet.ImageFit.CONTAIN,
)], height=600, auto_scroll=True)
def build(self):
# 5. 构建页面布局
layout = [
# 页面标题
flet.Row(
controls=,
alignment=flet.MainAxisAlignment.CENTER,
),
# 汉字输入区域
flet.Row(controls=),
# 操作按钮区域
flet.Row(
controls=[
self.word_sort_dropdown,
# 生成笔划按钮
flet.ElevatedButton(
"汉字笔划",
height=55,
icon=flet.icons.SAVE,
on_click=self.generate_bi_hua,
),
],
alignment=flet.MainAxisAlignment.END,
),
# 显示笔划图片区域
flet.Row(controls=)
]
return flet.Column(controls=layout)
def generate_bi_hua(self, e):
"""生成汉字笔划事件处理函数"""
# 6. 初始化Playwright环境
with sync_playwright() as playwright:
if self.persistent_browser:# 无痕模式
browser = playwright.chromium.launch(headless=False, args=['--start-maximized'])
page = browser.new_context(user_agent=USER_AGENT).new_page()
page.set_viewport_size(viewport_size={'width': 1920, 'height': 1080})# 设置浏览器窗口大小
else:
browser = playwright.chromium.launch_persistent_context(# 非无痕模式
executable_path=r'C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe',# 浏览器路径
channel='msedge',# 浏览器类型
headless=False,
user_data_dir=r"C:\Users\Administrator\AppData\Local\Microsoft\Edge\User Data\Default",# 浏览器数据路径
accept_downloads=True,
args=['--start-maximized'],# 设置浏览器窗口大小
no_viewport=True,
)
page = browser.new_page()
# 获取待处理汉字
words = re.sub(r'[^\u4e00-\u9fff]', '', self.chinese_word_input.value)
logging.info(f'汉字: {words}')
# 去除重复汉字并按指定顺序排序
word_list = list(set(words))
if self.word_sort_dropdown.value == "2":
word_list.sort()
# 逐个生成并保存单个汉字笔划图片
for word in word_list:
self.generate_single_bi_hua(page, word)
time.sleep(1)
# 合成所有汉字笔划图片
concat_images(, direction='vertical')
# 删除图片
for item in word_list:
os.remove(f'./images/{item}.png')
# 更新界面上的笔划图片为合成后的图片
self.bihua_scroll_viewer.controls.clear()# 清空已存在的图片控件
self.bihua_scroll_viewer.controls.append(flet.Image(
src='./images/合成.png',
fit=flet.ImageFit.CONTAIN
))
self.bihua_scroll_viewer.update()
# 弹出提示对话框并打开图片目录
self.show_completion_dialog_and_open_directory()
# 关闭浏览器
browser.close()
def generate_single_bi_hua(self, page, word):
"""生成单个汉字笔划图片"""
url = f"https://hanyu.baidu.com/s?wd={word}&ptype=zici"
try:
# 访问指定URL
page.goto(url)
# 等待笔划元素加载并截图
element_selector = '.word-stroke-wrap'
page.wait_for_selector(element_selector, timeout=5000)
element = page.locator(element_selector)
bounding_box = element.bounding_box()
logging.info(f'{word}: {bounding_box}')
if bounding_box:
x, y, width, height = (bounding_box['x'], bounding_box['y'], bounding_box['width'],
bounding_box['height'])
page.screenshot(path=f'./images/{word}.png', full_page=True,
clip={'x': x, 'y': y, 'width': width, 'height': height})
time.sleep(0.5)
else:
logging.warning(f"{word}没有找到笔划!")
except Exception as e:
logging.error(f"{word}生成笔划时发生错误,原因:{e}")
def show_completion_dialog_and_open_directory(self):
"""显示完成提示对话框并打开图片目录"""
def close_dlg(e):
dialog.open = False
os.startfile(os.path.abspath('./images'))
self.page.update()
# 创建提示对话框
dialog = AlertDialog(
title=Text('提示:'),
actions=[
TextButton("确定", on_click=close_dlg)
],
actions_alignment=flet.MainAxisAlignment.END,
)
self.page.dialog = dialog
dialog.content = Text('合成图片完成!')
dialog.open = True
self.page.update()
def concat_images(images, direction='horizontal', separator_color=(0, 0, 0), separator_size=3):
"""
合成图片
:param images: 待合成图片列表
:param direction: 合成方向(horizontal或vertical)
:param separator_color: 分割线颜色
:param separator_size: 分割线大小
"""
# 打开所有图像并获取尺寸
images =
widths, heights = zip(*(i.size for i in images))
logging.info(f'widths: {widths}, heights: {heights}')
# 计算拼接后图像的尺寸
if direction == 'horizontal':
total_width = sum(widths) + separator_size * (len(images) - 1)
max_height = max(heights)
new_size = (total_width, max_height)
else:
max_width = max(widths)
total_height = sum(heights) + separator_size * (len(images) - 1)
new_size = (max_width, total_height)
# 创建新图像并将所有图像拼接到上面
new_image = Image.new('RGB', new_size, color=separator_color)
offset = 0
for img in images:
if direction == 'horizontal':
new_image.paste(img, (offset, 0))
offset += img.size + separator_size
else:
new_image.paste(img, (0, offset))
offset += img.size + separator_size
new_image.save('./images/合成.png')
def main(page: flet.Page):
# 10. 定义页面属性和布局
page.title = "汉字笔画"
page.window_width = 650
page.window_height = 850
page.scroll = True
page.window_maximizable = False
page.window_minimized = False
page.window_center()
page.update()
# 11. 创建并添加汉字笔划控件到页面
chinese_bihua = ChineseBiHua(page)
page.add(chinese_bihua)
if __name__ == '__main__':
flet.app(target=main)
三,本地运行
1,安装依赖
```shell
pip install flet==0.21.2 playwright==1.42.0 pillow==10.2.0
```
2,安装浏览器
```shell
playwright install chromium
```
3,运行
```shell
python main.py
```
四,可执行文件地址
版本hanzibihuaV20240415.zip
123网盘:
https://www.123pan.com/s/Gvawjv-TwOph.html提取码:52pj
百度网盘:
链接:https://pan.baidu.com/s/1ibSbeemyyir_cb-k8K0fCw?pwd=1024
提取码:1024
说明:
1)增加拼音,部首,笔画数
2)效果图
版本hanzibihuaV20240410.zip
https://www.123pan.com/s/Gvawjv-PaOph.html提取码:52pj
说明:
1)输入汉字或句子生成笔画合成图片
2)效果图
这个非常好,分享的很是有水准 D:\Python>pip install flet
ERROR: Could not find a version that satisfies the requirement flet (from versions: none)
ERROR: No matching distribution found for flet
D:\Python>playwright install chromium
'playwright' 不是内部或外部命令,也不是可运行的程序
或批处理文件。
D:\Python>pip3 install flet
ERROR: Could not find a version that satisfies the requirement flet (from versions: none)
ERROR: No matching distribution found for flet
D:\Python>pip install flet -i https://pypi.tuna.tsinghua.edu.cn/simple/
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple/
ERROR: Could not find a version that satisfies the requirement flet (from versions: none)
ERROR: No matching distribution found for flet
D:\Python>pip3 install flet -i https://pypi.tuna.tsinghua.edu.cn/simple/
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple/
ERROR: Could not find a version that satisfies the requirement flet (from versions: none)
ERROR: No matching distribution found for flet
这个也太强了,练字好帮手 这个不错,方便! 真的很不错,感谢楼主分享 不错。这是一个好帮手。 这个厉害了,我现在都不会写字了 不懂编程,请问怎么使用它?谢谢! py都写了这么多行代码,这是真的牛。 感谢楼主分享!