当前位置: 首页 > news >正文

【PB案例学习笔记】-13 徒手做个电子时钟

写在前面

这是PB案例学习笔记系列文章的第11篇,该系列文章适合具有一定PB基础的读者。

通过一个个由浅入深的编程实战案例学习,提高编程技巧,以保证小伙伴们能应付公司的各种开发需求。

文章中设计到的源码,小凡都上传到了gitee代码仓库https://gitee.com/xiezhr/pb-project-example.git

gitee代码仓库

需要源代码的小伙伴们可以自行下载查看,后续文章涉及到的案例代码也都会提交到这个仓库【pb-project-example

如果对小伙伴有所帮助,希望能给一个小星星⭐支持一下小凡。

一、小目标

上一篇中我们使用Timer时间制作了一个秒表,之后就有小伙伴问了,秒表都做了,能不能做个电子时钟呢?

当然可以了,这就安排上。这篇文章我们将使用到新的控件Oval来做一个钟表框,

利用Now()Hour()、Minute()Second()等日期时间函数将系统时间显示在文本框中;

利用Sin()Cos()Pi()等数学函数来来控制时针、分针、秒针实现下图所示的电子时钟;

利用WindowTimer时间让时钟走起来。最终实现下面的效果

电子时钟

二、时间日期函数

在之前的案例中我们并没有接触过日期时间函数,而这些函数在日常开发中也是使用比较频繁的。

现在我们来具体说说这些函数都是怎么用的。

函数名称返回值功能描述
DayInteger返回日期的天数值
DayNameString返回日期的星期值
DayNumberInteger返回日期为该周的第几天
DaysAfterLong返回两个日期的间隔天数
HourInteger返回时间的小时值
MinuteInteger返回时间的分钟值
MonthInteger返回日期的月份值
NowTime返回系统的当前时间
RelativeDateDate返回日期之后指定天数的日期
RelativeTimeTime返回指定时间前后指定秒数的时间
SecondInteger返回时间的秒数值
SecondAfterLOng返回两个时间的间隔秒数
TodayDate返回系统当前日期
YearInteger返回日期的年份

三、Oval控件简介

Oval控件是一种图形控件,用于在窗口或用户界面上绘制椭圆或圆形。

在这篇文章中我们就通过该控件绘制了一个表盘及各个时刻点

四、创建程序基本框架

① 建立examplework工作区

② 建立exampleapp应用

③ 新建w_main窗口,标题Title设置为电子时钟

以上步骤如果忘记的小伙伴可以翻一翻该系列的第一篇文章

④ 新建控件

w_main窗口中新建一个SingleLineEdit控件、13个Oval控件和4个StaticText控件和3个Line控件

SingleLineEdit控件用来显示数字时间,一个Oval控件用来做钟表盘,其他12个Oval控件指示小时位置,

4个StaticText分别显示3、6、9、12 四个小时数值,3个Line控件分别作为时针、分针和秒针

控件布局

⑤ 将上面画好的窗口保存为w_main

五、编写事件代码

① 定义全局变量

定义三个全局变量,分别表示小时、分钟、秒

long  l_hour, l_Min,l_Sec

② 在w_main窗口的open事件中添加如下代码

// 获取当前时间的秒数,并赋值给变量l_sec
l_sec = Second(Now())// 获取当前时间的分钟数,并赋值给变量l_Min
l_Min = Minute(Now())// 获取当前时间的小时数,并赋值给变量l_hour
l_hour = Hour(Now())// 如果小时数大于12,将小时数转换为12小时制
if l_hour > 12 thenl_hour = l_hour - 12
end if// 设置线条ln_1的起始Y坐标为ov_1对象的Y坐标加上ov_1高度的一半
ln_1.BeginY = ov_1.y + ov_1.height / 2// 设置线条ln_1的起始X坐标为ov_1对象的X坐标加上ov_1宽度的一半
ln_1.BeginX = ov_1.x + ov_1.width / 2// 计算线条ln_1的结束Y坐标,基于当前秒数和角度45度,使用正弦函数
ln_1.EndY = ln_1.BeginY + 580 * Sin(Pi(l_sec + 45) / 30)// 计算线条ln_1的结束X坐标,基于当前秒数和角度45度,使用余弦函数
ln_1.EndX = ln_1.BeginX + 580 * Cos(Pi(l_sec + 45) / 30)// 设置线条ln_2的起始X和Y坐标与ln_1相同
ln_2.BeginX = ln_1.BeginX
ln_2.BeginY = ln_1.BeginY// 计算线条ln_2的结束X坐标,基于当前分钟数和角度45度,使用正弦函数
ln_2.EndX = ln_2.BeginX + 550 * Sin(Pi(l_Min + 45) / 30)// 计算线条ln_2的结束Y坐标,基于当前分钟数和角度45度,使用余弦函数
ln_2.EndY = ln_2.BeginY + 550 * Cos(Pi(l_Min + 45) / 30)// 设置线条ln_3的起始X和Y坐标与ln_1相同
ln_3.BeginX = ln_1.BeginX
ln_3.BeginY = ln_1.BeginY// 计算线条ln_3的结束X坐标,基于12小时制的小时数、分钟数和角度,使用正弦函数
ln_3.EndX = ln_3.BeginX + 520 * Sin(Pi(((12 - l_hour) * 60 - l_Min - 360) / 360))// 计算线条ln_3的结束Y坐标,基于12小时制的小时数、分钟数和角度,使用余弦函数
ln_3.EndY = ln_3.BeginY + 520 * Cos(Pi(((12 - l_hour) * 60 - l_Min - 360) / 360))// 调用定时器,通常会触发周期性执行这段代码
Timer(1)

③ 在w_main窗口的Timer事件中添加如下代码

// 声明一个time类型变量t_now,用于存储当前时间
time t_now// 获取当前系统时间,并赋值给t_now
t_now = Now()// 提取当前时间的小时数,并赋值给整型变量l_hour
l_hour = Hour(t_now)// 提取当前时间的分钟数,并赋值给整型变量l_min
l_min = Minute(t_now)// 提取当前时间的秒数,并赋值给整型变量l_sec
l_sec = Second(t_now)// 如果小时数大于12,将小时数转换为12小时制
if l_hour > 12 thenl_hour = l_hour - 12
end if// 将当前时间t_now转换为字符串,并设置滑块sle_1的文本
sle_1.text = String(t_now)// 更新线条ln_1的结束Y坐标,基于当前秒数和角度45度,使用正弦函数
ln_1.EndY = ln_1.BeginY + 580 * Sin(Pi((l_Sec + 45) / 30))// 更新线条ln_1的结束X坐标,基于当前秒数和角度45度,使用余弦函数
ln_1.EndX = ln_1.BeginX + 580 * Cos(Pi((l_Sec + 45) / 30))// 更新线条ln_2的结束Y坐标,基于当前分钟数和角度45度,使用正弦函数
ln_2.EndY = ln_2.BeginY + 550 * Sin(Pi((l_Min + 45) / 30))// 更新线条ln_2的结束X坐标,基于当前分钟数和角度45度,使用余弦函数
ln_2.EndX = ln_2.BeginX + 550 * Cos(Pi((l_Min + 45) / 30))// 更新线条ln_3的结束X坐标,基于12小时制的小时数、分钟数和角度,使用正弦函数
ln_3.EndX = ln_3.BeginX + 520 * Sin(Pi(((12 - l_hour) * 60 - l_Min - 360) / 360))// 更新线条ln_3的结束Y坐标,基于12小时制的小时数、分钟数和角度,使用余弦函数
ln_3.EndY = ln_3.BeginY + 520 * Cos(Pi(((12 - l_hour) * 60 - l_Min - 360) / 360))

③ 在开发界面左边的System Tree窗口中双击exampleApp应用对象,并在其open事件中添加如下代码

open(w_main)

六、运行程序

到此大功告成了,一个简单的电子时钟基本完成了,我们来看看能不能达到我们预期的效果

电子时钟最终效果

本期内容到这儿就结束了,希望对您有所帮助★,°:.☆( ̄▽ ̄)/$:.°★

我们下期再见 ヾ(•ω•`)o (●’◡’●)

相关文章:

【PB案例学习笔记】-13 徒手做个电子时钟

写在前面 这是PB案例学习笔记系列文章的第11篇,该系列文章适合具有一定PB基础的读者。 通过一个个由浅入深的编程实战案例学习,提高编程技巧,以保证小伙伴们能应付公司的各种开发需求。 文章中设计到的源码,小凡都上传到了gite…...

Java多线程——线程强制执行

Join合并线程&#xff0c;待此线程执行完成后&#xff0c;再执行其他线程&#xff0c;其他线程阻塞。 可以想象成插队。 代码演示&#xff1a; //测试Join方法 //想象为插队 public class TestJoin implements Runnable{Overridepublic void run() {for (int i 0; i < 1…...

虹科Pico汽车示波器 | 免拆诊断案例 | 2017款奔驰E300L车行驶中发动机偶尔无法加速

故障现象 一辆2017款奔驰E300L车&#xff0c;搭载274 920发动机&#xff0c;累计行驶里程约为21万km。车主反映&#xff0c;该车行驶中发动机偶尔无法加速&#xff0c;且车辆发闯。 故障诊断 用故障检测仪检测&#xff0c;发动机控制单元&#xff08;N3/10&#xff09;中存储…...

华发股份:加强业务协同 新政下项目热销

“5.17”楼市政策出台后&#xff0c;各地密集落地执行。5月27—28日&#xff0c;上海、广州、深圳三个一线城市跟进落地“517”新政。上海发布《关于优化本市房地产市场平稳健康发展政策措施的通知》&#xff0c;共计9条调整政策&#xff0c;涵盖外地户籍、人才、单身、婚否、企…...

RedHat9网络配置设计

目录 一、实验目的 二、实验过程 1、配置新网络接口 2、多网卡配置网络 3、网络接口的绑定&#xff0c;进行远程访问 4、配置网络接口的组合 一、实验目的 本次实验的目的是使用nmcli命令工具配置网络&#xff0c;ens160配置多个网卡&#xff0c;进行网络接口的绑定与组合…...

HDR视频相关标准-HDR vivid(二)

上文介绍了HDRvivid的一些技术。今天从全局角度来看看HDR视频的处理流程&#xff0c;HDR视频系统&#xff0c;即建立一个比SDR视频更大的色彩/亮度坐标体系&#xff0c;并改变系统的传输函数&#xff0c;以再现更大的色域(WCG)和更高的亮度动态范围。 菁彩 HDR技术的专业术语 …...

uniapp或微信小程序一些问题解决

1.按钮边框如何去除&#xff1f; 参考博主&#xff1a;微信小程序按钮去不掉边框_微信小程序button去掉边框-CSDN博客文章浏览阅读1k次。最近在学uni-app&#xff0c;顺便自己写个小程序。左上角放了个button&#xff0c;可边框怎么也去不掉…原来微信小程序的按钮要去掉边框要…...

最长递增子序列,交错字符串

第一题&#xff1a; 代码如下&#xff1a; int lengthOfLIS(vector<int>& nums) {//dp[i]表示以第i个元素为结尾的最长子序列的长度int n nums.size();int res 1;vector<int> dp(n, 1);for (int i 1; i < n; i){for (int j 0; j < i; j){if (nums[i]…...

力扣:344. 反转字符串

344. 反转字符串 编写一个函数&#xff0c;其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。 不要给另外的数组分配额外的空间&#xff0c;你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。 示例 1&#xff1a; 输入&#xff1a;s ["…...

linux Inodes满导致数据库宕机

项目经理反馈集群环境中有个节点无法使用了需要支援下&#xff0c;同时发过来截图说明磁盘还是有空的。 登录系统后直接发现问题 orcl2:/home/oracledb2> sqlplus / as sysdba SQL*Plus: Release 11.2.0.4.0 Production on Wed May 29 13:59:21 2024 Copyright (c) 1982,…...

【STL】C++ stack(栈) 基本使用

目录 一 stack常见构造 1 空容器构造函数&#xff08;默认构造函数&#xff09; 2. 使用指定容器构造 3 拷贝构造函数 二 其他操作 1 empty 2 size 3 top 4 push && pop 5 emplace 6 swap 三 总结 一 stack常见构造 1 空容器构造函数&#xff08;默认构造…...

轻量级 K8S 环境 安装minikube

文章目录 操作系统DockerDocker CE 镜像源站使用官方安装脚本自动安装 &#xff08;仅适用于公网环境&#xff09;安装校验Docker代理docker permission denied while trying to connect to the Docker daemon socket minikubekubectl工具minikube dashboardminikube 基本命令参…...

市场巨变,移动开发行业即将迎来“第二春”?

随着鸿蒙生态的不断壮大&#xff0c;越来越多的企业开始加入其中&#xff0c;对鸿蒙OS开发工程师的需求也越来越迫切。 年初时还只有200个APP宣布加入鸿蒙生态&#xff0c;而最近华为也已经官宣&#xff0c;已经有4000多个应用加入鸿蒙&#xff0c;短短三个月就增加了20倍。 …...

DependencyCheck工具使用

1、工具下载地址 Releases jeremylong/DependencyCheck GitHub 2、工具使用 ./dependency-check.sh --disableRetireJS --disableNodeJS --project test -s /test/ -o /home/clog/test/report10 --noupdate...

oracle翻页查询的小坑记录

oracle的查询&#xff0c;因为能获取到查询结果的rownum&#xff0c;就想着直接在查询条件后面做翻页&#xff0c;而且首页确实是正常查询到了。后面才发现翻页是空的。。。 这是因为rownum排序是在查询结果才分配的。所以应该把查询结果作为子查询&#xff0c;在外查询应用排序…...

学习笔记——动态路由协议——OSPF(OSPF基本术语)

OSPF基本术语 1、链路状态(LS)与链路状态通告(LSA) 链路(LINK)&#xff1a;路由器上的一个接口。 状态(State)&#xff1a;描述接口以及其与邻居路由器之间的关系。 (1)链路状态(LS) OSPF是一种链路状态协议&#xff0c;所谓的链路状态&#xff0c;其实就是路由器的接口状态…...

子集和问题(回溯法)

目录 ​​​​ 前言 一、算法思路 二、分析过程 三、代码实现 伪代码&#xff1a; C&#xff1a; 总结 前言 【问题描述】考虑定义如下的PARTITION问题中的一个变型。给定一个n个整数的集合X{x1,x2,…,xn}和整数y&#xff0c;找出和等于y的X的子集Y。 一、算法思路 基本思想&am…...

【NumPy】全面解析arange函数:高效创建数值范围数组

&#x1f9d1; 博主简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟&#xff0c;欢迎关注。提供嵌入式方向…...

[ C++ ] 深入理解模板( 初 阶 )

函数模板 函数模板格式 template <typename T1, typename T2,......,typename Tn> 返回值类型 函数名(参数列表){} 注意&#xff1a; typename是用来定义模板参数关键字&#xff0c;也可以使用class(切记&#xff1a;不能使用struct代替class) 函数模板的实例化 模板参数…...

UI自动化测试最佳设计模式POM

当使用Selenium进行UI自动化测试时&#xff0c;Page Object Model&#xff08;POM&#xff09;是一种最佳实践的设计模式。POM的核心思想是通过将页面封装成对象&#xff0c;使得测试代码更加清晰、可维护和可重用。 POM的主要组成部分包括页面对象类、元素定位方式和操作方法…...

iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘

美国西海岸的夏天&#xff0c;再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至&#xff0c;这不仅是开发者的盛宴&#xff0c;更是全球数亿苹果用户翘首以盼的科技春晚。今年&#xff0c;苹果依旧为我们带来了全家桶式的系统更新&#xff0c;包括 iOS 26、iPadOS 26…...

CentOS下的分布式内存计算Spark环境部署

一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架&#xff0c;相比 MapReduce 具有以下核心优势&#xff1a; 内存计算&#xff1a;数据可常驻内存&#xff0c;迭代计算性能提升 10-100 倍&#xff08;文档段落&#xff1a;3-79…...

页面渲染流程与性能优化

页面渲染流程与性能优化详解&#xff08;完整版&#xff09; 一、现代浏览器渲染流程&#xff08;详细说明&#xff09; 1. 构建DOM树 浏览器接收到HTML文档后&#xff0c;会逐步解析并构建DOM&#xff08;Document Object Model&#xff09;树。具体过程如下&#xff1a; (…...

HTML前端开发:JavaScript 常用事件详解

作为前端开发的核心&#xff0c;JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例&#xff1a; 1. onclick - 点击事件 当元素被单击时触发&#xff08;左键点击&#xff09; button.onclick function() {alert("按钮被点击了&#xff01;&…...

今日科技热点速览

&#x1f525; 今日科技热点速览 &#x1f3ae; 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售&#xff0c;主打更强图形性能与沉浸式体验&#xff0c;支持多模态交互&#xff0c;受到全球玩家热捧 。 &#x1f916; 人工智能持续突破 DeepSeek-R1&…...

JS设计模式(4):观察者模式

JS设计模式(4):观察者模式 一、引入 在开发中&#xff0c;我们经常会遇到这样的场景&#xff1a;一个对象的状态变化需要自动通知其他对象&#xff0c;比如&#xff1a; 电商平台中&#xff0c;商品库存变化时需要通知所有订阅该商品的用户&#xff1b;新闻网站中&#xff0…...

CSS | transition 和 transform的用处和区别

省流总结&#xff1a; transform用于变换/变形&#xff0c;transition是动画控制器 transform 用来对元素进行变形&#xff0c;常见的操作如下&#xff0c;它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...

React从基础入门到高级实战:React 实战项目 - 项目五:微前端与模块化架构

React 实战项目&#xff1a;微前端与模块化架构 欢迎来到 React 开发教程专栏 的第 30 篇&#xff01;在前 29 篇文章中&#xff0c;我们从 React 的基础概念逐步深入到高级技巧&#xff0c;涵盖了组件设计、状态管理、路由配置、性能优化和企业级应用等核心内容。这一次&…...

C++--string的模拟实现

一,引言 string的模拟实现是只对string对象中给的主要功能经行模拟实现&#xff0c;其目的是加强对string的底层了解&#xff0c;以便于在以后的学习或者工作中更加熟练的使用string。本文中的代码仅供参考并不唯一。 二,默认成员函数 string主要有三个成员变量&#xff0c;…...

电脑桌面太单调,用Python写一个桌面小宠物应用。

下面是一个使用Python创建的简单桌面小宠物应用。这个小宠物会在桌面上游荡&#xff0c;可以响应鼠标点击&#xff0c;并且有简单的动画效果。 import tkinter as tk import random import time from PIL import Image, ImageTk import os import sysclass DesktopPet:def __i…...