开源的嵌入式gGUI使用
gGUI是专门为资源紧缺的嵌入式系统设计的GUI库,不需要动态申请内存,占用内存极小(1KB以内也可以运行),运行速度快。
开源库:https://gitee.com/understanding-the-k8s-network/gGUI
codeblocks编译器下载:https://www.codeblocks.org/downloads/
我在原始的codeblocks编译器基础上增加了代码着色,代码显示类似sourceInsight,需要的可以自行下载,地址:https://download.csdn.net/download/hanpsbec/90468052
介绍
gGUI是专门为资源紧缺的嵌入式系统设计的GUI库,不需要动态申请内存,占用内存极小(1KB以内也可以运行),运行速度快。
gGUI界面采用类似Windows10的风格,下面是通过模拟器的运行界面:

gGUI目前提供的控件数量有限(后续有需求再增加),控件界面如下:

工程说明
工程整体代码结构:
| fonts.dat // 字体文件
| gui.cpp // gui主代码
| gui.h // gui头文件
| lcdDriver.h // lcd驱动头文件
├─image // 文档中的图像文件
├─samples
│ ├─GUISamples // 测试样例代码
│ │ └─LibSimuLCD
│ └─Template // 样例模板代码
└─simulator // 模拟器
├─simuLCDApp // PC版的LCD模拟器
│ └─res
└─simuLCDLib // 模拟器接口库
模拟器
本工程提供了LCD模拟器,位于 simulator 目录下,用户可以在PC机上完成界面设计,复制到嵌入式工程中即可以直接使用。
simuLCDApp 使用 VC6.0 编译器,非常古老的工程。
simuLCDLib 使用 Codeblocks + GCC 编译器,生成连接LCD APP的库代码。
模拟器运行界面如下:

用户工程
GUI库自身只有4个文件:
| fonts.dat // 字体文件
| gui.cpp // gui主代码
| gui.h // gui头文件
| lcdDriver.h // lcd驱动头文件
用户需要实现:
- 创建头文件 guiConfig.h:用于配置LCD显示屏的大小;
- 实现 samples/Template/lcdDriver.cpp 文件中的函数。
guiConfig.h 定义LCD显示屏大小,范例:
#ifndef _GUI_CONFIG_H
#define _GUI_CONFIG_H
#define LCD_WIDTH 240
#define LCD_HEIGHT 240
#endif // header guard
用户需要实现 samples/Template/lcdDriver.cpp 中如下5个函数,其中3个必选,2个可选:
void lcdInit(void)
{
}
void lcdDrawPoint(uint16_t x, uint16_t y, GColor color)
{
}
void lcdFillRect(uint16_t xstart, uint16_t ystart, uint16_t width, uint16_t height, GColor color)
{
}
/* 下面两个函数可选,如果硬件支持此功能,建议实现,这样可以提高操作效率 */
/*
void lcdSetRect(uint16_t xstart, uint16_t ystart, uint16_t width, uint16_t height)
{
}
void lcdWriteSeq(GColor color)
{
}
*/
示例工程代码解析
初始化
第一块是初始化代码,分别调用guiInit函数执行初始化,然后调用guiSetSysFont和guiSetSysFontHZ函数分别注册英文字库和汉字字库,最后显示屏清零:
int main()
{
printf("启动...\n");
guiInit();
guiSetSysFont(&sysfont_8x16);
guiSetSysFontHZ(&hzFont16);
lcdClear(C_BLACK);
接下来进入GUI测试界面,程序代码如下:
void guiTest()
{
GMainWND mainWin;
mainWin.init();
mainWin.showModal();
}
说明:
- 创建一个
GMainWND对象,并执行初始化; - 调用
showModal方法,显示该窗口。
主窗口类
初始化控件
GMainWND为主窗口类,该窗口上创建了很多的控件,在GMainWND的构造函数中对这些控件进行初始化:
class GMainWND : public GWND {
public:
GMainWND() :
GWND(NULL, GWID_WND_1, 0, 0, 240, 240, WND_CONFIG_Border|WND_CONFIG_TitleBar, "Main Window"),
myMenu(this),
stTitle0(this, GWID_STATICTEXT, 2, PowerSettingUI_Y_Line1, 116, 24, "中文字体"),
btVersion(this, GWID_Button_1, 120, PowerSettingUI_Y_Line1, 116, 24, "版本号"),
stTitle1(this, GWID_STATICTEXT, 2, PowerSettingUI_Y_Line2, 116, 24, "CheckBox"),
ckCheck(this, GWID_CheckBox_0, 120, PowerSettingUI_Y_Line2, 116, 24, "Check Me", 1),
stTitle2(this, GWID_STATICTEXT, 2, PowerSettingUI_Y_Line3, 116, 24, "Digit Text"),
tcDigit(this, GWID_TEXTCTRL_0, 120, PowerSettingUI_Y_Line3, 116, 24, 10, 1, 1, 100),
stTitle3(this, GWID_STATICTEXT, 2, PowerSettingUI_Y_Line4, 116, 24, "Digit Select"),
tcDSel(this, GWID_TEXTCTRL_1, 120, PowerSettingUI_Y_Line4, 116, 24, 123456, 1, 1, 999999),
stTitle4(this, GWID_STATICTEXT, 2, PowerSettingUI_Y_Line5, 116, 24, "ComboBox"),
cbBox(this, GWID_ComboBox_0, 120, PowerSettingUI_Y_Line5, 116, 24, pComboxValue, 3),
stTitle5(this, GWID_STATICTEXT, 2, PowerSettingUI_Y_Line6, 116, 24, "Menu"),
btMenu(this, GWID_Button_2, 120, PowerSettingUI_Y_Line6, 116, 24, "Menu Test"),
btExit(this, GWID_Button_9, 60, PowerSettingUI_Y_Line8, 120, 24, "Close")
{}
void init() {
myMenu.addItem(1, "SubMenu1");
myMenu.addItem(2, "SubMenu2");
myMenu.addItem(3, "SubMenu3");
myMenu.addItem(4, "SubMenu4");
myMenu.addItem(5, "SubMenu5");
myMenu.addItem(6, "SubMenu6");
myMenu.addItem(7, "SubMenu7");
}
private:
GMenu myMenu;
GStaticText stTitle0;
GButton btVersion;
GStaticText stTitle1;
GCheckBox ckCheck;
GStaticText stTitle2;
GTextCtrlDigit tcDigit;
GStaticText stTitle3;
GTextCtrlDigitSelect tcDSel;
GStaticText stTitle4;
GComboBox cbBox;
GStaticText stTitle5;
GButton btMenu;
GButton btExit;
DECLARE_EVENT_TABLE()
};
模拟器界面效果如下:

消息映射
gGUI采用了类似MFC的机制,支持消息映射表,用法如下:
class GMainWND : public GWND {
public:
...
void onEventbtVersion(GEvent& event) {
guiMessageBox("Version: 1.0", "Version");
}
void onEventcbCheck(GEvent& event) {
printf("Check box value = %d\n", event.para);
}
void onEventcComboBox(GEvent& event) {
printf("ComboBox Current selection = %d, old selection = %d\n", event.para&0xFFFF, event.para>>16);
}
void onEventbtMenu(GEvent& event) {
myMenu.popup(btMenu.getRectAbs().x, btMenu.getRectAbs().y);
}
void onMenu(GEvent& event) {
char buf[16];
guiMessageBox(guiFormat(buf, "menu %d selected", event.para), "MENU");
}
void onEventbtExit(GEvent& event) {
close();
}
private:
...
DECLARE_EVENT_TABLE()
};
BEGIN_EVENT_TABLE(GMainWND)
EVT_BUTTON(GWID_Button_1, &GMainWND::onEventbtVersion)
EVT_CHECKBOX(GWID_CheckBox_0, &GMainWND::onEventcbCheck)
EVT_COMBOBOX(GWID_ComboBox_0, &GMainWND::onEventcComboBox)
EVT_BUTTON(GWID_Button_2, &GMainWND::onEventbtMenu)
EVT_BUTTON(GWID_Button_9, &GMainWND::onEventbtExit)
EVT_MENU(&GMainWND::onMenu)
END_EVENT_TABLE(GMainWND)
类声明中增加 DECLARE_EVENT_TABLE,然后在实现文件中增加 BEGIN_EVENT_TABLE(GMainWND)和END_EVENT_TABLE(GMainWND),中间增加消息映射表。
不同类型的消息映射,event事件结构的定义也有不同,具体请参考gui.h头文件说明。
开源库地址
https://gitee.com/understanding-the-k8s-network/gGUI
openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。
更多推荐



所有评论(0)