XUI是xboot内置的立即模式GUI框架,代码量很低,但功能绝对强大,所想即所得,无需各种设计器辅助,随心所欲敲你的代码,就行了,当你敲完了,UI开发工作就结束了。
离线
这个项目demo采用xboot的主线代码,感兴趣的可以研究,不要钱的,学到了,就是自己的了
https://github.com/xboot/xboot
离线
补充一下原始设计稿,不是贴图喔,上面的界面是纯代码实现。
离线
离线
发现是不是有点不一样,设计稿对于xui最大的意义,就是提供颜色尺寸等信息
离线
如果感兴趣的人多的话,我可以再讲讲XUI的细节,先说个概括性的。
GUI实现分为三种设计模式:
1,保留模式,传统GUI,都是使用此方案,优点是成熟,缺点是开发繁琐
2,立即模式,诞生于游戏开发领域,解决游戏交互,xui就采用此模式,此模式优点,是代码量低,所想所得,灵活性强1,编写事情响应得心应手,缺点是纯代码,驾驭不了代码的新手,会退避三分
3,声明式,这个在web领域,如火如荼,什么VUE啥的,很现代,优点是,效果赞,赏心锐目,而且现代,缺点是,需要脚本语言配合,而且需要描述能力稍强点的语言,再有就是性能需求也是较高。嵌入式裸奔系统或者各种rtos没有见到过有这种的。不知以后会不会有这玩意儿。
离线
前排听讲
离线
XUI里面没有任何回调函数,所有的事件响应都是 在if else 里面,是不是觉得不可以思议。来事件了,条件判断会自动转向
离线
https://gitee.com/xboot/xboot/blob/master/src/kernel/command/cmd-overview.c
这个链接,是一个测试demo,大部分控件,都展示了。
if(xui_begin_tree(ctx, "Normal Button"))
{
xui_layout_row(ctx, 3, (int[]){ 100, 100, -1 }, 40);
for(int i = 0; i < 8; i++)
{
xui_button_ex(ctx, 0, wcstr[i], (i << 8) | XUI_OPT_TEXT_CENTER);
}
xui_end_tree(ctx);
}
比如这段代码,就是如果点击了树形控件里面的Normal Button标题,则会自动创建8个按钮,每行3个,前2个100像素宽,40高,最后一个完全填充完剩余空间。
感觉是不是很神奇,这一点代码就可以做这么多事了。
离线
如果感兴趣的人多的话,我可以再讲讲XUI的细节,先说个概括性的。
GUI实现分为三种设计模式:
1,保留模式,传统GUI,都是使用此方案,优点是成熟,缺点是开发繁琐
2,立即模式,诞生于游戏开发领域,解决游戏交互,xui就采用此模式,此模式优点,是代码量低,所想所得,灵活性强1,编写事情响应得心应手,缺点是纯代码,驾驭不了代码的新手,会退避三分
3,声明式,这个在web领域,如火如荼,什么VUE啥的,很现代,优点是,效果赞,赏心锐目,而且现代,缺点是,需要脚本语言配合,而且需要描述能力稍强点的语言,再有就是性能需求也是较高。嵌入式裸奔系统或者各种rtos没有见到过有这种的。不知以后会不会有这玩意儿。
给力,说的很到位。VUE开发有的,叫有嵌入式的框架叫EVM的一直在搞这个。看上去很不错,后面现代ui应该是越来越多是声明式了。主要是配合设计工具特别好用。感觉AWTK也算是吧
离线
补充一下原始设计稿,不是贴图喔,上面的界面是纯代码实现。
不懂就问,这个设计辅助工具是什么
离线
问楼主,右边的白色方块是什么
离线
不错 刚好有个项目 可以试下
离线
问楼主,右边的白色方块是什么
串口wifi
离线
是的,乐鑫的wifi模块
离线
前排围观大佬!
离线
大佬一出,必然精品
离线
xui 的icon资源是怎么加载的 我测试了例子 都是在资源文件里面找不到 icon的图片资源
离线
xui 的icon资源是怎么加载的 我测试了例子 都是在资源文件里面找不到 icon的图片资源
看了一下 icon 资源 貌似是字体里面的 image 貌似是通过surface_t 实现的 如果我要显示一张自定义图片应该怎么加载显示呢
离线
linghaibin 说:xui 的icon资源是怎么加载的 我测试了例子 都是在资源文件里面找不到 icon的图片资源
看了一下 icon 资源 貌似是字体里面的 image 貌似是通过surface_t 实现的 如果我要显示一张自定义图片应该怎么加载显示呢
找到了 是不是这个 surface_alloc_from_xfs
离线
xui 的icon资源是怎么加载的 我测试了例子 都是在资源文件里面找不到 icon的图片资源
可能楼主用的是SVG矢量图片。
离线
linghaibin 说:linghaibin 说:xui 的icon资源是怎么加载的 我测试了例子 都是在资源文件里面找不到 icon的图片资源
看了一下 icon 资源 貌似是字体里面的 image 貌似是通过surface_t 实现的 如果我要显示一张自定义图片应该怎么加载显示呢
找到了 是不是这个 surface_alloc_from_xfs
可以了 分享一下流程
ctx_xfs = xfs_alloc("/private/framework", 0);
logo = surface_alloc_from_xfs(ctx_xfs, "assets/images/panel.png");
if(logo) {
printf("create suss/n");
} else {
printf("create fail/n");
}
xui_image_ex(ctx, logo, 0, XUI_IMAGE_CONTAIN);
离线
icon是矢量字体实现的,渲染过程利用了freetype,就是流行的icon font
离线
贴一个overview demo的演示视频,可以看看究竟实现了哪些控件,要扩展控件也是比较简单的,一般一个控件也就不到200行代码,也可自定义高级别的的控件。
离线
高级别的组件可以由各种低级别的组件组合而成,也就是说,你实现了一个模拟时钟界面,那么这个界面可以变成一个控件,导出一个控件函数,就可以随便调用了,需要注意的事,可变的控制信息需要通过参数传递进去,不能共享变量,不然创建多个控件时会导致同步变化。
离线
理解立即模式好难啊。
普通GUI的界面元素都是对象,对象拥有一些属性和方法,对象用树状结构管理,这很好理解。
立即模式该怎么理解呢?
离线
立即模式是个大循环,里面不断调用各种控件,每一帧只要屏幕上看得见的都会调用一遍,在调用时会生成绘图指令队列,再全部调用完后,重排绘图指令,做脏矩形优化,找到需要更新的区域,执行相关的绘图指令。事件处理过程就是在控件的调用里,事件会改变绘图指令,当绘图指令变化了,界面就跟这变化了
离线
因为是个大循环,感觉效率会很低,但这里做了很多优化,比如,比如当屏幕不变化时,也要去重刷,明显是浪费cpu资源,在这里用hash算法优化了,每一帧的所有绘图指令,都进行hash运算,当hash值变化了,就代表屏幕内容变化了,这样才需要执行具体的绘图指令。但光有这一个部分优化,还是不够的,如果屏幕仅仅有一小块区域变化了,hash值变了就进行全屏刷新绘制,效率也是很低的,所有,这里又将屏幕分成无数个格子,每个格子都有一个hash值,如果这个格子的hash值变化了,就代表这个格子需要重新绘制,这样就实现按需刷新,也就是脏矩形技术。
离线
经过优化后,这个大循环基本能做到千帧以上,逻辑上的响应速度是很快的,瓶颈主要是在渲染部分,这个看硬件渲染看硬件绘图能力,千帧UI的表现就是很灵敏,没有迟钝的现象,可以看上面的演示视频,当然你绘图拖后腿了,那就没辙了,谁叫你画得慢呢,立即UI,都是通过指令来生成各种图形的,贴图在这里是二等公民,因为都是指令,所以整个UI都是矢量的,每个控件都支持无限缩放,自动布局。看视频最后的演示,里面调整了主题参数,然后一个个按钮都变得特别大
离线
板凳,听大佬讲课
离线
优化了下xui,避免多次重复计算字体尺寸,在F1C100S平台上测试帧率提升了4帧
字体测量,布局,这个还是比较耗资源的。
离线
看起来不错
离线
补充一下原始设计稿,不是贴图喔,上面的界面是纯代码实现。
请问这个设计稿软件是做什么用的,也是上位机做界面,Xboot去运行吗
离线
这个就是一个美工用的工具,类似ps而已
离线
按一个按钮让树的某个节点以及它的子节点全部展开或关闭应该怎么调用接口?
可以在一个线程循环读数和计算,然把计算结果显示在label里面吗?
离线
可以的,可以看那个cmd-overview.c,看里面怎么写的,千万别用保留模式的思维来思考,换一种思维,你会发现,一切都是顺其自然的,纯线性思维。
离线
下面是一个简单的demo代码,一个窗体里创建了3个控件,一个label,独占一行,显示value变量的值,两个button,每个100像素宽,在同一行,其中一个点击后执行加一操作,另一个执行减一操作。看着着代码应该更容易理解怎么编写UI吧。
static void test_window(struct xui_context_t * ctx)
{
if(xui_begin_window(ctx, "Test Window", NULL))
{
static int value = 0;
xui_layout_row(ctx, 1, (int[]){ -1 }, 0);
xui_label(ctx, xui_format(ctx, "value = %d", value));
xui_layout_row(ctx, 2, (int[]){ 100, 100 }, 0);
if(xui_button(ctx, "add"))
value++;
if(xui_button(ctx, "sub"))
value--;
xui_end_window(ctx);
}
}
下面是演示视频
最近编辑记录 xboot (2021-04-26 17:49:23)
离线
可以的,可以看那个cmd-overview.c,看里面怎么写的,千万别用保留模式的思维来思考,换一种思维,你会发现,一切都是顺其自然的,纯线性思维。
我第一个问题其实是想问控件有没有记录状态功能,然后通过api更改它的状态,然后下一次刷新就能做出正确的绘图,例如树节点的开或闭。还是说所有状态都要用户程序通过全局或静态变量来记录,然后在代码中用if else做相应的处理?
还有一个问题,如果数据来自于网络,譬如这个论坛的一个主题,它包含很多内容,现在是否有比较简便的接口从数据直接生成ui呢?以后呢?
离线
第一个问题,绝大部分控件的状态是由用户来维护,但某些控件,为了方便使用,xui自动负责维护了,这个需要在实现控件时,跟一般控件有些区别,也就是说,系统可以自动维护状态,比如树形控件的展开和折叠,窗口的显示与关闭,toogle开关的缓动动画过程,这些是控件自动维护的,但checkbox,radiobutton等状态是需要外面的变量来维护的。
第二个问题,通过描述文件生成ui,界面的描述,是没有任何问题的,但你事件响应就无法编程了,没有任何响应的界面,是没有任何意义的。
通过api改变控件的状态,这种是保留模式特有的,这立即模式根本就不需要api来改变控件状态,你直接改变变量的值,ui就跟着变化了。
控件和变量是天然绑定的,控件可以改变变量,同样变量也可以改变控件。
最近编辑记录 xboot (2021-04-26 20:07:23)
离线
关于控件和变量天然绑定,这个可以看number控件,这个控件可以绑定一个变量,变量类型有多种,char,int,float,double等都是可以绑定的
static inline int xui_number(struct xui_context_t * ctx, double * value, double low, double high, double step)
static inline int xui_number_float(struct xui_context_t * ctx, float * value, float low, float high, float step)
static inline int xui_number_int(struct xui_context_t * ctx, int * value, int low, int high, int step)
static inline int xui_number_uint(struct xui_context_t * ctx, unsigned int * value, unsigned int low, unsigned int high, unsigned int step)
static inline int xui_number_char(struct xui_context_t * ctx, char * value, char low, char high, char step)
static inline int xui_number_uchar(struct xui_context_t * ctx, unsigned char * value, unsigned char low, unsigned char high, unsigned char
number控件绑定某个变量后,就会双向控制,滑动鼠标可以改变变量的值,同样,改变变量的值,可以修改控件的显示状态,滑动的范围,步长等参数,都可以在调用控件时传递参数来设置。
if(xui_begin_tree(ctx, "Normal Number"))
{
static double n[8] = { 10, 20, 30, 40, 50, 60, 70, 80 };
xui_layout_row(ctx, 1, (int[]){ -1 }, 0);
for(int i = 0; i < 8; i++)
{
xui_number_ex(ctx, &n[i], -1000, 1000, 1, "%.2f", (i << 8) | XUI_OPT_TEXT_LEFT);
}
xui_end_tree(ctx);
}
这个代码是创建8个double型number控件,从-1000 到1000,步长为1。这样这个double变量,就限制了变化范围,以及变化的步长,可以通过ui来双向控制。
离线
立即模式天然绑定变量,可以说是天然的响应式UI框架。不过缺点也很明显,没有快速化组件能力,需要自己维护大量状态变量。
离线
wifi模块是ESP8266吗?
离线
如果要在程序中记住UI所有状态,这未免增加了应用开发人员的脑力负担,而且程序耦合度也高了。不过嵌入式系统ui不会很复杂元素也比较固定,这点额外负担倒是可以接受。
控件和变量天然绑定,我看了代码有些是,有些不是,譬如raido,progress,哪些应该绑定哪些不用绑定以后要好好设计。
我的第二个问题并不是通过描述文件生成ui,而是wpf中的mvvm,数据驱动ui。既然xui有数据绑定功能,那应该可以做到。
通过描述文件生成ui 看似解耦了ui和代码,其实在现实中ui和代码绝对分开的例子比例并不大,最后还是会增加ui设计者和代码开发者的沟通成本,如果都由一个人来做的话又要在ui语言和代码语言之间切换,这又增加了脑力成本,现在大家都准备走flutter和jetpack compose路线,也是吸取了多年经验教训后的结果啊。
离线
不知道xui怎么解决多余重绘问题的,譬如某个控件的状态变化了,整个画面需要重画。在保留模式下因为修改控件的状态必须调用控件接口,所以控件的状态都由自己记录,控件可以知道自己状态有没有改变,没有就不需要重画。
某个控件状态改变导致整个画面重绘的问题很耗cpu,在嵌入式里面恐怕难以接受。
可以学学react的做法,控件函数里面只记录状态,控件api调用完成时(譬如xui_end_window()或xui_end()时)把整个ui树的状态发送到另一个线程做界面绘制。因为绘制线程拿到整个ui树各个控件的状态,这还可以在绘制前做优化。也可以在性能不足的时候把某些帧跳过,只需要忽略掉某次主线程发过来的状态。
离线
不知道xui怎么解决多余重绘问题的,譬如某个控件的状态变化了,整个画面需要重画。在保留模式下因为修改控件的状态必须调用控件接口,所以控件的状态都由自己记录,控件可以知道自己状态有没有改变,没有就不需要重画。
某个控件状态改变导致整个画面重绘的问题很耗cpu,在嵌入式里面恐怕难以接受。
可以学学react的做法,控件函数里面只记录状态,控件api调用完成时(譬如xui_end_window()或xui_end()时)把整个ui树的状态发送到另一个线程做界面绘制。因为绘制线程拿到整个ui树各个控件的状态,这还可以在绘制前做优化。也可以在性能不足的时候把某些帧跳过,只需要忽略掉某次主线程发过来的状态。
XUI是绘图命令级别的脏矩形刷新,不是控件级别的局部刷新
离线
jlau 说:不知道xui怎么解决多余重绘问题的,譬如某个控件的状态变化了,整个画面需要重画。在保留模式下因为修改控件的状态必须调用控件接口,所以控件的状态都由自己记录,控件可以知道自己状态有没有改变,没有就不需要重画。
某个控件状态改变导致整个画面重绘的问题很耗cpu,在嵌入式里面恐怕难以接受。
可以学学react的做法,控件函数里面只记录状态,控件api调用完成时(譬如xui_end_window()或xui_end()时)把整个ui树的状态发送到另一个线程做界面绘制。因为绘制线程拿到整个ui树各个控件的状态,这还可以在绘制前做优化。也可以在性能不足的时候把某些帧跳过,只需要忽略掉某次主线程发过来的状态。XUI是绘图命令级别的脏矩形刷新,不是控件级别的局部刷新
好像是,看了代码xui_draw_xxx()都是把绘图命令放入队列,在xui_end()做优化后绘图
离线
XUI记录的是绘图指令,每条指令都有影响的空间区域且记录在指令里,将所有指令重排,计算出影响了到了哪些区域再做脏矩形优化。一个控件由多条绘制指令组合而成,其实所谓的控件仅仅是一个函数,并没有特别的,复合控件,就是多调用了很多其他函数而已。控件的概念本身是弱化了,只不过方便人使用而抽象出来的。从这一点上看,任何奇形怪状的控件都是可以做出来的,不一定是矩形区域,只要能画得出来的都可以。立即UI特别灵活,少量的代码就可以作出复杂的界面,在嵌入式领域还是有优势的,谁都讨厌动不动就上万行的代码。现在xui,23个控件总共才3000多行,其中框架就占了近2000行,也就说说一个控件才需100行代码,我想这是立即UI最大的优势吧。当然耦合性强,这也是他的缺点。
声明式UI肯定是未来的趋势,但这个需要强大的脚本语言配合,纯编译型语言是不可能实现声明式UI的。Jetpack Compose理念最大的变化就是将原来的继承关系变成了顶级函数间的组合关系,摒弃类,而拥抱函数。
再补充一句,声明式UI可以说是进化版的立即UI,就是不用用户维护变量版本的立即UI。为何能做到不要用户维护,那是因为引入了脚本语言,可以动态记录各种状态。
离线
确实,立即模式GUI实现容易,使用方便,显示速度快,而且更像是业务代码的一个呈现层,并不是框架,这些优势确实很契合嵌入式系统。我想一个比较大的问题会是扩展性比较差,应用的功能一多,代码的规模和逻辑就有点难以控制。我想也是它的应用面不广的一个主要原因吧。保留模式GUI在应用设计时就要有分层思维,也容易模块化,更适合功能多规模大的应用。
声明式GUI说是兼有了立即模式GUI和保留模式GUI的优势,算是未来的趋势了。它们并没有使用脚本语言,swift、kotlin、dart都是编译型语言,只是它们的语法和编译器对声明式GUI做了些适配。脚本语言代码一多维护成本就很高,对app开发并不是好的选择。我记得qt在qt6也要把qml做成编译型的静态语言了。xboot支持lua,或许可以用lua做个声明式GUI。
离线
是的,lua理论上是可以实现声明式GUI的,但现在还没见到相关工程,有lua版的react移植,但react仅仅是框架,排版,渲染,等都是自己实现,工作量还是很大的,这个领域我会一直关注,如果思路成熟了,真可能会去实现个lua版的声明式gui,现在xboot里,支持各种c版app,lua版app,可同时运行,不管选用哪种gui框架,都不冲突。之所以开发个c版本的gui,就是考虑到嵌入式领域,某些简单的案子,完全用c就可以胜任了,没必要上那么高阶的技能,况且lua也不是每个人都懂,多少是有点学习成本的。
编译型语言支持声明式ui,这一点我现在还没想明白,如果要让c支持声明式ui,理论上也有可能吗?第一感觉是不能。
离线
如果c语言支持命名参数和匿名函数,那可以写成flutter那样:
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Center(child: Text('$val'))),
ElevatedButton(
child: Text('Add'),
onPressed: () => change(),
),
],
),
),
);
}
如果c语言进取一点,有更多的语法糖(https://developer.android.google.cn/jetpack/compose/kotlin),可以写成jetpack compose那样:
@Composable
fun NewsStory() {
Column(
modifier = Modifier.padding(16.dp)
) {
Image(
painter = painterResource(R.drawable.header),
contentDescription = null
)
Text("A day in Shark Fin Cove")
Text("Davenport, California")
Text("December 2018")
}
}
我了解了c语言的标准,即使是下一代标准c2x,仍然不支持这些语法,所以用c语言做声明式GUI还是不成。
有另一个法子,可以自己定义一套DSL,用编译器把DSL转换成c,然后统一通过gcc编译。作为参考,nim,vlang这些语言都可以直接编译成c,而且还是全功能语言不是DSL,DSL应该更简单。另外,vlang也有自己的声明式GUI。
不用神话声明式GUI,概略的看它跟立即式GUI很像,flutter的runApp()就是xui_loop(),它内部也是不断调用build()函数,build()函数不断调用里面的widget生成函数去实例化widget,就跟xui的应用不断调用xui_begin_xxx()一样。只不过由于flutter和jetpack compose的语言有一些便利的语法,写出来的代码看上去像声明一个个widget而不是创建一个个widget,其实内在是创建一个个widget。
如果是实现立即式GUI,用过程式编程语言就可以了;如果是实现保留式GUI,面向对象语言更合适;而要实现声明式GUI,更现代的语言才行。声明式GUI的流行可能是前端开发人员在不断采用现代化的语言的过程中受了立即式GUI的启发慢慢发展和流行出来的吧。
离线
新版本,支持wifi,485更新界面信息
离线
这个屏和我买的一毛一样,是不是中显的
离线
不用神话声明式GUI,概略的看它跟立即式GUI很像,flutter的runApp()就是xui_loop(),它内部也是不断调用build()函数,build()函数不断调用里面的widget生成函数去实例化widget,就跟xui的应用不断调用xui_begin_xxx()一样。只不过由于flutter和jetpack compose的语言有一些便利的语法,写出来的代码看上去像声明一个个widget而不是创建一个个widget,其实内在是创建一个个widget。
如果是实现立即式GUI,用过程式编程语言就可以了;如果是实现保留式GUI,面向对象语言更合适;而要实现声明式GUI,更现代的语言才行。声明式GUI的流行可能是前端开发人员在不断采用现代化的语言的过程中受了立即式GUI的启发慢慢发展和流行出来的吧。
你对声明式UI理解有误,你说的是声明式创建控件,但是其实声明式UI直接创建的不是控件而是一个类似json结构的VDOM。然后才根据VDOM去创建或者更新真正的DOM控件。否则光有声明式创建,无法实现变量绑定和按需更新
我也是自己做了个React的Python版才真正理解了这点
离线
从另外一个角度看,虚拟dom是否可以看成绘制命令呢,diff算法,就相当于比较两帧之间的绘制命令差异。可能一个是宏观的,一个是微观的吧
离线
从另外一个角度看,虚拟dom是否可以看成绘制命令呢,diff算法,就相当于比较两帧之间的绘制命令差异。可能一个是宏观的,一个是微观的吧
是的,react它是控件级别的diff,算是宏观diff吧,backend其实是保留模式的控件。
你的UI是立即UI,有diff绘图了,感觉可以省掉vdom以及diff,直接声明式描述UI就可以了,就是状态不是很好封装
离线
是的,就是状态不好封装,还有具体的事件响应没办法描述,语言能力在声明式UI显得很关键,基本有什么样语言就有什么样的表达,还是看语言的表达能力。
离线
给xui添加滑动支持,采用阻尼系统模型
离线
中文界面启动速度优化,其中logo显示后会等待1秒,再执行APP
离线
强烈需要键盘..
离线
软键盘,输入法?
离线
软键盘,输入法?
不需要输入法,只需要键盘能输入符号、英文字母、数字就行。 一般不需要打单词和汉字。当然有汉字更好
离线
写个键盘控件没多少行代码,关键要好看的话,这个得找到漂亮的皮,才行
离线
启动速度及通信测试,持续通信45分钟,没有发现异常。
离线
区分拖动与滑动事件,滑动时可以急停,提升用户体验
离线
支持通过网络和485传输图片,因为传输协议层中间是通用的json数据,所以图片都是经过base64编码后,json格式打包传送到板子上,板子收到完整帧后,先base64解码,然后再jpg或png格式解码,解码后的内容直接生成surface_t对象,可通过xui_image 控件显示对象。
离线
离线
声明式ui,还是流行的web前端比较合适(html,css,js三剑客)。sciter就是基于这种技术实现,体积也比较小,不过需要linux(gtk)。
最近编辑记录 kekemuyu (2021-05-08 21:13:08)
离线
在树莓派运行的demo,可以看到依赖的东西很少,只有一个scapp文件,其他都是前端的东西
离线
基于前端技术的本地APP开发
离线
很多桌面软件都已经开始用前端技术来开发了,常用的网易云音乐pc端,vscode,微信小程序开发工具等。
离线
大佬,
stm32f4这样的芯片能跑吗??
不知道能否替代emwin
离线
看你内存多大了,靠内部K级的SRAM肯定是不可以的
离线
声明式ui,还是流行的web前端比较合适(html,css,js三剑客)。sciter就是基于这种技术实现,体积也比较小,不过需要linux(gtk)。
https://whycan.com/files/members/1315/Screenshot211109.png
sciter不是完整实现,React和VUE都跑不起来的。
不过作为一个HTML引擎,sciter确实很小巧才几个MB。我也关注很久了,学生时代就关注过,那时候它还很简陋,现在强大多了
离线
kekemuyu 说:声明式ui,还是流行的web前端比较合适(html,css,js三剑客)。sciter就是基于这种技术实现,体积也比较小,不过需要linux(gtk)。
https://whycan.com/files/members/1315/Screenshot211109.pngsciter不是完整实现,React和VUE都跑不起来的。
不过作为一个HTML引擎,sciter确实很小巧才几个MB。我也关注很久了,学生时代就关注过,那时候它还很简陋,现在强大多了
前端web不用框架开发桌面级程序也是很简单的.
离线
给屏幕打上水印,任何界面都会有,有人能猜到究竟是想干啥吗?
离线
XUI是xboot内置的立即模式GUI框架,代码量很低,但功能绝对强大,所想即所得,无需各种设计器辅助,随心所欲敲你的代码,就行了,当你敲完了,UI开发工作就结束了。
https://whycan.com/files/members/2137/1_20210423-1639.jpg
您这个开发是在Windows下开发的,Linux系统不会用,想进行裸机开发
离线
windows可以开发的,不过,体验差很多,开发效率也低很多。
离线
纯代码编写GUI,控件位置什么的,需要自己先计算好坐标值吗?
离线
不需要,有自动布局系统,布局相关函数的调用一下,就可以按你心里所想得布局规则,布局了。
离线
要是还要自己去算坐标,不是累死个人,而且,定死坐标的那种,怎么可能做到自适应,且矢量化的UI系统。任意缩放,靠指定坐标来实现,是不敢想象的。XUI里面任何一个控件都无需传递任何坐标参数信息,也不会存储各种坐标,全靠自动布局系统来管理布局。
离线
有没有移植教程,想搞到STM32F4平台上,内存8M,不知道够用了没
离线
楼主的界面是用在医疗系统上的吗?
离线
感谢楼主分享,的确是一个不错的ui框架
离线
感谢楼主分享,的确是一个不错的ui框架
离线
离线
看上去确实不错,xui跟微软的guix比怎么样?
离线
请问一下楼主,这个图形库支持非触摸屏吗?比如支持手动改变焦点控件、手动改变焦点控件后,自动把焦点控件移到可显示的区域显示
离线
立即UI想做任何效果都可以的,通过按键来操作UI,也是可以的,仅需要声明一个变量用来存储当前激活的控件
if(xui_tabbar(ctx, 0xf26c, "Turn off backlight", item == MENU_ITEM_LCD))
item = MENU_ITEM_LCD;
if(xui_tabbar(ctx, 0xf4ad, "Device infomation", item == MENU_ITEM_INFO))
item = MENU_ITEM_INFO;
if(xui_tabbar(ctx, 0xf011, "Shutdown", item == MENU_ITEM_SHUTDOWN))
item = MENU_ITEM_SHUTDOWN;
比如这段代码item是一个枚举型,代表当前激活的控件,你按按键后去改变item的值就可以了,当然如果你通过触摸控件,item的值也可以跟着变化,算数据双向绑定。
离线
现在的XUI比较依赖XBoot,是否能够剥离出来,作为一个单独的GUI框架呢
离线
现在的XUI比较依赖XBoot,是否能够剥离出来,作为一个单独的GUI框架呢
离线
感谢楼主分享,第一次听说GUI实现的三种设计模式,我还在手算坐标。。。
最近编辑记录 oldgerman (2021-12-28 15:18:57)
离线
@海石生风
XML打包成二进制格式,本质还是一个配置文件,那如何用xml或者二进制描述事件呢,以及在xml里如何动态修改控件状态或者外部变量呢,如果做不到这一点,就不能称之为声明式,如果仅仅是普通的xml描述界面,连响应式都算不上。
离线
@海石生风
AWTK不算声明式UI,只不过用xml来描述UI,而且只是静态描述。后来加了数据绑定之后有点声明式UI的感觉了,不过还是远远不够。
ReactJS才是目前最纯正的声明UI
除了数据绑定,声明式UI还要能做到动态根据状态显示不同的UI,而不需要命令式的去增减或修改控件
if a>0 then
<button text={variable}>
else
<Text text={variable}>
end
离线
调用surface_alloc_from_xfs()显示一张图片,然后在图片的某个地方显示一个可以变化的时间,这样可以做到吗
最近编辑记录 岁月快快快 (2022-01-24 16:38:53)
离线
可以的,什么效果都可以做到,对于在一个控件之上,再绘制一个控件,需要主动调用布局相关函数,不然,会依次向下排列的。
离线
可以的,什么效果都可以做到,对于在一个控件之上,再绘制一个控件,需要主动调用布局相关函数,不然,会依次向下排列的。
我是想在固定的坐标位置显示时间(或者贴上一张小尺寸的图片覆盖原来显示的图片的某一区域),不传入坐标值的话,布局函数怎么知道要显示在什么地方呢
最近编辑记录 岁月快快快 (2022-01-25 17:39:10)
离线
可以调用这个布局函数
void xui_layout_set_next(struct xui_context_t * ctx, struct region_t * r, int relative);
离线
可以调用这个布局函数
void xui_layout_set_next(struct xui_context_t * ctx, struct region_t * r, int relative);
@xboot,大佬,按照@linghaibin坛友这样写:
static void ShowPage(struct xui_context_t * ctx)
{
struct xfs_context_t * ctx_xfs;
struct surface_t * page;
xui_begin(ctx);
ctx_xfs = xfs_alloc("/private/framework", 0);
if(ctx_xfs) {
page = surface_alloc_from_xfs(ctx_xfs, "assets/images/06.png");
if (page) {
xui_image_ex(ctx, page, 0, XUI_IMAGE_CONTAIN);
surface_free(page);
}
xfs_free(ctx_xfs);
}
xui_end(ctx);
}
图片没显示出来,显示成了这样:
按照开机logo这样写,是可以正常显示图片的:
static void ShowPage(const char * filename)
{
struct device_t * pos, * n;
struct xfs_context_t * ctx;
struct surface_t * s, * page;
struct framebuffer_t * fb;
struct matrix_t m;
ctx = xfs_alloc("/private/framework", 0);
if(ctx)
{
page = surface_alloc_from_xfs(ctx, filename);
if(page)
{
list_for_each_entry_safe(pos, n, &__device_head[DEVICE_TYPE_FRAMEBUFFER], head)
{
if((fb = (struct framebuffer_t *)(pos->priv)))
{
s = framebuffer_create_surface(fb);
matrix_init_identity(&m);
surface_blit(s, NULL, &m, page, RENDER_TYPE_GOOD);
framebuffer_present_surface(fb, s, NULL);
framebuffer_destroy_surface(fb, s);
}
}
surface_free(page);
}
xfs_free(ctx);
}
}
第一种方式是我还少了什么步骤吗
最近编辑记录 岁月快快快 (2022-01-27 09:11:55)
离线
你这写法不正确,xui_begin和xui_end之间,是会疯狂调用的,你这写法等于无限分配一个图片,当然后面的肯定无法分配成功,没有内存了。合理的写法,是外部分配好,再使用,或者引入图片cache机制。才可以这样写。
离线
@达克罗德
AWTK支持动态渲染控件
<label v-if="{value < 0}" /> <!-- value 小于0 时渲染这个label控件 -->
<label v-elif="{value > 0 && value < 2}"/> <!-- value 大于0且小于2时渲染这个label控件 -->
<label v-else=""/> <!-- 其他情况则渲染这个label控件 -->
可以在UI描述文件内执行fscript脚本
<button text="Basic" on:click="open('basic')" />
<text_selector name="month" options="1-12-%02d" selected_index="8" loop_options="true">
<property name="on:value_changed">
<![CDATA[
a = get_days_of_month(widget_get('parent.year', 'value'), widget_get('parent.month', 'value'))
widget_set('parent.day', 'options', iformat( '1-%d', a) + '%02d')
]]>
</property>
</text_selector>
最近编辑记录 海石生风 (2022-08-14 09:34:57)
离线
@海石生风
不错,谢谢指出!就是看起来有些复杂,很难让人用起来。还得高级语言来实现才有易用性
离线
@海石生风
有些逻辑是UI相关的逻辑,如果描述语言无法实现描述的动态性和逻辑,实际反而不方便。以前我也觉得逻辑是逻辑,UI是UI,必须分开。但是看过ReactJS之后我又动摇了,现在流行的是业务逻辑-》数据-》UI逻辑和状态-》View这样的单向数据流,反而不提倡UI和逻辑放的太开。
高级语言当然有用,可以实现UI和逻辑的无缝组合,多位一体,不用创造和学习一个特定的描述语言;既可以写逻辑也可以写UI,想分开就分开,想合在一起就合在一起,想组合就组合,灵活多变,表达能力强。
AWTK这种有点像Vue,创造了很多扩展语法到XML,要想写UI和逻辑,你得在XML,扩展语法,C或者JS三者之间跳转
QML这种,你得在QML,JS,C++三者中跳转
ReactJS这种,你只需要JS语法和一点点XML的组织形式(其实也只是可选项)。比如Flutter,语言本身就可以实现类似XML的嵌套结构和可变参数,所以它只需要一个语言。
离线
@海石生风
有人在玩嵌入式跑React:https://github.com/ZhUyU1997/MEUI
QQ群765228998
AWTK好像也有ReactJS版的移植,以前看到过,不知道现在怎么样了
我想那些全志的带DDR的芯片应该都可以跑得起来
离线
AWTK相对LVGL、emWin这些只能用API手写界面的UI库已经方便很多了。基于MVVM框架只需要写模型(C语言)跟视图(XML),开发效率已经很高了。关键是这个UI能通吃MCU、ARM9、A7、PC平台。
逻辑跟UI分开的其中一个好处是逻辑跟UI都可以用不同的东西实现:逻辑可以用不同的编程语言来写,像AWTK就支持C/C++、python、golang、javascript等;而UI描述语言也可以在后期另外造轮子来实现。这样就能支持多种平台、发展再灵活,像AWTK这样。
如果将UI描述写在逻辑里,基本就限死了编程语言。目前来说,要通吃各种平台的简单的方法是用C/C++作为编程语言。
最近编辑记录 海石生风 (2022-08-19 09:41:49)
离线
ReactJS这种是未来的趋势,大家都在追求效率以及体验,多种语言互相切换,还是很烦人的,lua可以说是最牛逼的胶水语言,但尽管如此,跟C交互,还是有很多细节需要照顾到,要开发声明式UI,必须从语言选择开始,否则再怎么设计,都是隔靴搔痒。
离线
WASM技术 + reactJS,应该算终极方案,嵌入式上实现一个wasm虚拟机,然后什么都可以搞定了
离线
可以播放动态图片和视频吗
离线
想请教下大神,xui_layout_begin_column 和 xui_begin_panel 这两个函数的区别是什么?哪些场景选择xui_layout_begin_column而不是xui_begin_panel?
谢谢!
离线
xui_layout_begin_column是纯逻辑实现,用于实现包裹多列布局的代码,xui_begin_panel当然也能搞出这种多列布局,但自身就是一个具体控件。前者是一个布局函数,后者是控件。
离线
大佬,这个启动速度快吗?需要几秒?
离线
可以呀 裸机不需要配置环境
离线
大佬,帧率能到多少呀?
离线