用emWin的2D绘图函数画一个带圆形端点的环形进度条

先上效果图,首先是顺时针转:

顺时针转

然后是逆时针转:

逆时针转

大概讲一下思路吧,首先讲一下顺时针是怎么弄的,很简单。

画圆弧函数GUI_DrawArc有起始角度a0和终止角度a1两个参数,且a0必须小于a1否则无法显示,而且这个函数的角度正方向又是逆时针的,这就容易造成一个误解,以为起始角度a0和终止角度a1的值只能从0°逆时针增加到360°这么一个变化,换句话说,在a0不变时通过增加a1的值可以让圆弧沿逆时针方向增长。

之前我也是这么认为的,但是通过测试发现,a0为负值也是能正常显示的,只要保证a0<a1。然后顺着上面的思路想了下,那可不可以不改变a1,通过减少a0的值实现圆弧沿顺时针方向增长呢?结果一测试发现果然可行。

啰里啰唆这么多其实就一句话:顺时针转,减起始角度a0;逆时针转,加终止角度a1。

/* 顺时针转,减起始角度 */
a0 = 90;
while(1)
{
    GUI_DrawArc(0, 0, 20, 20, a0, 90);
    a0 -= 1;
    if(a < -270)
    {
        a0 = 90;
    }
}

/* 逆时针转,加终止角度 */
a1 = 90;
while(1)
{
    GUI_DrawArc(0, 0, 20, 20, 90, a0);
    a0 += 1;
    if(a > 450)
    {
        a1 = 90;
    }
}

然后再来说一下圆形端点是怎么实现的,其实这个是从圆弧函数的官方例程里面找到的思路,就是那个画速度表盘的例程。例程代码我就不贴出来了,手册上都有的。也很简单,官方例程在圆弧旁边画了很多的圆形图案,这些圆形图案包括字符的坐标都是通过求圆上任意一点坐标的方法算出来的,只不过计算用的圆半径比画的圆弧小罢了。

我们直接用同样的方法把计算用的圆半径等于画的圆弧,即可求得圆形端点的坐标。

但是具体哪一点的坐标呢?其实分两种情况,一种是定点坐标,这个几乎可以说是已知的,你圆弧哪里不动就求哪里的坐标;另一种是动点坐标,这个就需要根据圆弧运动的一侧进行及时调整了。

不知道这样有没有讲明白,如果实在不懂的话还是直接看代码吧,可以到这个链接下载:分享一个用2D绘图函数做的带圆形端点的环形进度条 - GUI图形库 - 野火电子论坛 - Powered by Discuz!(出处: 野火电子论坛)

2022.04.16更新

最新的emwinv6.16版本有了官方的环形进度条,比我自己实现的好用,大家可以去试试。

可以在这里下载:

单片机版emWin6.16软件包来了,可以完美配合最新版AppWizard了
https://www.armbbs.cn/forum.php?mod=viewthread&tid=107080&fromuid=23005
(出处: 硬汉嵌入式论坛)

以下是使用emWin库实现环形进度条的案例详细代码: ```c #include "GUI.h" #include "DIALOG.h" /********************************************************************* * * Defines * ********************************************************************** */ #define ID_FRAMEWIN_0 (GUI_ID_USER + 0x00) #define ID_GRAPH_0 (GUI_ID_USER + 0x01) #define ID_BUTTON_0 (GUI_ID_USER + 0x02) #define ID_BUTTON_1 (GUI_ID_USER + 0x03) #define ID_BUTTON_2 (GUI_ID_USER + 0x04) #define ID_BUTTON_3 (GUI_ID_USER + 0x05) #define ID_BUTTON_4 (GUI_ID_USER + 0x06) #define ID_PROGBAR_0 (GUI_ID_USER + 0x07) #define PROGBAR_RADIUS 70 #define PROGBAR_WIDTH 20 /********************************************************************* * * Static data * ********************************************************************** */ static const GUI_POINT aPoints[] = { { 0, 0}, { 50, 0}, { 50, -50}, { 0, -50} }; static WM_HWIN _hGraph; static WM_HWIN _hProgBar; /********************************************************************* * * Static code * ********************************************************************** */ /********************************************************************* * * _cbBkWindow * ********************************************************************** */ static void _cbBkWindow(WM_MESSAGE * pMsg) { int NCode; int Id; switch (pMsg->MsgId) { case WM_NOTIFY_PARENT: Id = WM_GetId(pMsg->hWinSrc); /* Id of widget */ NCode = pMsg->Data.v; /* Notification code */ switch (Id) { case ID_BUTTON_0: /* React to clicks of the button */ if (NCode == WM_NOTIFICATION_CLICKED) { PROGBAR_SetValue(_hProgBar, PROGBAR_GetValue(_hProgBar) + 10); } break; case ID_BUTTON_1: /* React to clicks of the button */ if (NCode == WM_NOTIFICATION_CLICKED) { PROGBAR_SetValue(_hProgBar, PROGBAR_GetValue(_hProgBar) - 10); } break; case ID_BUTTON_2: /* React to clicks of the button */ if (NCode == WM_NOTIFICATION_CLICKED) { PROGBAR_SetValue(_hProgBar, 0); } break; case ID_BUTTON_3: /* React to clicks of the button */ if (NCode == WM_NOTIFICATION_CLICKED) { PROGBAR_SetValue(_hProgBar, 100); } break; case ID_BUTTON_4: /* React to clicks of the button */ if (NCode == WM_NOTIFICATION_CLICKED) { WM_DeleteWindow(pMsg->hWinSrc); } break; } break; default: WM_DefaultProc(pMsg); break; } } /********************************************************************* * * _cbGraph * ********************************************************************** */ static void _cbGraph(WM_MESSAGE * pMsg) { switch (pMsg->MsgId) { case WM_PAINT: GUI_SetColor(GUI_RED); GUI_AA_FillRoundedRect(0, 0, PROGBAR_RADIUS * 2, PROGBAR_RADIUS * 2, PROGBAR_RADIUS); GUI_SetColor(GUI_WHITE); GUI_AA_FillCircle(PROGBAR_RADIUS, PROGBAR_RADIUS, PROGBAR_RADIUS - PROGBAR_WIDTH); GUI_AA_DrawPolygon(&aPoints[0], GUI_COUNTOF(aPoints), PROGBAR_RADIUS, PROGBAR_RADIUS); break; default: WM_DefaultProc(pMsg); break; } } /********************************************************************* * * _cbProgBar * ********************************************************************** */ static void _cbProgBar(WM_MESSAGE * pMsg) { switch (pMsg->MsgId) { case WM_PAINT: GUI_SetColor(GUI_BLUE); GUI_AA_FillCircle(PROGBAR_RADIUS, PROGBAR_RADIUS, PROGBAR_RADIUS - PROGBAR_WIDTH); break; default: PROGBAR_Callback(pMsg); break; } } /********************************************************************* * * Public code * ********************************************************************** */ /********************************************************************* * * MainTask * ********************************************************************** */ void MainTask(void) { WM_HWIN hFrame; WM_HWIN hItem; int xPos; int yPos; GUI_Init(); WM_SetCallback(WM_HBKWIN, _cbBkWindow); hFrame = FRAMEWIN_CreateEx(10, 10, 300, 220, WM_HBKWIN, WM_CF_SHOW, 0, ID_FRAMEWIN_0, "emWin Progress Bar"); xPos = (WM_GetWindowSizeX(hFrame) - PROGBAR_RADIUS * 2) / 2; yPos = (WM_GetWindowSizeY(hFrame) - PROGBAR_RADIUS * 2) / 2; _hGraph = WM_GetDialogItem(hFrame, ID_GRAPH_0); GRAPH_SetUserDraw(_hGraph, _cbGraph); WM_SetSize(_hGraph, PROGBAR_RADIUS * 2, PROGBAR_RADIUS * 2); WM_MoveTo(_hGraph, xPos, yPos); _hProgBar = PROGBAR_CreateEx(xPos, yPos, PROGBAR_RADIUS * 2, PROGBAR_RADIUS * 2, hFrame, WM_CF_SHOW, PROGBAR_CF_HORIZONTAL, ID_PROGBAR_0); PROGBAR_SetMinMax(_hProgBar, 0, 100); PROGBAR_SetValue(_hProgBar, 50); WM_SetCallback(_hProgBar, _cbProgBar); hItem = BUTTON_CreateEx(40, 160, 30, 20, hFrame, WM_CF_SHOW, 0, ID_BUTTON_0); BUTTON_SetText(hItem, "+10"); hItem = BUTTON_CreateEx(90, 160, 30, 20, hFrame, WM_CF_SHOW, 0, ID_BUTTON_1); BUTTON_SetText(hItem, "-10"); hItem = BUTTON_CreateEx(140, 160, 30, 20, hFrame, WM_CF_SHOW, 0, ID_BUTTON_2); BUTTON_SetText(hItem, "0"); hItem = BUTTON_CreateEx(190, 160, 30, 20, hFrame, WM_CF_SHOW, 0, ID_BUTTON_3); BUTTON_SetText(hItem, "100"); hItem = BUTTON_CreateEx(240, 160, 30, 20, hFrame, WM_CF_SHOW, 0, ID_BUTTON_4); BUTTON_SetText(hItem, "Close"); while (1) { GUI_Delay(10); } } ``` 该代码使用了GUI库提供的GRAPH和PROGBAR控件,其中GRAPH控件用于绘制环形进度条的边框,PROGBAR控件用于显示进度条的进度。在主函数中创建了一个窗口,包含了GRAPH控件、PROGBAR控件和几个按钮控件。GRAPH控件使用了回调函数_cbGraph,自定义绘制了环形进度条的边框,PROGBAR控件使用了回调函数_cbProgBar,自定义绘制了进度条的进度。按钮控件用于增加、减少、清空和关闭进度条
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值