快速入门
欢迎来到 LCUI 文档!本章节将介绍一些基础概念和用法,以帮助你快速入门。
你将会学习到:
- 如何创建应用程序
- 如何创建和嵌套组件
- 如何创建自定义组件
- 如何设置工作目录以让程序正确加载文件
- 如何调整布局
- 如何使用 XML 描述界面
- 如何对事件做出响应并更新界面
在你开始之前
本文档面向有开发经验的中级开发者,且具备以下条件:
- 熟练掌握 C 语言及构建工具链,能够解决常见的编译问题。
- 熟悉至少一个 GUI 开发库/框架,理解 GUI 应用程序工作原理。
- 了解 Web 开发技术,包括 HTML、CSS。
安装 LCUI
阅读《安装》文档。
创建应用程序
创建 main.c 文件,写入如下代码:
#include <LCUI.h>
#include <LCUI/main.h>
int main(int argc, char *argv[])
{
lcui_init();
return lcui_main();
}
这段代码比较简单,主要是包含头文件和调用函数,其作用具体如下:
- LCUI.h 是 LCUI 库的头文件。
- LCUI/main.h 是则是程序主入口的头文件,仅需由 main 函数所在的源文件包含,它 封装了各个平台的程序入口代码,使得 LCUI 应用程序能够统一用 main 函数作为入口。
- 调用
lcui_init()
初始化 LCUI 库的各项功能。 - 调用
lcui_main()
进入主循环,让应用程序保持运行状态并能够响应用户操作。
创建和嵌套组件
LCUI 应用程序的用户界面是由组件组成的。组件拥有自己的逻辑和外观,可以小到一个按钮,也可以大到整个页面。
接下来,我们将使用 text 组件来显示一段文本:
#include <LCUI.h>
#include <LCUI/main.h>
int main(int argc, char *argv[])
{
lcui_init();
ui_widget_t *text = ui_create_widget("text");
ui_text_set_content(text, "Welcome to my app");
ui_root_append(text);
return lcui_main();
}
在这段代码中我们创建了一个 text 类型的组件,将它的内容设置为 "Welcome to my app"
,然后追加到根组件中。
运行命令 xmake && xmake run
重新构建和运行它,你会看到这样的窗口:
在默认的显示模式下,根组件与主窗口绑定,它的尺寸、内容都会同步到主窗口,这意味着将组件追加到根组件内就能让它在窗口中显示。
创建自定义组件
LCUI 的组件基于原型来实现组件的抽象和继承,组件原型记录了组件的创建、销毁、绘制、估算尺寸等方法,通过创建组件原型然后修改这些方法即可创建你的自定义组件。
我们将添加一个名为 my-button
的自定义组件,它的表现形式是按钮,初始内容是 I'm a button
。
首先定义原型指针和注册函数:
ui_widget_prototype_t *my_button_proto;
void register_my_button(void)
{
my_button_proto = ui_create_widget_prototype("my-button", "text");
my_button_proto->init = my_button_init;
}
ui_create_widget_prototype()
用于创建组件原型,它参数分别是组件的类名和基类名。因为 my-button
组件需要用到文本显示能力,所以将第 二个参数设置为 "text"
以继承 text
组件。
然后定义初始化函数,在里面初始化基组件和自身内容:
void my_button_init(ui_widget_t *w)
{
my_button_proto->proto->init(w);
ui_text_set_content(w, "I'm a button");
}
最后,在主函数中注册和使用我们的自定义组件:
#include <LCUI.h>
#include <LCUI/main.h>
ui_widget_prototype_t *my_button_proto;
void my_button_init(ui_widget_t *w)
{
my_button_proto->proto->init(w);
ui_text_set_content(w, "I'm a button");
}
void register_my_button(void)
{
my_button_proto = ui_create_widget_prototype("my-button", "button");
my_button_proto->init = my_button_init;
}
int main(int argc, char *argv[])
{
lcui_init();
register_my_button();
ui_widget_t *text = ui_create_widget("text");
ui_text_set_content(text, "Welcome to my app");
ui_root_append(text);
ui_root_append(ui_create_widget("my-button"));
return lcui_main();
}
重新构建和运行它,你会看到如下的效果:
设置工作目录
接下来要让程序从外部加载资源文件。在代码中加载文件时指定的文件路径是相对路径,相对于工作目录,且会因程序的启动方式的不同而有所差异,例如:用 xmake run
命令启动、双击程序的可执行文件启动。因此,在加载文件前需手动设置工作目录。
在下面的例子中我们将 app 目录作为工作目录,需要用到 set_rundir()
函数:
add_rules("mode.debug", "mode.release")
includes("vendor/LCUI/xmake.lua")
target("myapp")
set_kind("binary")
add_deps("lcui")
add_files("src/*.c")
set_rundir("app")
这项配置只影响到以 xmake run
命令启动程序时的工作目录,你还需要额外编写代码根据 main()
函数的 argv 参数设置工作目录。
添加样式
LCUI 包含 CSS 解析和选择引擎,你可以使用一些简单的 CSS 规则来设置用户界面的视觉效果。
你将学会使用这几个函数:
ui_load_css_file()
:从文件中加载 CSS。ui_load_css_string()
:从字符串中加载 CSS。ui_widget_add_class()
:为组件设置类名,以应用对应类的 CSS 样式。
首先在工作目录内创建一个 css 文件,填入以下 CSS 规则:
root {
padding: 24px;
}
.title {
font-size: 24px;
font-weight: bold;
margin-bottom: 16px;
}
my-button {
display: inline-block;
padding: 4px 8px;
border: 1px solid #ddd;
border-radius: 4px;
background: #f4f4f4;
}
my-button:hover {
background: #eaeaea;
}
my-button:active {
background: #fbfbfb;
}
然后在 main()
函数中加载 CSS,再为 text 组件添加 title 类名。
int main(int argc, char *argv[])
{
lcui_init();
register_my_button();
ui_load_css_file("main.css");
ui_widget_t *text = ui_create_widget("text");
ui_text_set_content(text, "Welcome to my app");
ui_widget_add_class(text, "title");
ui_root_append(text);
ui_root_append(ui_create_widget("my-button"));
return lcui_main();
}
效果如下所示:
Welcome to my app
除了从文件中加载 CSS,你还可以从字符串中加载 CSS:
const char *css_str = "\
root {\
padding: 24px;\
}\
\
.title {\
font-size: 24px;\
font-weight: bold;\
margin-bottom: 16px;\
}\
my-button {\
padding: 4px 8px;\
border: 1px solid #ddd;\
border-radius: 4px;\
background: #f4f4f4;\
}\
my-button:hover {\
background: #eaeaea;\
}\
my-button:active {\
background: #fbfbfb;\
}";
int main(int argc, char *argv[])
{
lcui_init();
register_my_button();
ui_load_css_string(css_str, __FILE__);
ui_widget_t *text = ui_create_widget("text");
ui_text_set_content(text, "Welcome to my app");
ui_widget_add_class(text, "title");
ui_root_append(text);
ui_root_append(ui_create_widget("my-button"));
return lcui_main();
}
调整布局
LCUI 支持流式布局(Flow Layout)和弹性盒子布局(Flexible Box)两种布局,用法和效果与网页的布局相似,你可通过设置组件的 CSS display 属性来更改其布局行为。
以常见的垂直水平居中布局为例,我们可以使用弹性盒子布局来实现:
root {
padding: 24px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.title {
font-size: 24px;
font-weight: bold;
margin-bottom: 16px;
}