2. TraitsUI基础

来源:互联网 发布:最全英语单词数据库 编辑:程序博客网 时间:2024/06/03 12:43

  • TraitsUI
  • 缺省界面程序框架
  • View自定义界面
    • traitsui支持的后台界面库
    • traitsui中的MVC
    • view对象属性
    • Item对象属性
    • 实例
  • Group对象组织界面
    • Group对象
    • 实例
  • Group的各种派生类
    • 实例
  • 使用多个视图对象
  • 视图类型
    • truitsUI按钮配置
    • 实例
  • TraitsUI控件
    • 文本编辑器
    • 按钮Button Editor
      • 实例
    • Range滑动条
    • 菜单工具栏

TraitsUI

以traits为基础,以 MVC 为设计思想。
MVC:Modle-View-Controller

  • Model:程序中存储数据以及对数据进行处理
  • View :程序的界面实现数据的可视化/显示
  • Controller:控制程序流程,M/V之间组织作用

官方文档

缺省界面程序框架

from traits.api import HasTraits, Str, Intclass ModelManager(HasTraits):    model_name = Str    category = Str    model_file = Str    model_number = Intif __name__ == "__main__":    model = ModelManager()    model.configure_traits()

这里写图片描述

文字标签根据trait属性名自动生成:

  • 第一个字母->大写
  • 下划线->空格

View自定义界面

traitsui支持的后台界面库

后台界面库 程序启动时选择界面库参数 qt4 -toolkit qt4 Wx –toolkit wx

traitsui中的MVC

MVC类别 MVC说明 Model HasTraits的派生类用Trait保存数据,相当于模型 View 没有指定界面显示方式时,Traits自动建立默认界面 Controller 起到视图和模型之间的组织作用,控制程序的流程

view对象属性

View(title,width,height,resizable…)

属性 说明 title 窗口标题栏 Width 窗口宽度 Height 窗口高度 resizable 窗口大小可变,默认为True

Item对象属性

Item(id,name,label…)

属性 说明 id item的唯一id name trait属性的名称 label 静态文本,用于显示编辑器的标签 tooltip 编辑器的提示文本

实例

from traits.api import HasTraits, Str, Intfrom traitsui.api import View, Itemclass ModelManager(HasTraits):    model_name = Str    category = Str    model_file = Str    model_number = Int    view = View(        Item('model_name', label=u"模型名称"),        Item('model_file', label=u"文件名"),        Item('category', label=u"模型类型"),        Item('model_number', label=u"模型数量"),        title=u"模型资料", width=220, resizable=True)if __name__ == "__main__":    model = ModelManager()    model.configure_traits()

这里写图片描述

Group对象组织界面

Group对象

属性 说明 orientation 编辑器的排列方向 layout 布局方式normal、flow、split、tabbed show_labels 是否显示编辑器的标签 columns 布局的列数,范围为(1,50)

实例

from traits.api import HasTraits, Str, Intfrom traitsui.api import View, Item, Groupfrom traitsui.menu import ModalButtonsclass ModelManager(HasTraits):    model_name = Str    category = Str    model_file = Str    model_number = Int    vertices = Intif __name__ == "__main__":    view1 = View(        Group(            Item('model_name', label=u"模型名称"),            Item('model_file', label=u"文件名"),            Item('category', label=u"模型类型"),            label=u'模型信息',            show_border=True),        Group(            Item('model_number', label=u"模型数量"),            Item('vertices', label=u"顶点数量"),            label=u'统计数据',            show_border=True),    )    model = ModelManager()    model.configure_traits(view=view1)

这里写图片描述

如果想要不分标签页显示,可以在外面再嵌套一个Group。

from traits.api import HasTraits, Str, Intfrom traitsui.api import View, Item, Groupfrom traitsui.menu import ModalButtonsclass ModelManager(HasTraits):    model_name = Str    category = Str    model_file = Str    model_number = Int    vertices = Intif __name__ == "__main__":    view1 = View(        Group(            Group(                Item('model_name', label=u"模型名称"),                Item('model_file', label=u"文件名"),                Item('category', label=u"模型类型"),                label=u'模型信息',                show_border=True),            Group(                Item('model_number', label=u"模型数量"),                Item('vertices', label=u"顶点数量"),                label=u'统计数据',                show_border=True),        )    )    model = ModelManager()    model.configure_traits(view=view1)

这里写图片描述

在外层Group添加orientation = 'horizontal'

这里写图片描述

Group的各种派生类

派生类 说明 HGroup 内容水平排列Group(orientation=‘horizontal’) HFlow 内容水平排列,超过水平宽度时,自动换行,隐藏标签文字。Group(orientation=‘horizontal’,layout=‘flow’,show_labels=False) HSplit 内容水平分隔,中间插入分隔条Group(orientation=‘horizontal’,layout=‘flow’) Tabbed 内容分标签页显示Group(orientation=‘horizontal’,layout=‘tabber’ ) VGroup 内容垂直排列Group(orientation=‘vertical’) VFlow 内容垂直排列,超过垂直高度时,自动换列,隐藏标签文字Group(orientation=‘vertical’,layout=‘flow’,show _labels=False) VFold 内容垂直排列,可折叠Group(orientation=‘vertical’,layout=‘fold’,show _labels=False) VGrid 按照多列网格进行垂直排列,columns属性决定网格的列数Group(orientation=‘vertical’, columns=2) VSplit 内容垂直排列,中间插入分隔条Group(orientation=‘vertical’,layout=‘split’)

实例

from traitsui.api import HSplit, VGroup, View, Itemfrom traits.api import HasTraits, Str, Intclass ModelManager(HasTraits):    model_name = Str    category = Str    model_file = Str    model_number = Int    vertices = Intif __name__ == "__main__":    view1 = View(        HSplit(            VGroup(                Item('model_name', label=u"模型名称"),                Item('model_file', label=u"文件名"),                Item('category', label=u"模型类型"),                label=u'模型信息',            ),            VGroup(                Item('model_number', label=u"模型数量"),                Item('vertices', label=u"顶点数量"),                label=u'统计数据',            )        )    )    model = ModelManager()    model.configure_traits(view=view1)

这里写图片描述

使用多个视图对象

from traits.api import HasTraits, Str, Intfrom traitsui.api import View, Item, Groupg1 = [Item('model_name', label="模型名称"),      Item('category', label="模型类型")]g2 = [Item('model_number', label="模型数量"),      Item('vertices', label="顶点数量")]class ModelManager(HasTraits):    model_name = Str    category = Str    model_file = Str    model_number = Int    vertices = Int    traits_view = View(            Group(*g1, label='模型信息', show_border=True),            Group(*g2, label='统计数据', show_border=True),            title="内部试图")global_view = View(    Group(*g1, label='模型信息', show_border=True),    Group(*g2, label='统计数据', show_border=True),    title="外部试图")if __name__ == "__main__":    model = ModelManager()    # 内部试图    model.configure_traits()    model.configure_traits(view='traits_view')    # 外部视图    model.configure_traits(view=global_view)

视图类型

通过kind属性设置View显示类型

显示类型 说明 modal 模态窗口,非即时更新 live 非模态窗口,即时更新 livemodal 模态窗口,即时更新 nonmodal 非模态窗口,非即时更新 wizard 向导窗口,模态窗口,即时更新 panel 嵌入到其它窗口中的面板,即时更新,非模式 subpanel

模态窗口:在此窗口关闭之前,其他窗口不能激活;
即时更新:修改控件内容,立即反应到模型数据上。

前四个采用窗口显示内容,后两个是嵌入窗口中的面板。

configure_traits edit_traits() 界面显示后,进入消息循环 界面显示后,不进入消息循环。 主界面窗口或模态对话框 无模态窗口或对画框

truitsUI按钮配置

标准命令按钮:
UndoButton、ApplyButton、RevertButton、OKButton、CancelButton、HelpButton
预定义命令按钮:
OKCancelButtons = [OKButton, CancelButton]
ModelButtons = [ApplyButton, RevertButton, OKButton, CancelButton, HelpButton]
LiveButtons = [UndoButton, RevertButton, OkButton, Cancel]

实例

view1 = View(    Group(        Item('model_name', label=u"模型名称"),        Item('model_file', label=u"文件名"),        Item('category', label=u"模型类型"),        label=u'模型信息',        show_border=True),    Group(        Item('model_number', label=u"模型数量"),        Item('vertices', label=u"顶点数量"),        label=u'统计数据',        show_border=True),    kind='modal',    buttons=ModalButtons)model = ModelManager()model.configure_traits(view=view1)

这里写图片描述

TraitsUI控件

文本编辑器

from traits.api import HasTraits, Str, Passwordfrom traitsui.api import Item, Group, Viewclass TextEditor(HasTraits):    # 定义文本编辑器的变量    string_trait = Str("sample string")    password = Password    # 定义布局    text_str_group = Group(        Item('string_trait', style='simple', label='Simple'),        Item('_'),        Item('string_trait', style='custom', label='Custom'),        Item('_'),        Item('password', style='simple', label='password')    )    # 定义视图    traits_view = View(        text_str_group,        title='TextEditor',        buttons=['OK']    )if __name__ == '__main__':    text = TextEditor()    text.configure_traits()

这里写图片描述

按钮Button Editor

监听方法对比

作用 Event属性 Trait属性 触发监听事件 对Event属性赋值 值被改变后 监听函数名 _event_fired() _trait_changed()

实例

from traits.api import HasTraits, Button, Intfrom traitsui.api import Viewclass ButtonEditor(HasTraits):    # 定义一个Button trait:    my_button = Button('Click Me')    counter = Int    # 当按钮点击后,处理当按钮被点击后,触发的事件    def _my_button_fired(self):        self.counter += 1    # 创建视图    traits_view = View(        'my_button',        'counter',        title='ButtonEditor',        buttons=['OK'],        resizable=True)if __name__ == '__main__':    button = ButtonEditor()    button.configure_traits()

这里写图片描述

Range滑动条

from traits.api import HasTraits, Int, Range, Property, property_depends_onfrom traitsui.api import View, Item, RangeEditorclass RangeDemo(HasTraits):    a = Range(1, 10)    b = Range(1, 10)    c = Property(Int)    view = View(        Item('a'),        Item('b'),        '_',        Item('c', editor=RangeEditor(low=1, high=20, mode='slider')),        Item('c'),        width=0.3    )    @property_depends_on('a,b', settable=True)    def _get_c(self):        print("computing")        return self.a + self.bif __name__ == '__main__':    ran = RangeDemo()    ran.configure_traits()

这里写图片描述

菜单、工具栏

对象 说明 Action 在Menu对象中,通过Action对象定义菜单中的每个选项 ActionGroup 对菜单中的选项进行分组 Menu 定义菜单栏中的一个菜单 MenuBar 菜单栏对象,由多个Menu对象组成 ToolBar 工具栏对象,它由多个Action对象组成,每个Action对 应工具条中的一个按钮

控件列表

对象 说明 Array 数组空间 Bool 单选框、复选框 Button 按钮 Code 代码编辑器 Color 颜色对话框 Dircetory 目录控件 Enum 枚举控件 File 文件控件 Font 字体选择控件 Html Html网页控件
"""演示TraitsUI的各种编辑器"""import osfrom datetime import timefrom traits.api import *from traitsui.api import *class EditorDemoItem(HasTraits):    """界面右半部分,对于选中的某个Trait属性,使用4种样式创建属性编辑器"""    code = Code()    view = View(        Group(            # 使用simple编辑器,可尽量减少界面占用空间,width属性可指定编辑器宽度,负数表示强制设置宽度            Item("item", style="simple", label="simple", width=-300),            "_",  # 下划线字符串表示创建分隔线            # 使用custom编辑器,可尽量呈现更多内容 #            # TODO: Trait,Enum,Range三个函数无法用于custom编辑器,要运行这三个函数需要将其注释            Item("item", style="custom", label="custom"),            "_",            # 使用text编辑器,只呈现文本内容            Item("item", style="text", label="text"),            "_",            # 使用readonly编辑器,呈现只读文本            Item("item", style="readonly", label="readonly"),        ),    )class EditorDemo(HasTraits):    """创建主界面"""    codes = List(Str)  # 创建List界面,用来展示各种Trait属性的字符串    selected_item = Instance(EditorDemoItem)  # 初始化selected_item界面,用来存储被选项的编辑界面    selected_code = Str  # 初始化selected_code变量,用来存储被选项名称    view = View(        # 使用HSplite水平分隔两个界面        HSplit(            # 界面左半部分,用来创建各种Trait属性的源程序列表            Item("codes", style="custom", show_label=False,                 # 将editor属性设置为ListStrEditor(列表选择框控件),并更新selected_code变量                 editor=ListStrEditor(editable=False, selected="selected_code")),            # 界面右半部分            Item("selected_item", style="custom", show_label=False),        ),        resizable=True,        width=800,        height=400,        title=u"各种编辑器演示"    )    def _selected_code_changed(self):        """当selected_code变量改变时触发,更新selected_item界面"""        item = EditorDemoItem(code=self.selected_code)        # 使用eval对selected_code字符串进行求值,并将值存储到item中        item.add_trait("item", eval(str(self.selected_code)))        self.selected_item = itemclass Employee(HasTraits):    """创建Employee类,该类为包含四个属性的界面"""    name = Unicode(label=u"姓名")    department = Unicode(label=u"部门")    salary = Int(label=u"薪水")    bonus = Int(label=u"奖金")    view = View("name", "department", "salary", "bonus")if __name__ == '__main__':    employee = Employee()    demo_list = [u"低通", u"高通", u"带通", u"带阻"]    trait_defines = """        Array(dtype="int32", shape=(3,3)) #{1}fadsfa        Bool(True)        Button("Click me")        List(editor=CheckListEditor(values=demo_list))        Code("print('hello world')")        Color("red")        RGBColor("red")        Trait(*demo_list) #无法用于custom编辑器        Directory(os.getcwd())        Enum(*demo_list) #无法用于custom编辑器        File()        Font()        HTML('<b><font color="red" size="40">hello world</font></b>')        List(Str, demo_list)        Range(1, 10, 5) #无法用于custom编辑器        List(editor=SetEditor(values=demo_list))        List(demo_list, editor=ListStrEditor())        Str("hello")        Password("hello")        Str("Hello", editor=TitleEditor())        Tuple(Color("red"), Range(1,4), Str("hello"))        Instance(EditorDemoItem, employee)            Instance(EditorDemoItem, employee, editor=ValueEditor())        Instance(time, time(), editor=TimeEditor())    """    demo = EditorDemo()    # 一般写法    trait_list = []    for s in trait_defines.split('\n'):  # 按行分割字符串        if s.split('#')[0].strip():  # 判断s中是否存在可执行函数            trait_list.append(s.split('#')[0])  # 去掉注释    demo.codes = trait_list    # 简洁写法    # demo.codes = [s.split("#")[0] for s in trait_defines.split("\n") if s.split('#')[0].strip()]    demo.configure_traits()