【STM32H7S78-DK】手撸一个数字键盘
<div class='showpostmsg'> 本帖最后由 lugl4313820 于 2024-10-20 16:07 编辑<p>【前言】</p>
<p>touchgfx 是一个优秀的图形界面,在用户交互中,数字键盘非常重要,本篇是基于STM32H7S78的TouchGFX实现的一款数字键盘。</p>
<p>【开发工具】</p>
<p>TouchGFX Desiger 4.24.1</p>
<p>【开发步骤】</p>
<p>1、打开TouchGFX Desiger 新建一个基于STM32H7S78-DK的基础工程:</p>
<p> 2、新建一个自定义容器,命名为Keyboard:</p>
<p> 3、准备一张数字键盘的背景图片,将他放入工程目录:\KeyBoard\Appli\TouchGFX\assets\images之下。</p>
<p> 4、添加一张图片,图片指向这张背图片:</p>
<p> 5、添加一个box控件到1上面,并把透明度调到0。</p>
<p> 6、复制这个box,分别放到对应的数字键盘之上。并按下图所示重命名box的名称:</p>
<p> </p>
<p> 7、添加一个textArear到Keyboard界面,并按下图重命名为textNum,用于存放输出结果:</p>
<p> 8、钩选ClickListener,使能可以捕捉box的事件。</p>
<p> </p>
<p>9、在screen1的界面把这个keyboard添加进桌面。并同时添加两个box,用于捕捉按键,再添加两个textArea用于显示输入数据的结果。</p>
<p>10、添加OK按下后事件发送函数,实现与其他窗体的交互:</p>
<p> </p>
<p>11、生成工程后使用模拟器观察无误:</p>
<p> </p>
<p>【用户代码实现】</p>
<p>1、首先需要设定回调函数,以及将操作对象绑定到相应的控件上面。首先需要在keyboard.hpp文件中添加函数的声明,以及一些变量的声明,在KeyBoard.hpp上添加代码如下:</p>
<pre>
<code> virtual void ButtonClickHandle(const Box& box,const ClickEvent& evt);//
Callback<KeyBoard, const Box&, const ClickEvent&> ButtonCallBack;
int key_value;
uint8_t set_index;</code></pre>
<p>2、在Keyboard.cpp中添加实现回调函数的注册代码:</p>
<pre>
<code>KeyBoard::KeyBoard():
ButtonCallBack(this, &KeyBoard::ButtonClickHandle)
{
}
</code></pre>
<p>3、接下来我们来分析一下在这个回调函数里面我们需要做点什么,第一点,你需要判断是哪一个按键摁下,不同的按键有不同的事件处理机制,其次你还要将输入的键值显示在设定的input text上面,同时你还需要考虑怎么实现错误删除,以及清空等操作!其实现代码如下:</p>
<pre>
<code>
void KeyBoard::ButtonClickHandle(const Box& box,const ClickEvent& evt)
{
static uint8_t index;
static uint32_t num_value;
touchgfx::ClickEvent::ClickEventType type = evt.getType();
if(type == touchgfx::ClickEvent::PRESSED) //这里是判断事件类型,EVENT_CLICK属于点击事件
{
if(&box == &num1)
{
key_value = 1;
}else if(&box == &num2){
key_value = 2;
}else if(&box == &num3){
key_value = 3;
}else if(&box == &num4){
key_value = 4;
}else if(&box == &num5){
key_value = 5;
}else if(&box == &num6){
key_value = 6;
}else if(&box == &num7){
key_value = 7;
}else if(&box == &num8){
key_value = 8;
}else if(&box == &num9){
key_value = 9;
}else if(&box == &num0){
key_value = 0;
}else if(&box == &num_del){
key_value = -1;
}else if(&box == &num_ok){
key_value = -2;
}else if(&box == &num_cancel){
key_value = -3;
}else if(&box == &num_dot){
key_value = -5;
}
if(key_value >= 0){
if(index<5){
num_value =num_value*10 + key_value;
Unicode::snprintf(textNumBuffer, TEXTNUM_SIZE, "%d",num_value);
textNum.invalidate();
}
}else if(key_value == -1)
{
num_value = num_value/10;
Unicode::snprintf(textNumBuffer, TEXTNUM_SIZE, "%d",num_value);
textNum.invalidate();
}else if(key_value == -3)
{
num_value = 0;
Unicode::snprintf(textNumBuffer, TEXTNUM_SIZE, "%d",num_value);
textNum.invalidate();
}else if(key_value == -2)
{
emitKeyValueTransforCallback(num_value);
}
}
}
</code></pre>
<p>4、在初始时注册box的按下回调函数,代码如下:</p>
<pre>
<code>void KeyBoard::initialize()
{
KeyBoardBase::initialize();
num0.setClickAction(ButtonCallBack);
num1.setClickAction(ButtonCallBack);
num2.setClickAction(ButtonCallBack);
num3.setClickAction(ButtonCallBack);
num4.setClickAction(ButtonCallBack);
num5.setClickAction(ButtonCallBack);
num6.setClickAction(ButtonCallBack);
num7.setClickAction(ButtonCallBack);
num8.setClickAction(ButtonCallBack);
num9.setClickAction(ButtonCallBack);
num_del.setClickAction(ButtonCallBack);
num_ok.setClickAction(ButtonCallBack);
num_cancel.setClickAction(ButtonCallBack);
num_dot.setClickAction(ButtonCallBack);
}</code></pre>
<p>5、同样,在screenView.hpp中先定义虚拟函数与回调函数:</p>
<pre>
<code> virtual void ButtonClickHandle(const Box& box,const ClickEvent& evt);
Callback<KeyBoard, const Box&, const ClickEvent&> ButtonCallBack;
virtual void setValue(uint32_t value);</code></pre>
<p>6、在screen1View.cpp的类中注册回调函数:</p>
<pre>
<code>SettingScreenView::SettingScreenView():
ButtonCallBack(this, &SettingScreenView::ButtonClickHandle)
{
}</code></pre>
<p>7、把box的按键事在屏幕载入时注册好:</p>
<pre>
<code>void Screen1View::setupScreen()
{
Screen1ViewBase::setupScreen();
box2.setClickAction(ButtonCallBack);
box3.setClickAction(ButtonCallBack);
}</code></pre>
<p>8、添加按键回调函数的实现:</p>
<pre>
<code>void SettingScreenView::ButtonClickHandle(const Box& box,const ClickEvent& evt) {
touchgfx::ClickEvent::ClickEventType type = evt.getType();
if (type == touchgfx::ClickEvent::PRESSED)
{
if(&box == &box2)
{
keyBoard1.set_index = 1;
keyBoard1.moveTo(0,0);
}else if(&box == &box3)
{
keyBoard1.set_index = 2;
keyBoard1.moveTo(0,0);
}
}
}</code></pre>
<p>9、在TouchGFX Designer中注册一个接收KeyBoard的函数:</p>
<p> 10、在回调中,把返回的数据更新到指定的textArear中</p>
<pre>
<code>void SettingScreenView::setValue(uint32_t value)
{
if(keyBoard1.set_index == 1)
{
Unicode::snprintf(textArea1Buffer, 10, "%d", value);
keyBoard1.moveTo(0,500);
textArea1.invalidate();
}
else if(keyBoard1.set_index == 2)
{
Unicode::snprintf(textArea2Buffer, 10, "%d", value);
keyBoard1.moveTo(0,500);
textArea2.invalidate();
}
}</code></pre>
<p>【实现效果】</p>
<p>在摸拟器中运行,结果如下:</p>
<p> 视频效果如下:</p>
<p>b1836b1791d60462b31c487a99411b73<br />
附工程源码如下:</p>
<p><a href="https://download.eeworld.com.cn/detail/lugl4313820/634590">STM32H7S78-DK TouchGFX数字键盘-嵌入式开发相关资料下载-EEWORLD下载中心</a></p>
<p> </p>
</div><script> var loginstr = '<div class="locked">查看本帖全部内容,请<a href="javascript:;" style="color:#e60000" class="loginf">登录</a>或者<a href="https://bbs.eeworld.com.cn/member.php?mod=register_eeworld.php&action=wechat" style="color:#e60000" target="_blank">注册</a></div>';
if(parseInt(discuz_uid)==0){
(function($){
var postHeight = getTextHeight(400);
$(".showpostmsg").html($(".showpostmsg").html());
$(".showpostmsg").after(loginstr);
$(".showpostmsg").css({height:postHeight,overflow:"hidden"});
})(jQuery);
} </script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script> <p>咋样,计算上有没有bug</p>
Jacktang 发表于 2024-10-20 08:58
咋样,计算上有没有bug
<p>只做了界面,计算还没有弄,只是记录了一下数据交互。</p>
<p>好厉害啊</p>
jobszheng5 发表于 2024-10-22 23:44
好厉害啊
<p>感谢大佬的肯定,touchGFX的界面设计还是非常有想法的。</p>
<p>touchGFX 使用需要的资源多吗?STM32F207/407能不能用?</p>
inkinessray 发表于 2024-10-23 12:24
touchGFX 使用需要的资源多吗?STM32F207/407能不能用?
<p>都可以吧,资源小的不能驱动大屏。</p>
页:
[1]