前面的章节我们已经学习了大部分的布局知识,接下来我们将重点学习功能实现。
本节我们将以一个简单的 todo list 为实战,讲解在 nicegui 中最基础的功能代码组织方式。
本节尽可能避免过多的布局和样式代码
本节我们将学会:
本节使用的 nicegui 版本为 1.4.22
从一个简单信息提交的功能开始。
看看流程图:
与代码对照看:
经常有人问我,怎么用 nicegui 做一个数据库的增删改查界面?大家想想,上面第15行代码中的函数 save_data ,里面的代码到底怎么写?如果我告诉你,它里面就是把数据写入数据库,你觉得有可能吗?
实际上,它的代码是这样:
是的,对于界面代码来说,这个函数里面的代码逻辑不重要。界面根本不关心到底是不是把数据写入了数据库。
现在我们可以非常简单测试出界面代码是否正确。
注意,这个函数里面完全不会用到任何与界面相关的东西。所以函数的参数只能是基础类型。千万别因为偷懒,而把组件对象直接传进来。
因此,我们必须学会把界面逻辑与业务逻辑分离。
什么才算是界面逻辑?
现在看看怎么实现第二点:
这就是最普通最基础的方式,基于事件实现交互。这不是 nicegui 独有的方式,任何界面框架都离不开这种模式。
基于这种写法,现在可以构建 todo list 中,新增任务的界面和功能:
下面是界面逻辑:
下面是业务模块的代码:
这里为了方便演示,用了全局变量并且业务代码与界面代码写在同一个文件。你当然可以通过定义类等方式组织代码
当我们添加了一个 todo 任务后,下方应该显示当前所有的任务信息。接下来我们将应用 nicegui 特有的页面局部区域刷新功能完成。
按直觉来说,代码应该如下:
但是很显然是不行。在以前关于事件的章节中我们已经了解到,只有事件处理函数的代码才会不断执行。而这里的任务列表(变量 g_todos),随着用户操作不断变化。
在容器的章节中,我们知道,容器可以增删改里面的元素。所以我们稍微修改一下:
当然,我们还需要在所有影响任务列表的事件处理中,调一下函数 create_todo_items
现在界面显示已经没问题:
但是我们的界面代码不够好,nicegui 内置了一个"刷新"装饰器:
@ui.refreshable
装饰器打在自定义函数。在点击按钮的时候,我们不能再次调用函数,改成调用函数对象的 refresh
方法:
这是因为只有调用 refresh 方法,才是清空容器。如果直接调用函数本身,则会重新创建了一个"刷新区域"
下面是一个简单示意图:
refresh
方法,则会触发所有的区域进行刷新(上图红色部分)总结一下:
@ui.refreshable
refresh
方法
@ui.refreshable
还有广播能力,后续的章节再展开说明
接下来看看任务删除的功能:
这里简单说一下,直觉上你可能认为下面的代码没问题:
实际上,每个按钮的事件中,获得的 todo 总是列表中的最后一个。
我们只需要搞清楚,上面代码,哪些代码是在循环中立刻执行,哪些代码是延迟执行,就知道该怎么写: