摩匹克斯

mopyx的Python项目详细描述


mopyx是一个受mobx/vue启发的反应式模型驱动的ui库。用户界面 工具包独立。

反应式ui是一个让ui自动更新为 对后端模型中所做更改的响应。这种情况会发生 不需要手动注册监听器,以及反应式框架 跟踪模型的哪些部分影响 应用程序

演示

PySide2 MoPyX Demo

Pyside2 mopyx演示

完整的演示项目来源如下: https://github.com/germaniumhq/mopyx-sample

@型号

@model装饰模型类。所有的属性 将监视该类的更改无论什么时候 属性将更改,受影响的渲染器(仅渲染器 使用该属性的函数)将在模型更改时重新调用

@modelclassFormModel:def__init__(self):self.first_name="John"self.last_name"Doe"

@渲染

@render装饰ui呈现函数,或调用 他们用render_call。mopyx将映射使用的呈现方法 模型中的属性函数的参数也将是 录制并发送到渲染器函数。

classUiForm:def__init__(self):# ...self.render_things()@renderdefrender_things(self):self.first_name_label.set_text(self.model.first_name)self.last_name_label.set_text(self.model.last_name)

每当模型中的first_namelast_name发生变化时, render_things将被再次调用。

为了优化UI更新的数量,只有 @render函数将被调用,并不总是最上面的函数

所以可以将前面的@render方法分解为两个 方法:

@renderdefrender_things(self):self.render_first_name()self.render_last_name()@renderdefrender_first_name(self):self.first_name_label.set_text(self.model.first_name)@renderdefrender_last_name(self):self.last_name_label.set_text(self.model.last_name)

现在,如果模型中的first_name更改,则 不会调用last_name。这是自动发生的,而且 只调用所需的呈现器。

若要键入较少的内容,render_call()只需将给定的可调用内容包装成 @render。例如,我们可以将渲染器重写为更短:

@renderdefrender_things(self):render_call(lambda:self.first_name_label.set_text(self.model.first_name))render_call(lambda:self.last_name_label.set_text(self.model.last_name))

@render方法不允许在运行时进行模型更改。 如果设置ui值将触发模型更改,请阅读 ignore_updates

@行动

如果它们没有包装在动作中,那么每个属性也是一个动作, 因此,属性更改后,将触发渲染改进 性能您可以将多个模型更新打包为一个 @action。action方法可以调用其他方法,包括 @actions

当最上面的@action完成呈现时 调用mopyx将找出需要调用的渲染器,以及 应更新计算属性,以便将用户界面 一致的状态。

在内部,@model类中的所有属性setter都是 包裹在@actions中。

@action# withonut this would trigger a render after each assignmentdefchange_model(self):self.first_name="Jane"self.last_name="Mary"

@计算的

还可以使用^{tt20}在模型上创建属性$ 装饰工。这与普通python@property类似,但是 只有当它所依赖的其他属性之一 (包括其他Mopyx车型)变化。否则就叫这个 属性将返回先前计算的值。

这对于难以计算的属性是很好的。有一个必须 以排序方式访问,但从数据存储区以未排序方式访问?你 可以用@computed方法包装它。再次,请注意 @computed方法只在使用的属性由 @computed方法将更改:

@modelclassRootModel:def__init__(self):self.backend_data=[]@actiondeffetch_data(self):self.backend_data=fetch_data_from_service()@computeddeffirst_five_items(self):# will only be invoked when self.backend_data changesresult=list(self.backend_data)result.sort()result=result[0:5]returnresultclassUiRenderer:# ...@renderdefrender_items(self):# will be invoked only when first_five_items changesforiteminself.root_model.first_five_items:self.render_item(item)

@computed属性不允许更改 反对。

列表

如果其中一个属性是列表,则该列表将替换为 特殊实现,也会在顶部通知其更改 财产

@modelclassRootModel:def__init__(self):self.items=[]classUiComponent:@renderdefupdate_ui(self):foriteminself.items:self.render_sub_component(item)model=RootModel()ui=UiComponent(model)model.items.append("new item")# this will trigger the update_ui rerender.

忽略更新

如果渲染器将调用一个值,该值在ui中设置 将使ui触发一个事件,而该事件又可能在 操作(模型更新也是操作),可以禁用渲染 使用ignore_updates属性。这将抑制all操作 从该呈现方法调用,包括all model updates

这真是太棒了或用于输入编辑的onchange事件,或树更新 否则将进入无限递归的选定节点

调试

要检查发生了什么,可以在您的环境中导出:

  • MOPYX_DEBUG-这将在 慰问。
  • MOPYX_THREAD_CHECK-如果线程 对于@render方法更改。

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java InputStream对象在声明后关闭   java未定义名为“transactionManager”的bean重命名transactionManager   java“jar”命令何时会拒绝将类添加到java中。jar文件?   java JPA标准依赖WHERE子句   安卓中从SD卡读取文本文件时出现java错误   java直接启用类似位置的权限   使用@WebMvcTest和Mockito-BDDMockito对SpringBoot-RestController进行java测试   java JSESSIONID存储在哪里?   java jtextarea鼠标事件覆盖容器鼠标事件   java DRL无法解析动态加载的类   java是从一个方法返回多个对象的最简单方法   java自定义按钮/编辑框是否不可见?   java GUI如何在保存用户输入的同时在面板或框架之间切换   swing Java自定义JSlider不会更新   GridBagLayout中的java超过1个JPanel   java从ProjectReactor中的flux中采样除第一个元素外的所有元素   Java泛型和泛型类型   Java代码生成宽指令的jvm