【PB案例学习笔记】-22制作一个语音朗读金额小应用
写在前面
这是PB案例学习笔记系列文章的第22篇,该系列文章适合具有一定PB基础的读者。
通过一个个由浅入深的编程实战案例学习,提高编程技巧,以保证小伙伴们能应付公司的各种开发需求。
文章中设计到的源码,小凡都上传到了gitee代码仓库https://gitee.com/xiezhr/pb-project-example.git
需要源代码的小伙伴们可以自行下载查看,后续文章涉及到的案例代码也都会提交到这个仓库【pb-project-example】
如果对小伙伴有所帮助,希望能给一个小星星⭐支持一下小凡。
一、小目标
上一个案例中我们将小写金额转换为大写金额,这一个案例中我们将制作一个语音播报金额的小应用。
这个在日常开发中也很常见,尤其是在收费结算应用中。最终实现效果如下
金额语音播报
二、实现思路
首先我们需要准备 零、壹、贰、叁、肆、伍、陆、柒、捌、玖、拾、佰、仟、万、亿、元、角、分、整
的.wav格式的语音文件。然后通过WINMM.dll
外部动态库的sandPlaySoundA
()和waveOutGetNumDevs()
联合起来播放语音文件
三、创建程序基本框架
① 新建examplework
工作区
② 新建exampleapp
应用
③ 新建w_main
窗口,将其Title
属性值设置成“朗读款项金额”
由于篇幅原因,以上步骤这儿就不展开了,忘记了的小伙伴翻一翻该系列文章的第一篇
④ 在w_main
窗口上放置控件
在窗口上添加3个StaticEdit
控件,1个singleLineEdit
控件和2个CommandButton
。将其分别命名为st_1
、st_2
、st_3
sle_1
、sle_2
、cb_1
和cb_2
。 调整各个控件布局后如下
⑤ 保存窗口
四、编写代码
① 定义本地外部扩展函数
在w_main
的Declare Local External Function
选项卡中添加如下代码
Function boolean sndPlaySoundA(string SoundName, uint Flags) Library "WINMM.DLL"
Function uint waveOutGetNumDevs ()Library "WINMM.DLL"
② 在W_main
窗口的Function List
选项卡中添加Playsound(string as_filename,integer ai_option) return integer
函数
代码如下
uint lui_numdevslui_numdevs = WaveOutGetNumDevs()
If lui_numdevs > 0 Then sndPlaySoundA(as_filename,ai_option)return 1
Elsereturn -1
End If
③ 在w_main
窗口的Function List
选项卡中添加xx2dx(decimal ls) return string
函数
代码如下
string dx_sz,dx_dw,str_int,str_dec,dx_str,fu,a,b,b2,c,d,result
long num_int,num_dec,len_int,i,a_int,ppdx_sz = "零壹贰叁肆伍陆柒捌玖"
dx_dw = "万仟佰拾亿仟佰拾万仟佰拾元" //处理小于零情况
if ls<0 thenls = ls*(-1) fu = "负"
else fu = ""
end if //取得整数及整数串
dx_str = string(ls)
if (ls>0) and (ls<1) then dx_str = "0"+dx_str
pp = pos(dx_str,".")
if pp>0 then str_int = mid(dx_str,1,pos(dx_str,".")-1)
elsestr_int = dx_str
end if
num_int = long(str_int) //取得小数及小数串
if (ls>0) and (ls<1) then num_dec = ls * 100
elsenum_dec = (ls - num_int) * 100
end if
str_dec = string(num_dec)
len_int = len(str_int)
dx_str = "" //转换整整部分
for i = 1 to len_int //a为小写数字字符,b为对应的大写字符,c为对应大写单位,d为当前大写字符串的最后一个汉字a= mid(str_int,i,1) a_int = long(a) b = mid(dx_sz,(a_int*2)+1,2) c = mid(dx_dw,((13 - len_int +i - 1)*2+1),2) if dx_str<>"" thend=mid(dx_str,len(dx_str)-1,2)elsed= "" end if if (b="零") and ((d="零") or (b=b2) or (c="元") or (c="万") or (c="亿")) then b = "" if (a="0") and (c<>"元") and (c<>"万") and (c<>"亿") then c="" if ((c="元") or (c="万") or (c="亿")) and (d="零") and (a="0") thendx_str = mid(dx_str,1,len(dx_str)-2) d=mid(dx_str,len(dx_str)-1,2) if ((c="元") and (d="万")) or ((c="万") and (d="亿")) then c = "" end if dx_str = dx_str + b+ c b2 = b
next//处理金额小于1的情况if len(dx_str) <= 2 then dx_str= "" //转换小数部分if (num_dec<10) and (ls>0) thena_int = long(str_dec) b = mid(dx_sz,(a_int*2+1),2) if num_dec = 0 then dx_str = dx_str + "整" if num_dec > 0 then dx_str = dx_str +"零"+b+"分" end ifif num_dec >= 10 thena_int = long(mid(str_dec,1,1)) a = mid(dx_sz,(a_int*2+1),2) a_int = long(mid(str_dec,2,1)) b = mid(dx_sz,(a_int*2+1),2) if a<>"零" then a = a+"角" if b <> "零" thenb = b+"分"else b= "" end ifdx_str = dx_str + a + b end ifif ls= 0 then dx_str = "零元整" dx_str = fu+dx_str result = dx_str return result
④ 将事先准备好的.wav格式声音放到项目temp目录下
语音包小凡已经上传的百度网盘了,需要的小伙伴自行下载哈
链接:https://pan.baidu.com/s/17sPGYC21fvzw4ebgXll74A?pwd=8888
提取码:8888
⑤在w_main
窗口的cb_1
按钮的Clicked
事件 中添加如下代码
integer i,count
string ls_current_path
//获取项目当前路径
ls_current_path = GetCurrentDirectory()st_3.text = xx2dx(dec(sle_1.text))count = len(st_3.text)for i= 1 to count step 2CHOOSE CASE mid(st_3.text,i,2)CASE "零"playsound(ls_current_path+"\temp\0.wav",0) CASE "壹"playsound(ls_current_path+"\temp\1.wav",0) CASE "贰"playsound(ls_current_path+"\temp\2.wav",0) CASE "叁"playsound(ls_current_path+"\temp\3.wav",0) CASE "肆"playsound(ls_current_path+"\temp\4.wav",0) CASE "伍"playsound(ls_current_path+"\temp\5.wav",0) CASE "陆"playsound(ls_current_path+"\temp\6.wav",0) CASE "柒"playsound(ls_current_path+"\temp\7.wav",0) CASE "捌"playsound(ls_current_path+"\temp\8.wav",0) CASE "玖"playsound(ls_current_path+"\temp\9.wav",0) CASE "拾"playsound(ls_current_path+"\temp\十.wav",0) CASE "佰"playsound(ls_current_path+"\temp\佰.wav",0) CASE "仟"playsound(ls_current_path+"\temp\仟.wav",0) CASE "万"playsound(ls_current_path+"\temp\万.wav",0) CASE "亿"playsound(ls_current_path+"\temp\亿.wav",0) CASE "元"playsound(ls_current_path+"\temp\元.wav",0) CASE "角"playsound(ls_current_path+"\temp\角.wav",0) CASE "分"playsound(ls_current_path+"\temp\分.wav",0) CASE "整"playsound(ls_current_path+"\temp\整.wav",0) END CHOOSE
next
⑥ 在cb_2
退出按钮的Clicked
事件中添加如下代码
close(parent)
⑦ 在开发界面左边的System Tree
窗口中双击exampleapp
应用对象,并在其Open
事件中添加如下代码
open(w_main)
五、运行程序
代码写完了,来检验下我们的劳动成果。
金额语音播报
本期内容到这儿就结束了 ,★,°:.☆( ̄▽ ̄)/$:.°★ 。希望对您有所帮助
我们下期再见 ヾ(•ω•`)o (●’◡’●)
相关文章:

【PB案例学习笔记】-22制作一个语音朗读金额小应用
写在前面 这是PB案例学习笔记系列文章的第22篇,该系列文章适合具有一定PB基础的读者。 通过一个个由浅入深的编程实战案例学习,提高编程技巧,以保证小伙伴们能应付公司的各种开发需求。 文章中设计到的源码,小凡都上传到了gite…...
glmark2代码阅读总结
glmark2代码阅读总结 一、总体 用输入参数生成testbench项用scene和benchmark管理进行复用通过类的重载,创建出不同的分支和具体的实现点,如scene和mainloop类用例执行又规划,每个scene都统一有setup,等使用scene的继承关系&…...
第 6 章 监控系统 | 监控套路 - 总结
前面,我们使用 Prometheus + Grafana + Node Exporter 实现虚拟机监控及告警。 那么,😇 监控的套路究竟是什么呢? 第 1 步:暴露 metrics,通过某个 exporter 将 metrics 暴露出来第 2 步:配置 Prometheus 抓取上面暴露的 metrics 数据第 3 步:加速 metrics 显示,配置…...

VsCode中C文件调用其他C文件函数失败
之前一直使用CodeBlocks,最近使用vscode多,感觉它比较方便,但在调用其他C文件的时候发现报错以下内容基于单C文件运行成功,否则请移步 博文:VSCode上搭建C/C开发环境 报错信息 没有使用CodeRunner插件,弹…...
css中content属性你了解多少?
在CSS中,content属性通常与伪元素(如 ::before 和 ::after)一起使用,用于在元素的内容之前或之后插入生成的内容。这个属性不接受常规的HTML内容,而是接受一些特定的值,如字符串、属性值、计数器值等。 以…...
JVM-GC-G1垃圾回收器
JVM-GC-G1垃圾回收器 基本概念 card table card table概念是为了解决新生代对象进入老年代时,在进行新生代扫描的时候会遍历老年代对象的问题。将内存分为多个card,如果在一个老年代card中存在引用新生代对象的对象,则将该区域标记及为dirty card。 CS…...

【Ubuntu通用压力测试】Ubuntu16.04 CPU压力测试
使用 stress 对CPU进行压力测试 我也是一个ubuntu初学者,分享是Linux的优良美德。写的不好请大佬不要喷,多谢支持。 sudo apt-get update 日常先更新再安装东西不容易出错 sudo apt-get upgrade -y 继续升级一波 sudo apt-get install -y linux-tools…...
Artix Linux 默认不使用 systemd
开发者选择不使用systemd,而倾向于使用OpenRC或runit作为其初始化系统的原因。 哲学和设计原则:Systemd是一个功能丰富的初始化系统和系统管理器,它集成了许多功能,但这也导致它的设计哲学与一些用户或开发者的偏好不符。有些用户…...
JVM-GC-CMS垃圾回收器
JVM-CMS垃圾回收器 CMS垃圾回收的步骤 1. 初始标记(InitialMarking) 这是一个STW的过程,并行标记,只是标记GC Roots能直接关联到的对象。由于GC Root直接关联的对象少,因此STW时间比较短。 2. 并发标记 非STW的过程&…...
【玩转google云】实战:如何在GKE上使用Helm安装和配置3节点的RabbitMQ集群
需求 因项目需要需要在Google Kubernetes Engine (GKE) 中使用Helm安装一个3节点的RabbitMQ集群,配置用户名和密码,开通公网访问的Web管理界面,指定namespace为mq,并使用5G的硬盘存储MQ的数据。 前提条件 GKE集群:确保你有一个运行中的GKE集群。Helm工具:确保已安装Hel…...
【神经网络】深度神经网络
深度神经网络(Deep Neural Network,简称DNN)是一种模仿人脑神经网络结构和工作原理的机器学习模型。它通过层级化的特征学习和权重调节,能够实现复杂任务的高性能解决方案。深度神经网络由多个神经元层组成,每个神经元…...
机器学习算法 —— K近邻(KNN分类)
🌟欢迎来到 我的博客 —— 探索技术的无限可能! 🌟博客的简介(文章目录) 目录 KNN的介绍和应用KNN的介绍1) KNN建立过程2) 类别的判定KNN的优点KNN的缺点KNN的应用实战KNN分类数据集 —— KNN分类库函数导入数据导入模型训练&可视化原理简析莺尾花数据集 —— KNN分…...

Thinkphp5内核流浪猫流浪狗宠物领养平台H5源码
Thinkphp5内核流浪猫流浪狗宠物领养平台H5源码 可封装APP,适合做猫狗宠物类的发信息发布,当然懂的修改一下,做其他信息发布也是可以的。 Thinkphp5内核流浪猫流浪狗宠物领养平台H5源码...
c++ 智能指针使用注意事项及解决方案
c11智能指针 shared_ptr介绍注意事项示例解决方案 weak_ptr特点示例 unique_ptr特点示例 shared_ptr 介绍 shared_ptr 是一种智能指针,用于自动管理动态分配的对象的生命周期。它通过引用计数机制来确保当最后一个 shared_ptr 指向一个对象时,该对象会…...
SQLite Delete 语句
SQLite Delete 语句 SQLite 的 DELETE 语句用于从表中删除数据。它是 SQL 数据库管理中非常基础且重要的操作之一。在使用 DELETE 语句时,可以删除表中的特定行,也可以删除整个表的数据。本文将详细介绍 SQLite 中的 DELETE 语句,包括其语法、用法以及如何安全地执行删除操…...

vue3的基本使用方法
【 vue3实例 】 【 0 】对象、方法和属性 对象(Object): 对象是编程中的一个数据结构,它可以包含多种数据类型,包括数字、字符串、布尔值、数组、其他对象等。对象通常由一系列属性和方法组成。在面向对象编程&…...
Java数据结构与算法(盛水的容器贪心算法)
前言 . - 力扣(LeetCode) 贪心算法(Greedy Algorithm)是一种在每一步选择中都采取当前状态下最优或最佳的选择,以期望通过一系列的局部最优选择达到全局最优解的算法。贪心算法的核心思想是贪心选择性质和最优子结构性质。 贪心算法的基本步骤 建立模型:将问题分解为一…...
MYSQL 数字(Aggregate)函数
目录 1、AVG() 2、MAX() 3、MIN() 4、SUM() 5、COUNT() 6、LIMIT() 1、AVG() 解释:返回数值列(字段)的平均值。 语法格式:SELECT AVG(column_name) FROM table_name 中文注释:select AVG(数值列/字段) from 表名 ; 用法࿱…...
【TensorFlow深度学习】如何处理不平衡数据集与欠采样、过采样技术
如何处理不平衡数据集与欠采样、过采样技术 如何处理不平衡数据集与欠采样、过采样技术:实现均衡学习的艺术1. 不平衡数据集的识别与评估2. 欠采样技术:减少多数类样本3. 过采样技术:增加少数类样本4. 集成采样策略:SMOTE +ENN 或 SMOTE +Tomek Links5. 评估与选择最佳策略…...

【考研数学】如何保证进度不掉队?暑假强化保姆级规划
数一125学长前来解答!一句话,跟对老师,抓基础,有计划的进行复习才是关键! 数学基础非常重要,包括高等数学、线性代数和概率论等基础知识点。要确保对这些基础知识有扎实的掌握。 按照教材的顺序ÿ…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...

循环冗余码校验CRC码 算法步骤+详细实例计算
通信过程:(白话解释) 我们将原始待发送的消息称为 M M M,依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)(意思就是 G ( x ) G(x) G(x) 是已知的)࿰…...

无法与IP建立连接,未能下载VSCode服务器
如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...

Python实现prophet 理论及参数优化
文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...

剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...

【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...

深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...