16. TraitsUI基础

文章目录

  • 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, Int


class ModelManager(HasTraits):
    model_name = Str
    category = Str
    model_file = Str
    model_number = Int

if __name__ == "__main__":
    model = ModelManager()
    model.configure_traits()

16. TraitsUI基础_第1张图片

文字标签根据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, Int
from traitsui.api import View, Item


class 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()

16. TraitsUI基础_第2张图片

Group对象组织界面

Group对象

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

实例

from traits.api import HasTraits, Str, Int
from traitsui.api import View, Item, Group
from traitsui.menu import ModalButtons


class ModelManager(HasTraits):
    model_name = Str
    category = Str
    model_file = Str
    model_number = Int
    vertices = Int

if __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)

16. TraitsUI基础_第3张图片

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

from traits.api import HasTraits, Str, Int
from traitsui.api import View, Item, Group
from traitsui.menu import ModalButtons


class ModelManager(HasTraits):
    model_name = Str
    category = Str
    model_file = Str
    model_number = Int
    vertices = Int

if __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)

16. TraitsUI基础_第4张图片

在外层Group添加orientation = 'horizontal'

16. TraitsUI基础_第5张图片

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, Item
from traits.api import HasTraits, Str, Int


class ModelManager(HasTraits):
    model_name = Str
    category = Str
    model_file = Str
    model_number = Int
    vertices = Int

if __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)

16. TraitsUI基础_第6张图片

使用多个视图对象

from traits.api import HasTraits, Str, Int
from traitsui.api import View, Item, Group

g1 = [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)

16. TraitsUI基础_第7张图片

TraitsUI控件

文本编辑器

from traits.api import HasTraits, Str, Password
from traitsui.api import Item, Group, View


class 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()

16. TraitsUI基础_第8张图片

按钮Button Editor

监听方法对比

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

实例

from traits.api import HasTraits, Button, Int
from traitsui.api import View


class 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()

16. TraitsUI基础_第9张图片

Range滑动条

from traits.api import HasTraits, Int, Range, Property, property_depends_on
from traitsui.api import View, Item, RangeEditor


class 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.b

if __name__ == '__main__':
    ran = RangeDemo()
    ran.configure_traits()

16. TraitsUI基础_第10张图片

菜单、工具栏

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

控件列表

对象 说明
Array 数组空间
Bool 单选框、复选框
Button 按钮
Code 代码编辑器
Color 颜色对话框
Dircetory 目录控件
Enum 枚举控件
File 文件控件
Font 字体选择控件
Html Html网页控件
"""
演示TraitsUI的各种编辑器
"""

import os
from datetime import time
from 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 = item


class 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('hello world')
        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()

你可能感兴趣的:(Python科学计算三维可视化)