MVC and InstanceEditor

54 views
Skip to first unread message

Yann Goudard

unread,
Nov 18, 2021, 11:03:41 AM11/18/21
to Enthought Tool Suite users
Hi everyone,
I use traitsui for some time now and I think I have missed something. I do prefer separating the view from the model and writing it inside a Controller or ModelView class. The documentation explain how and I have found simple examples. But I have found nothing that would allow me to use it in nested objects (and I write complex applications with a lot of depth). I am used to write this kind of code:

import traits.api as tapi
import traitsui.api as tuiapi


class Building(tapi.HasTraits):
    name = tapi.Str("Home")
    rooms = tapi.List(tapi.Instance("Room"))


class Room(tapi.HasTraits):
    name = tapi.Str
    level = tapi.Int


class BuildingHandler(tuiapi.Controller):

    room_handlers = tapi.List(tapi.Instance("RoomHandler"))

    def add_room(self):
        new_room = Room()
        self.model.rooms.append(new_room)
        return RoomHandler(model=new_room)

    def default_traits_view(self):
        return tuiapi.View(
            tuiapi.Readonly("name"),
            tuiapi.Item(
                "handler.room_handlers",
                editor=tuiapi.ListEditor(
                    editor=tuiapi.InstanceEditor(),      
                    style="custom",
                    item_factory=self.add_room
                ),
            ),
            width=400,
            height=400,
            resizable=True,
        )


class RoomHandler(tuiapi.Controller):
    def default_traits_view(self):
        return tuiapi.View(
            tuiapi.Item("name"),
            tuiapi.Item(
                "level",
                editor=tuiapi.RangeEditor(
                    low=-1, high=15, mode="spinner"
                )
            )
        )


BuildingHandler(model=Building()).configure_traits()

(This simplified example that does not manage very well deletion.)
I would prefer to declare a handler with a view within to InstanceEditor. Something like:

class BuildingHandler(tuiapi.Controller):
    def default_traits_view(self):
        return tuiapi.View(
            tuiapi.Readonly("name"),
            tuiapi.Item(
                "rooms",
                editor=tuiapi.ListEditor(
                    editor=tuiapi.InstanceEditor(
                        handler=RoomHandler
                    ),
                    style="custom",
                    item_factory=Room
                )
            ),
            width=400,
            height=400,
            resizable=True,
        )


This does not work because "handler" is not an InstanceEditor keyword but I hope you get the idea.
The 7.2 version of traitsui throws me new errors (In traitsui.editor.Editor._update_editor: Notifier not found) and it seems to me that I will have to rewrite some parts of my applications. Before doing anything, I would be glad to learn from you the right way.
Thanks,

Yann
Reply all
Reply to author
Forward
0 new messages