Python 如何在ipywidgets中分离模型和视图?
以一个简单的外汇计算器应用程序为例 我可以使用traitlets定义我的模型: 以及相应的基于打印的简单视图:Python 如何在ipywidgets中分离模型和视图?,python,model-view-controller,ipywidgets,enaml,Python,Model View Controller,Ipywidgets,Enaml,以一个简单的外汇计算器应用程序为例 我可以使用traitlets定义我的模型: 以及相应的基于打印的简单视图: class FXView: def __init__(self, model): self.model = model def show(self): print(""" domestic_qty: {:.4g} foreign_qty: {:.4g} fx_rate: {:.
class FXView:
def __init__(self, model):
self.model = model
def show(self):
print("""
domestic_qty: {:.4g}
foreign_qty: {:.4g}
fx_rate: {:.4g}
lock: {}""".format(
self.model.domestic_qty,
self.model.foreign_qty,
self.model.fx_rate,
self.model.lock
))
下面是它的工作原理:
>> fx_model = FXModel(domestic_qty = 100., fx_rate = 200.)
>> fx_view = FXView(fx_model)
>> fx_view.show()
domestic_qty: 100
foreign_qty: 0.5
fx_rate: 200
lock: domestic
>> fx_model.fx_rate = 195.
>> fx_view.show()
domestic_qty: 100
foreign_qty: 0.5128
fx_rate: 195
lock: domestic
我还使用ipywidgets创建了一个视图:
import ipywidgets as widgets
domestic_label = widgets.Label("Domestic quantity")
domestic_field = widgets.FloatText()
foreign_label = widgets.Label("Foreign quantity")
foreign_field = widgets.FloatText()
fx_label = widgets.Label("Exchange rate (domestic/foreign)")
fx_field = widgets.FloatText()
lock_label = widgets.Label("If rates change, keep ")
lock_field = widgets.Dropdown(options=["domestic", "foreign"])
lock_label_post = widgets.Label('fixed')
ipyview = widgets.HBox([widgets.VBox([domestic_label, foreign_label, fx_label, lock_label]),
widgets.VBox([domestic_field, foreign_field, fx_field, widgets.HBox([lock_field, lock_label_post])])])
看起来真的很好:
我的问题是,;如何将模型和ipyview绑定在一起?我对ENML有一些经验,可以通过操作符:=和朋友来实现
使用ipyWidget的最佳方式是什么?好问题!我在ipywidgets上发布了一个答案: 下面介绍如何使用本文中的小部件,使用ipywidget视图创建自定义视图。关键是将属性绑定到小部件值的链接调用 将IPyWidget作为小部件导入 从traitlets导入链接 从IPython.display导入显示 类FXWidgetView: 定义初始自我,型号: self.model=model self.homesel\u label=widgets.label国内数量 self.hominal_field=widgets.FloatText self.foreign\u label=widgets.LabelForeign数量 self.foreign_field=widgets.FloatText self.fx_label=widgets.label国内/国外汇率 self.fx_field=widgets.FloatText self.lock_label=widgets.label如果速率发生变化,请保持 self.lock_field=widgets.dropdownpoptions=[国内外] self.lock\u label\u post=widgets.label'fixed' self.ipyview=widgets.HBox[widgets.VBox[self.national\u label、self.foreign\u label、self.fx\u label、self.lock\u label], widgets.VBox[self.national\u字段、self.foreign\u字段、self.fx\u字段、widgets.HBox[self.lock\u字段、self.lock\u标签\u post]] linkmodel,“国内数量”,self.national\u字段,“值” linkmodel,“外来数量”,self.foreign\u字段,“值” 链接模型,“汇率”,self.fx\u字段,“价值” 链接模型“锁定”,self.lock\u字段“值” def_ipython_显示器自身: displayself.ipyview
我要指出,Param提倡这种分离已经有一段时间了,@jbednar指出ipywidgets也可以实现方便的函数来支持这种模式。我认为这是一个好主意-拥有一些简单的便利函数,这些函数是从接受HasTraits类的interact函数中升级而来的,可以对其进行反思,并为常见情况下的不同traits提供默认小部件。好问题!我在ipywidgets上发布了一个答案: 下面介绍如何使用本文中的小部件,使用ipywidget视图创建自定义视图。关键是将属性绑定到小部件值的链接调用 将IPyWidget作为小部件导入 从traitlets导入链接 从IPython.display导入显示 类FXWidgetView: 定义初始自我,型号: self.model=model self.homesel\u label=widgets.label国内数量 self.hominal_field=widgets.FloatText self.foreign\u label=widgets.LabelForeign数量 self.foreign_field=widgets.FloatText self.fx_label=widgets.label国内/国外汇率 self.fx_field=widgets.FloatText self.lock_label=widgets.label如果速率发生变化,请保持 self.lock_field=widgets.dropdownpoptions=[国内外] self.lock\u label\u post=widgets.label'fixed' self.ipyview=widgets.HBox[widgets.VBox[self.national\u label、self.foreign\u label、self.fx\u label、self.lock\u label], widgets.VBox[self.national\u字段、self.foreign\u字段、self.fx\u字段、widgets.HBox[self.lock\u字段、self.lock\u标签\u post]] linkmodel,“国内数量”,self.national\u字段,“值” linkmodel,“外来数量”,self.foreign\u字段,“值” 链接模型,“汇率”,self.fx\u字段,“价值” 链接模型“锁定”,self.lock\u字段“值” def_ipython_显示器自身: displayself.ipyview
我要指出,Param提倡这种分离已经有一段时间了,@jbednar指出ipywidgets也可以实现方便的函数来支持这种模式。我认为这是一个好主意-使用一些简单的便利函数,这些函数是从接受HasTraits类的interact函数中升级而来的,可以对其进行反思,并为常见情况下的不同traits提供默认小部件。我已经复制过了我已经复制过了
import ipywidgets as widgets
domestic_label = widgets.Label("Domestic quantity")
domestic_field = widgets.FloatText()
foreign_label = widgets.Label("Foreign quantity")
foreign_field = widgets.FloatText()
fx_label = widgets.Label("Exchange rate (domestic/foreign)")
fx_field = widgets.FloatText()
lock_label = widgets.Label("If rates change, keep ")
lock_field = widgets.Dropdown(options=["domestic", "foreign"])
lock_label_post = widgets.Label('fixed')
ipyview = widgets.HBox([widgets.VBox([domestic_label, foreign_label, fx_label, lock_label]),
widgets.VBox([domestic_field, foreign_field, fx_field, widgets.HBox([lock_field, lock_label_post])])])