[tkinter实现]汉字笔顺小软件

软件简介

本软件旨在帮助小学生通过互动式学习掌握汉字的基本笔画和笔顺。软件采用Tkinter库构建,提供了一个用户友好的图形界面,适合小学生使用。

主要功能:

  1. 汉字展示:软件能够展示单个汉字,并以动画形式演示其标准笔画顺序。
  2. 笔顺学习:通过动态图示,学生可以学习每个汉字的正确笔顺,加强记忆。
  3. 读音练习:软件提供汉字的标准读音。
  4. 笔画数统计:展示每个汉字的笔画数,加深学生对汉字结构的认识。

技术实现:

  • 本软件使用Python语言开发,利用Tkinter库创建图形用户界面。
  • 汉字笔顺动画和读音数据来源于汉字数据库,确保信息的准确性。
  • 软件设计注重用户体验,界面简洁,操作直观。

效果展示:

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

源码

class WinGUI(tk.Tk):def __init__(self):super().__init__()self.__win()self.tk_tabs_menu = self.__tk_tabs_menu(self)self.tk_text_koujue = self.__tk_text_koujue(self.tk_tabs_menu_4)self.tk_text_ext_rule = self.__tk_text_ext_rule(self.tk_tabs_menu_3)self.tk_text_common_rule = self.__tk_text_common_rule(self.tk_tabs_menu_2)self.tk_label_bihua_name_image = self.__tk_label_bihua_name_image(self.tk_tabs_menu_1)self.tk_text_title = self.__tk_text_title(self.tk_tabs_menu_0)self.tk_input_search_chinese = self.__tk_input_search_chinese(self.tk_tabs_menu_0)self.tk_button_search_btn = self.__tk_button_search_btn(self.tk_tabs_menu_0)self.tk_text_bihua_num = self.__tk_text_bihua_num(self.tk_tabs_menu_0)self.tk_text_pinyin = self.__tk_text_pinyin(self.tk_tabs_menu_0)self.tk_label_bishun_img = self.__tk_label_bishun_img(self.tk_tabs_menu_0)self.tk_button_pre_img = self.__tk_button_pre_img(self.tk_tabs_menu_0)self.tk_button_next_img = self.__tk_button_next_img(self.tk_tabs_menu_0)self.bihua_num = 0self.current_tile = -1def __win(self):self.title("汉字笔画工具")# 设置窗口大小、居中width = 500height = 400screenwidth = self.winfo_screenwidth()screenheight = self.winfo_screenheight()geometry = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)self.geometry(geometry)self.resizable(width=False, height=False)def scrollbar_autohide(self, vbar, hbar, widget):"""自动隐藏滚动条"""def show():if vbar: vbar.lift(widget)if hbar: hbar.lift(widget)def hide():if vbar: vbar.lower(widget)if hbar: hbar.lower(widget)hide()widget.bind("<Enter>", lambda e: show())if vbar: vbar.bind("<Enter>", lambda e: show())if vbar: vbar.bind("<Leave>", lambda e: hide())if hbar: hbar.bind("<Enter>", lambda e: show())if hbar: hbar.bind("<Leave>", lambda e: hide())widget.bind("<Leave>", lambda e: hide())def v_scrollbar(self, vbar, widget, x, y, w, h, pw, ph):widget.configure(yscrollcommand=vbar.set)vbar.config(command=widget.yview)vbar.place(relx=(w + x) / pw, rely=y / ph, relheight=h / ph, anchor='ne')def h_scrollbar(self, hbar, widget, x, y, w, h, pw, ph):widget.configure(xscrollcommand=hbar.set)hbar.config(command=widget.xview)hbar.place(relx=x / pw, rely=(y + h) / ph, relwidth=w / pw, anchor='sw')def create_bar(self, master, widget, is_vbar, is_hbar, x, y, w, h, pw, ph):vbar, hbar = None, Noneif is_vbar:vbar = Scrollbar(master)self.v_scrollbar(vbar, widget, x, y, w, h, pw, ph)if is_hbar:hbar = Scrollbar(master, orient="horizontal")self.h_scrollbar(hbar, widget, x, y, w, h, pw, ph)self.scrollbar_autohide(vbar, hbar, widget)def __tk_tabs_menu(self, parent):frame = Notebook(parent)self.tk_tabs_menu_0 = self.__tk_frame_menu_0(frame)frame.add(self.tk_tabs_menu_0, text="笔画")self.tk_tabs_menu_1 = self.__tk_frame_menu_1(frame)frame.add(self.tk_tabs_menu_1, text="笔画名称表")self.tk_tabs_menu_2 = self.__tk_frame_menu_2(frame)frame.add(self.tk_tabs_menu_2, text="笔顺一般规则")self.tk_tabs_menu_3 = self.__tk_frame_menu_3(frame)frame.add(self.tk_tabs_menu_3, text="笔顺补充规则")self.tk_tabs_menu_4 = self.__tk_frame_menu_4(frame)frame.add(self.tk_tabs_menu_4, text="笔顺口诀")frame.place(x=0, y=0, width=500, height=400)return framedef __tk_frame_menu_0(self, parent):frame = Frame(parent)frame.place(x=0, y=0, width=500, height=400)return framedef __tk_frame_menu_1(self, parent):frame = Frame(parent)frame.place(x=0, y=0, width=500, height=400)return framedef __tk_frame_menu_2(self, parent):frame = Frame(parent)frame.place(x=0, y=0, width=500, height=400)return framedef __tk_frame_menu_3(self, parent):frame = Frame(parent)frame.place(x=0, y=0, width=500, height=400)return framedef __tk_frame_menu_4(self, parent):frame = Frame(parent)frame.place(x=0, y=0, width=500, height=400)return framedef __tk_text_koujue(self, parent):"""笔顺口诀"""text = tk.Text(parent, spacing2=25, bd=0, wrap="word", font=("微软雅黑", 14))text.place(x=0, y=0, width=500, height=400)text.insert(tk.END, "从上到下为主,从左到右为辅。\r\n上下左右俱全,根据层次分组;\r\n横竖交叉先横,撇捺交叉先撇;\r\n中间突出先中,右上有点后补;\r\n上包下时先外,下包上时先内;\r\n""三框首横末折,大囗最后封底;\r\n分歧遵照《规范》,做到流畅美观。")text.config(state='disabled')return textdef __tk_text_ext_rule(self, parent):text = tk.Text(parent, spacing2=25, bd=0, wrap="word", font=("微软雅黑", 14))text.place(x=0, y=0, width=500, height=400)text.insert(tk.END,"1.点在上部或左上,先写点:衣 立 为\r\n2.点在右上或在字里,后写点:发 瓦 我\r\n3.上右和上左包围结构的字,先外后里:厅 座 屋\r\n4.左下包围结构的字,先里后外:远 ""建 廷\r\n5.左下右包围结构的字,先里后外:凶 画\r\n6.左上右包围结构的字,先里后外:同 用 风\r\n7.上左下包围结构的字,先上后里在左下:医 巨 匠 区")text.config(state='disabled')return textdef __tk_text_common_rule(self, parent):text = tk.Text(parent, spacing2=25, bd=0, wrap="word", font=("微软雅黑", 14))text.place(x=0, y=0, width=500, height=400)text.insert(tk.END,"1.先撇后捺 : 人 八 入\r\n2.先横后竖:十 王 干\r\n3.从上到下:三 竟 音\r\n4.从左到右:理 利 礼 明 湖\r\n5.先外后里: 问 同 ""司\r\n6.先外后里在封口:国 圆 园 圈\r\n7.先中间后两边:小 水\r\n")text.config(state='disabled')return textdef __tk_label_bihua_name_image(self, parent):global img  # 使用全局变量来保持对图片对象的引用try:# 打开图片文件img = Image.open("bihua.png")# 获取Label的宽度和高度label_width = 500label_height = 400# 计算图片的原始宽高比original_ratio = img.size[0] / img.size[1]# 根据Label的尺寸和图片的宽高比计算新的图片尺寸if original_ratio >= 1:  # 宽度大于高度new_width = label_widthnew_height = int(new_width / original_ratio)else:  # 高度大于宽度new_height = label_heightnew_width = int(new_height * original_ratio)# 调整图片尺寸以适应Label的尺寸,同时保持宽高比img = img.resize((new_width, new_height - 35), )# 将PIL图片对象转换为Tkinter的PhotoImage对象img = ImageTk.PhotoImage(img)# 创建Label,并设置图片和位置label = Label(parent, image=img, anchor="center")label.place(x=(label_width - new_width) // 2, y=(label_height - new_height) // 2, width=new_width,height=new_height)return labelexcept IOError:logging.error("图片文件bihua.png未找到或无法打开。")def __tk_text_title(self, parent):ipt = Entry(parent, justify="center", font=("微软雅黑", 18), foreground="red")ipt.place(x=175, y=12, width=150, height=53)ipt.insert(tk.END, "汉字笔画工具")ipt.config(state='disabled')return iptdef __tk_input_search_chinese(self, parent):ipt = Entry(parent, justify="center", font=("微软雅黑", 24))ipt.place(x=20, y=116, width=59, height=58)return iptdef __tk_button_search_btn(self, parent):btn = Button(parent, text="搜索", takefocus=False, command=self.tk_button_search_click)btn.place(x=91, y=117, width=66, height=57)return btndef tk_button_search_click(self):# 清除数据self.bihua_num = 0self.current_tile = -1self.tk_text_bihua_num = self.__tk_text_bihua_num(self.tk_tabs_menu_0)self.tk_text_pinyin = self.__tk_text_pinyin(self.tk_tabs_menu_0)chinese = self.tk_input_search_chinese.get()if not chinese:messagebox.showerror("提示", message="搜索汉字不能为空")returnelif len(chinese) > 1:messagebox.showerror("提示", message="搜索汉字不能超过1个")returnassets = './assets'if not os.path.exists(assets):os.mkdir(assets)chinese_dir = os.path.join(assets, chinese)if not os.path.exists(chinese_dir):# 创建目录os.mkdir(chinese_dir)# 假设chinese是单个汉字字符,chinese_ord是其Unicode编码chinese_ord = ord(chinese)# 构造汉字笔顺动画图片和笔顺规范图片的URLhanzi_url = f'https://bishun.net/hanzi/{chinese_ord}'donghua_url = f'https://bishun.net/assets/bishun/donghua/bishundonghua-{chinese_ord}.gif'fenbu_url = f'https://bishun.net/assets/bishun/fenbu/bishun-{chinese_ord}.png'try:# 请求汉字信息页面response = requests.get(hanzi_url)if response.status_code == 200:# 解析网页内容soup = BeautifulSoup(response.content, 'html.parser')# 这里需要根据网页结构来定位笔画数和读音的元素# 例如,如果它们位于具有特定class的元素内,可以使用soup.find()或soup.select()# 以下代码仅为示例,需要根据实际网页结构进行调整bi_shu = soup.select('.bishun-hanzi-info-right')[1].textdu_yin = soup.select('.bishun-hanzi-info-right')[2].textprint(f"笔画数:{bi_shu},读音:{du_yin}")with open(os.path.join(chinese_dir, f'{chinese}.txt'), 'w', encoding='utf-8') as f:f.write(f"{bi_shu}\n{du_yin}")# 请求并下载笔顺动画图片donghua_response = requests.get(donghua_url)if donghua_response.status_code == 200:with open(os.path.join(chinese_dir, f'{chinese}.gif'), 'wb') as f:f.write(donghua_response.content)# 请求并下载笔顺规范图片fenbu_response = requests.get(fenbu_url)if fenbu_response.status_code == 200:with open(os.path.join(chinese_dir, f'{chinese}.png'), 'wb') as f:f.write(fenbu_response.content)except requests.exceptions.RequestException as e:logging.error(f"请求失败:{e}")# 读取汉字信息文件with open(os.path.join(chinese_dir, f'{chinese}.txt'), 'r', encoding='utf-8') as f:lines = f.readlines()bi_shu = lines[0].strip()self.tk_text_bihua_num.insert(tk.END, f'笔画: {bi_shu}')self.tk_text_bihua_num.config(state='disabled')du_yin = lines[1].strip()self.tk_text_pinyin.insert(tk.END, f'读音: {du_yin}')self.tk_text_pinyin.config(state='disabled')self.bihua_num = int(bi_shu)# 显示完整字图片gif self.tk_label_bishun_imgglobal img1  # 使用全局变量来保持对图片对象的引用# 打开图片文件img1 = Image.open(os.path.join(chinese_dir, f'{chinese}.gif'))# 获取Label的宽度和高度label_width = 137label_height = 138# 计算图片的原始宽高比original_ratio = img1.size[0] / img1.size[1]# 根据Label的尺寸和图片的宽高比计算新的图片尺寸if original_ratio >= 1:  # 宽度大于高度new_width = label_widthnew_height = int(new_width / original_ratio)else:  # 高度大于宽度new_height = label_heightnew_width = int(new_height * original_ratio)# 调整图片尺寸以适应Label的尺寸,同时保持宽高比img1 = img1.resize((new_width - 15, new_height - 15), )# 将PIL图片对象转换为Tkinter的PhotoImage对象img1 = ImageTk.PhotoImage(img1)self.tk_label_bishun_img.config(image=img1)# 提前加载笔顺规范global tilestiles = self.load_and_split_image(os.path.join(chinese_dir, f'{chinese}.png'), self.bihua_num)def __tk_text_bihua_num(self, parent):ipt = Entry(parent, justify="left", font=("微软雅黑", 16))ipt.place(x=169, y=115, width=91, height=60)return iptdef __tk_text_pinyin(self, parent):ipt = Entry(parent, justify="left", font=("微软雅黑", 14))ipt.place(x=272, y=116, width=220, height=58)return iptdef __tk_label_bishun_img(self, parent):label = Label(parent, text="", anchor="center", )label.place(x=180, y=215, width=137, height=138)return labeldef __tk_button_pre_img(self, parent):btn = Button(parent, text="上一笔", takefocus=False, command=lambda: self.__pre_img_click())btn.place(x=80, y=257, width=77, height=56)return btndef __tk_button_next_img(self, parent):btn = Button(parent, text="下一笔", takefocus=False, command=lambda: self.__next_img_click())btn.place(x=337, y=254, width=82, height=59)return btndef __pre_img_click(self):if 0 < self.current_tile < self.bihua_num:self.current_tile -= 1else:self.current_tile = 0self.tk_label_bishun_img.config(image=tiles[self.current_tile])def __next_img_click(self):if self.current_tile < 0:self.current_tile = 0elif self.current_tile == self.bihua_num - 1:self.current_tile = self.bihua_num - 1else:self.current_tile += 1self.tk_label_bishun_img.config(image=tiles[self.current_tile])# 加载图片并分割成多个部分def load_and_split_image(self, image_path, bi_shu):img = Image.open(image_path)width, height = img.sizeconst_per_row = 5  # 每一行最多5笔total_row = math.ceil(bi_shu / const_per_row)  # 向上取整,不能四舍五入tile_width, tile_height = (width // const_per_row, height // total_row)tiles = []for y in range(0, height, tile_height):for x in range(0, width, tile_width):tile = img.crop((x, y, x + tile_width, y + tile_height))tile = tile.resize((tile_width - 35, tile_height - 35), )tiles.append(ImageTk.PhotoImage(tile))return tiles

适用人群:

本软件特别适合刚开始学习汉字书写的小学生,也适用于对外汉语学习者了解汉字笔画。

开发者信息:

联系方式:liuchangng@163.com

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2982367.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

SWOT分析法:知彼知己的战略规划工具

文章目录 一、什么是SWOT分析法二、SWOT分析法如何产生的三、SWOT分析法适合哪些人四、SWOT分析法的应用场景五、SWOT分析法的优缺点六、SWOT分析实例 一、什么是SWOT分析法 SWOT分析法是一种用于评估组织、项目、个人或任何其他事物的战略规划工具。SWOT是Strengths&#xff…

每日OJ题_BFS解决拓扑排序③_力扣LCR 114. 火星词典

目录 力扣LCR 114. 火星词典 解析代码 力扣LCR 114. 火星词典 LCR 114. 火星词典 难度 困难 现有一种使用英语字母的外星文语言&#xff0c;这门语言的字母顺序与英语顺序不同。 给定一个字符串列表 words &#xff0c;作为这门语言的词典&#xff0c;words 中的字符串已…

光伏储能控制系统的功能策略

一、控制策略 1、功率控制策略 光伏阵列的输出功率受光照和温度影响&#xff0c;最大功率点是转换太阳能为电能的最高效点。MPPT控制器根据实时参数调整光伏阵列工作点&#xff0c;确保其始终处于最大功率输出状态&#xff0c;提高能量转换效率&#xff0c;增加发电量&#x…

基于51单片机智能鱼缸仿真LCD1602显示( proteus仿真+程序+设计报告+讲解视频)

基于51单片机智能鱼缸仿真LCD显示 1. 主要功能&#xff1a;2. 讲解视频&#xff1a;3. 仿真4. 程序代码5. 设计报告6. 设计资料内容清单&&下载链接资料下载链接&#xff1a; 基于51单片机智能鱼缸仿真LCD显示( proteus仿真程序设计报告讲解视频&#xff09; 仿真图prot…

免费开源!手机上有这一款软件就够了!

今天这款软件解决了你们最近常问我的资源问题&#xff0c;甚至解决的不是一种&#xff0c;而是好多种&#xff0c;所以这款软件我一定要分享给你&#xff0c;也建议需要这方面软件的小伙伴都去体验一下&#xff0c;说不定就爱上了呢。 01 - 简阅免费小说&#xff08;安卓&#…

低代码信创开发核心技术(四)动态元数据系统设计

一、概述 在当今快速发展的信息技术领域&#xff0c;动态元数据系统扮演着至关重要的角色。它不仅能够提供数据的描述信息&#xff0c;还能动态地适应业务需求的变化&#xff0c;从而提高系统的灵活性和可扩展性。构建一个动态元数据系统意味着我们可以在不重启系统的情况下&a…

CUDA的应用场景

CUDA的应用场景随着技术的发展不断扩展&#xff0c;其核心优势在于能够显著提高并行计算任务的处理速度&#xff0c;这对于任何需要处理大量数据和执行复杂计算的领域都是极其有价值的。CUDA开发的应用场景非常广泛&#xff0c;主要得益于其强大的并行计算能力&#xff0c;以下…

上网行为管理软件有哪些?三款常用上网行为管理软件评测

互联网的普及&#xff0c;企业和个人对于网络安全和信息保护的需求越来越高。为了确保网络环境的安全和稳定&#xff0c;上网行为管理软件应运而生。本文将对三款常用的上网行为管理软件进行评测&#xff0c;分别是域智盾、Splunk Enterprise Security和安企神。 1、域智盾 域…

冯喜运:4.24 周三黄金原油市场分析报告及操作策略

黄金消息面解析&#xff1a;周三(4月24日)黄金反弹后微幅回跌&#xff0c;金价在2325美元附近喘息。尽管美国国债收益率下降&#xff0c;美元走弱&#xff0c;金价未能维持涨势。标普全球PMI弱于预期&#xff0c;引发了对美联储可能降息的猜测。中东地缘紧张局势有所缓解&#…

dist包在windows的nginx下部署运行

nginx 附带下载包 我用夸克网盘分享了「nginx-1.18.0.zip」 链接&#xff1a;https://pan.quark.cn/s/e87bbf87a742 将dist放到html文件目录下 3.找到nginx的配置文件&#xff0c;conf 下&#xff0c;用编辑器打开 nginx.conf 编辑。 location ^~/api {rewrite ^/api/(.*)…

kubernetes中DaemonSet控制器

一、概念 使用DaemonSet控制器&#xff0c;相当于在节点上启动了一个守护进程。通过DaemonSet控制器可以确保在每个节点上运行Pod的一个副本。如果有心的node节点加入集群&#xff0c;则DaemonSet控制器会自动给新加入的节点增加一个Pod的副本&#xff1b;反之&#xff0c;当有…

企业工商信息查询API接口如何对接

企业工商信息查询API接口指的是输入公司名全称/注册号/社会统一信用代码的任意一种&#xff0c;获得企业工商注册登记中包含的各类重要信息&#xff0c;主要信息包括&#xff1a;注册号&#xff0c;注册资金&#xff0c;登记机关&#xff0c;注册地址&#xff0c;核准时间&…

Maven基础篇6

Idea环境中资源上传与下载 具体问题本地仓库如何与私服打交道&#xff1b; 本地仓库向私服上传文件&#xff0c;上传的文件位置在哪里&#xff1f; 访问私服配置相关信息&#xff1a;用户名密码&#xff1b; 下载东西&#xff0c;需要的各种信息&#xff0c;需要的仓库组的…

JavaEE 初阶篇-深入了解网络通信相关的基本概念(三次握手建立连接、四次挥手断开连接)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 网络通信概述 1.1 基本的通信架构 2.0 网络通信三要素 3.0 网络通信三要素 - IP 地址 3.1 查询 IP 地址 3.2 IP 地址由谁供应&#xff1f; 3.3 IP 域名 3.4 IP 分…

H800算力低至5.99元/卡时!抢鲜体验LLaMA3最佳实践就在潞晨云

由Meta发布的LLaMA3 8B和LLaMA3 70B的&#xff0c;将开源AI大模型推向新的高度。在多个基准测试上的表现均大幅超过已有竞品&#xff0c;成为AI应用的最新优选。 潞晨云现已上架 LLaMA3 8B和LLaMA3 70B从推理到微调和预训练的实践教程。 提供免费测试代金券&#xff0c;限时特…

树莓派学习之入门必会操作

树莓派学习之入门指南 一、软件准备二、镜像烧录三、远程登录 一、软件准备 ①raspberry pi image(官方烧录工具&#xff0c;将操作系统烧录到SD卡&#xff0c;SD卡插入树莓派) ②putty(远程登录软件&#xff0c;输入ip,以及username/password就可以远程登录树莓派不带图形化的…

【SMART目标法】项目管理必会的思维分析工具 06

SMART分析方法&#xff0c;是让管理者的工作变被动为主动的一个很好的手段。实施目标管理不但是有利于员工更加明确高效地工作&#xff0c;更是为未来的绩效考核制定了目标和考核标准&#xff0c;使考核更加科学化、规范化&#xff0c;更能保证考核的公开、公平与公正。 “sma…

嵌入式MCU和SOC的区别?

你大概率并不知晓嵌入式 MCU 与 SOC 之间的区别吧&#xff1f;从表面上来看&#xff0c;MCU 指代的是嵌入式微控制器&#xff0c;而 SOC 则代表着片上系统&#xff0c;这仿佛仅仅是嵌入式系统的不同称谓罢了。然而&#xff0c;在实际的研发以及产品设计过程中&#xff0c;你将会…

【算法刷题 | 贪心算法02】4.24(摆动序列)

文章目录 3.摆动序列3.1题目3.2解法&#xff1a;贪心3.2.1贪心思路3.2.2代码实现 3.摆动序列 3.1题目 如果连续数字之间的差严格地在正数和负数之间交替&#xff0c;则数字序列称为 摆动序列 。 第一个差&#xff08;如果存在的话&#xff09;可能是正数或负数。仅有一个元素…

docker-compose搭建redis环境:哨兵模式(一主两重两哨兵)

文章目录 0.BG1. 编写docker-compose.yml文件2. 哨兵配置文件sentinel.conf3.启动容器4.模拟故障转移 0.BG redis环境有多中模式&#xff0c;包括Standalone&#xff0c;Cluster和Sentinel模式等。这里介绍一种简单搭建Sentinel模式的方法&#xff0c;搭建一个一主两重两哨兵的…