Esempio n. 1
0
class ContainerModel(Atom):
    """ A model class for testing atomclist behavior.

    """
    #: A container list with no type checking.
    untyped = ContainerList()

    #: A container list of integers.
    typed = ContainerList(Int())

    #: Change dictionary for the last notification
    change = Value()

    #: Change dictionary for the last notification from static observer on
    #: untyped
    static_untyped_change = Value()

    #: Change dictionary for the last notification from static observer on
    #: typed
    static_typed_change = Value()

    def _observe_untyped(self, change):
        self.static_untyped_change = change

    def _observe_typed(self, change):
        self.static_typed_change = change

    def _changed(self, change):
        self.change = change

    def get_static_change(self, name):
        return getattr(self, 'static_' + name + '_change')
Esempio n. 2
0
class ContourPlugin(Plugin):

    #: Start point
    start_point = ContainerList(Float(strict=False))

    #: End point
    end_point = ContainerList(Float(strict=False))
Esempio n. 3
0
class AreaBase(Model):
    #: Size (in px)
    size = ContainerList(Float(), default=[1800, 2700]).tag(config=True)

    # Left, Top, Right, Bottom (in px)
    padding = ContainerList(Float(), default=[10, 10, 10, 10]).tag(config=True)

    area = Instance(QtCore.QRectF)
    path = Instance(QtGui.QPainterPath)
    padding_path = Instance(QtGui.QPainterPath)

    def _default_area(self):
        return QtCore.QRectF(0, 0, self.size[0], self.size[1])

    def _default_path(self):
        p = QtGui.QPainterPath()
        p.addRect(self.area)
        return p

    def _default_padding_path(self):
        p = QtGui.QPainterPath()
        p.addRect(self.available_area)
        return p

    @observe('size', 'padding')
    def _sync_size(self, change):
        self.area.setWidth(self.size[0])
        self.area.setHeight(self.size[1])
        self.path = self._default_path()
        self.padding_path = self._default_padding_path()

    @property
    def padding_left(self):
        return self.padding[0]

    @property
    def padding_top(self):
        return self.padding[1]

    @property
    def padding_right(self):
        return self.padding[2]

    @property
    def padding_bottom(self):
        return self.padding[3]

    def width(self):
        return self.size[0]

    def height(self):
        return self.size[1]

    @property
    def available_area(self):
        x, y = self.padding_left, self.padding_bottom
        w, h = (self.size[0] - (self.padding_right + self.padding_left),
                self.size[1] - (self.padding_bottom + self.padding_top))
        return QtCore.QRectF(x, y, w, h)
Esempio n. 4
0
class ContainerModel(Atom):
    """ A model class for testing atomclist behavior.

    """
    #: A container list with no type checking.
    untyped = ContainerList()

    #: A container list of integers.
    typed = ContainerList(Int())
Esempio n. 5
0
class MainModel(Atom):
    items = ContainerList()
    checked_items = ContainerList()
    selected_item = Typed(object)

    def toggle_item(self, item, toggled):
        if toggled:
            self.checked_items.append(item)
        else:
            self.checked_items.remove(item)
Esempio n. 6
0
class MapPolygon(ToolkitObject):
    """ A polygon on the map. """

    #: Sets the alpha (opacity) of the marker.
    points = d_(ContainerList(tuple))

    #: Specifies whether this polygon is clickable.
    clickable = d_(Bool())

    #: Adds a holes to the polygon being built.
    #: May be a list of coordinates or multiple coordinate lists
    holes = d_(ContainerList(tuple))

    #: Sets the fill color of the polygon
    fill_color = d_(Unicode())

    #: Specifies whether to draw each segment of this polyline as a geodesic
    geodesic = d_(Bool())

    #: Sets the color of the polygon
    stroke_color = d_(Unicode())

    #: Sets the joint type for all vertices of the polyline except the start and end vertices.
    stroke_joint_type = d_(Enum('', 'bevel', 'round'))

    #: Sets the width of the polyline in screen pixels.
    stroke_width = d_(Float(10, strict=False))

    #: Sets the visibility for the polygon.
    visible = d_(Bool(True))

    #: Sets the zIndex for the polygon.
    zindex = d_(Float(strict=False))

    #: Line clicked
    #: event value will have a 'result' that can be set to True
    #: to indicate the event was handled
    clicked = d_(Event(dict), writable=False)

    #: A reference to the proxy object.
    proxy = Typed(ProxyMapPolygon)

    @observe('points', 'clickable', 'holes', 'fill_color', 'geodesic',
             'stroke_joint_type', 'stroke_width', 'visible', 'zindex')
    def _update_proxy(self, change):
        """ An observer which sends the state change to the proxy.

        """
        if change['type'] == 'container':
            #: Only update what's needed
            self.proxy.update_points(change)
        else:
            super(MapPolygon, self)._update_proxy(change)
Esempio n. 7
0
class PlotItem2D(PlotItem):

    #: x-axis values, as a list
    x = d_(ContainerList())

    #: y-axis values, as a list
    y = d_(ContainerList())

    @observe('x', 'y')
    def _update_proxy(self, change):
        """ An observer which sends state change to the proxy.
        """
        # The superclass handler implementation is sufficient.
        super(PlotItem2D, self)._update_proxy(change)
Esempio n. 8
0
class DataSet(ToolkitObject):
    #: Data this chart displays
    data = d_(ContainerList())

    #: Series color(s)
    colors = d_(Instance((list, basestring)))

    #: Label text
    text = d_(Unicode())

    #: Label color
    text_color = d_(Unicode())

    #: Icon resource
    icons = d_(Unicode())

    #: Show icons, None is default
    show_icons = d_(Enum(None, False, True))

    @observe('data', 'colors', 'text', 'text_color', 'icons', 'show_icons')
    def _update_proxy(self, change):
        """ An observer which sends the state change to the proxy.

        """
        if change['name'] == 'data' and change['type'] == 'container':
            self.proxy.update_data(change)
        else:
            super(DataSet, self)._update_proxy(change)
Esempio n. 9
0
class Test(Atom):
    tt = Typed(subtest, ())
    tc = Coerced(int)
    tb = Bool()
    ti = Int().tag(unit_factor=10, show_value=True, unit="dog", spec="sinbox")
    tl = ContainerList(
        default=[0, True, 3, 5, 6, True, False, False, 3, 4, 5, 6]).tag(
            no_spacer=True)
    te = Enum("tc", "ti").tag(spec="attribute")

    @property
    def run_funcs(self):
        """class or static methods to include in run_func_dict on initialization. Can be overwritten in child classes"""
        return []

    @Callable
    def myc(self):
        print "myc called"

    @cached_property
    def te_mapping(self):
        return {"tc": self.tc, "ti": self.ti}

    def _observe_tc(self, change):
        print change

    def _observe_tb(self, change):
        print change

    def _observe_ti(self, change):
        print change
Esempio n. 10
0
class JDF_Array(Atom):
    """describes a jdf array. defaults to an array centered at 0,0 with one item.
    array_num=0 corresponds to the main array"""
    array_num = Coerced(int)  #Int()
    x_start = Coerced(int)  #Int()
    x_num = Coerced(int, (1, ))  #Int(1)
    x_step = Coerced(int)  #Int()
    y_start = Coerced(int)  #Int()
    y_num = Coerced(int, (1, ))  #Int(1)
    y_step = Coerced(int)  #Int()
    assigns = ContainerList().tag(no_spacer=True)  # inside_type=jdf_assign)

    def add_assign(self, tempstr, comment):
        assign_type = tempstr.split("ASSIGN")[1].split("->")[0].strip().split(
            "+")
        assign_type = [unicode(at) for at in assign_type]
        pos_assign = []
        shot_assign = ""
        for item in tempstr.split("->")[1].partition("(")[2].rpartition(
                ")")[0].split(")"):
            if "(" in item:
                xcor, ycor = item.split("(")[1].split(",")
                pos_assign.append((xcor, ycor))
            elif "," in item:
                shot_assign = unicode(item.split(",")[1].strip())
        self.assigns.append(
            JDF_Assign(assign_type=assign_type,
                       pos_assign=pos_assign,
                       shot_assign=shot_assign,
                       assign_comment=comment))
Esempio n. 11
0
class Wire(Shape):
    """ A Wire is a Path or series of Segment, Arcs, etc... All child items
    must be connected or an error will be thrown.
    
    Attributes
    ----------
    
    edges: List, optional
        Edges used to build the wire.  
         
    Examples
    ---------
    
    Wire:
        Polygon:
            closed = True
            Looper:
                iterable = [(0, 0, 0), (10, 0, 0), (10, 10, 0), (0, 10, 0)]
                Point:
                    position = loop_item
    
    
    """
    proxy = Typed(ProxyWire)

    #: Edges used to create this wire
    edges = d_(ContainerList((TopoDS_Edge, TopoDS_Wire)))

    @observe('edges')
    def _update_proxy(self, change):
        super(Wire, self)._update_proxy(change)
Esempio n. 12
0
class AbstractMonitorRule(HasPrefAtom):
    """
    """
    # Name of the rule.
    name = Str().tag(pref=True)

    # List of database entries suffixes used to identify the entries which
    # contributes to the rule.
    suffixes = ContainerList(Str()).tag(pref=True)

    # Name of the class used for persistence.
    class_name = Str().tag(pref=True)

    def try_apply(self, new_entry, monitor):
        """ Attempt to apply the rule.

        Parameters
        ----------
        new_entry : str
            Database path of the newly added entry.

        monitor : TextMonitor
            Instance of the text monitor trying to apply the rule.

        """
        raise NotImplementedError()

    def _default_class_name(self):
        """ Default factory for the class_name attribute

        """
        return type(self).__name__
Esempio n. 13
0
class DataPlugin(Plugin):

    parameters = ContainerList()
    trial_log = Typed(pd.DataFrame)

    def prepare(self):
        pass

    def prepare_trial_data(self, context_info):
        #columns = context_info.keys()
        arrays = dict((k, np.array([], dtype=i['dtype'])) \
                       for k, i in context_info.items())
        self.trial_log = pd.DataFrame(arrays)
        point = self.workbench.get_extension_point(TRIAL_POINT)
        for extension in point.extensions:
            for data in extension.get_children(TrialData):
                data.prepare(context_info)
            if extension.factory is not None:
                for data in extension.factory(self.workbench):
                    data.prepare(context_info)

    def process_trial(self, results):
        self.trial_log = self.trial_log.append(results, ignore_index=True)
        point = self.workbench.get_extension_point(TRIAL_POINT)
        for extension in point.extensions:
            for data in extension.get_children(TrialData):
                data.process_trial(results)
                data.trial_log_updated(self.trial_log)
            if extension.factory is not None:
                for data in extension.factory():
                    data.process_trial(results)
                    data.trial_log_updated(self.trial_log)
Esempio n. 14
0
class Line(Edge):
    """ Creates a Line passing through the position and parallel to vector 
    given by the direction.
    
    Attributes
    ----------
        position: Tuple
            The position of the line.
        direction: Tuple
            The direction of the line.
             
    Examples
    --------
    
    Line:
        position = (10, 10, 10)
        direction = (0, 0, 1)
    
    """
    proxy = Typed(ProxyLine)
    
    #: List of points
    points = d_(ContainerList(tuple))
    
    @observe('points')
    def _update_proxy(self, change):
        super(Line, self)._update_proxy(change)
Esempio n. 15
0
class BaseSelector(SimpleState, Declarative):

    context_info = Typed(dict, {})
    parameters = ContainerList()
    updated = Event()

    def append_parameter(self, parameter):
        self.insert_parameter(len(self.parameters), parameter)
        self.updated = True

    def remove_parameter(self, parameter):
        self.parameters.remove(parameter)
        self.updated = True

    def insert_parameter(self, index, parameter):
        self.parameters.insert(index, parameter)
        self.updated = True

    def find_parameter(self, name):
        for p in self.parameters:
            if p.name == name:
                return p

    def move_parameter(self, parameter, after=None):
        if parameter == after:
            return
        self.parameters.remove(parameter)
        if after is None:
            index = 0
        else:
            index = self.parameters.index(after) + 1
        self.parameters.insert(index, parameter)
        self.updated = True
Esempio n. 16
0
class ThickSolid(Offset):
    """ An operation that creates a hollowed out solid from shape.
    
    Attributes
    ----------
    
    closing_faces: List, optional
        List of faces that bound the solid.
        
    Examples
    --------
    
    ThickSolid:
        #: Creates an open box with a thickness of 0.1
        offset = 0.1
        Box: box1:
            position = (4,-4,0)
        # Get top face
        closing_faces << [sorted(box1.shape_faces,key=top_face)[0]] 
        
    """
    #: Reference to the implementation control
    proxy = Typed(ProxyThickSolid)

    #: Closing faces
    closing_faces = d_(ContainerList()).tag(view=True, group='ThickSolid')

    @observe('closing_faces')
    def _update_proxy(self, change):
        super(ThickSolid, self)._update_proxy(change)
Esempio n. 17
0
class ListView(ViewGroup):
    """A widget for displaying a large scrollable list of items."""

    #: List of items to display
    items = d_(ContainerList())

    #: use this setting to improve performance if you know that changes
    #: in content do not change the layout size of the RecyclerView
    fixed_size = d_(Bool())

    #: Layout manager to use
    arrangement = d_(Enum("linear", "grid", "staggered"))

    #: Orientation
    orientation = d_(Enum("vertical", "horizontal"))

    #: Span count (only for grid and staggered)
    span_count = d_(Int())

    #: A reference to the ProxyLabel object.
    proxy = Typed(ProxyListView)

    # -------------------------------------------------------------------------
    # Observers
    # -------------------------------------------------------------------------
    @observe("items", "arrangement", "orientation", "span_count", "fixed_size")
    def _update_proxy(self, change):

        super()._update_proxy(change)

    def scroll_to(self, x: int, y: int):
        """Scroll to the given x,y coordinates within the list"""
        if proxy := self.proxy:
            proxy.scroll_to(x, y)
Esempio n. 18
0
class PlotView(Control):
    hug_width = set_default('ignore')
    hug_height = set_default('ignore')
    proxy = Typed(ProxyPlotView)
    data = d_(ContainerList())
    setup = d_(Callable(lambda graph: None))

    title = d_(Str())
    labels = d_(Dict(Str(), Str()))

    axis_scales = d_(Dict(Str(), Float()))

    #background_color = d_(Str())
    #foreground = d_(Str())

    antialiasing = d_(Bool(True))
    aspect_locked = d_(Bool(True))

    grid = d_(Tuple(item=Bool(), default=(False, False)))
    grid_alpha = d_(FloatRange(low=0.0, high=1.0, value=0.5))

    multi_axis = d_(Bool(True))

    @observe('data', 'title', 'labels', 'multi_axis', 'antialiasing',
             'axis_scales', 'grid', 'grid_alpha')
    def _update_proxy(self, change):
        """ An observer which sends state change to the proxy.
        """
        # The superclass handler implementation is sufficient.
        super(PlotView, self)._update_proxy(change)
Esempio n. 19
0
class Node(GraphItem):
    id = Str()
    name = Unicode()

    graph = ForwardTyped(import_graph_type)

    inputs = ContainerList(Socket)
    outputs = ContainerList(Socket)

    input_dict = Property(lambda self: self._mk_input_dict(), cached=True)
    output_dict = Property(lambda self: self._mk_output_dict(), cached=True)

    def _observe_inputs(self, change):
        if change['type'] == 'create':
            for n in change['value']:
                n.node = self
                n.socket_type = SocketType.INPUT
                n.index = change['value'].index(n)
        elif change['type'] == 'container':
            if change['operation'] == 'append':
                change['item'].node = self
                change['item'].socket_type = SocketType.INPUT
                change['item'].index = change['value'].index(n)
            elif change['operation'] == 'remove':
                change['item'].node = None
        self.get_member('input_dict').reset(self)

    def _mk_input_dict(self):
        return {v.name: v for v in self.inputs}

    def _observe_outputs(self, change):
        if change['type'] == 'create':
            for n in change['value']:
                n.node = self
                n.socket_type = SocketType.OUTPUT
                n.index = change['value'].index(n)
        elif change['type'] == 'container':
            if change['operation'] == 'append':
                change['item'].node = self
                change['item'].socket_type = SocketType.OUTPUT
                change['item'].index = change['value'].index(n)
            elif change['operation'] == 'remove':
                change['item'].node = None
        self.get_member('output_dict').reset(self)

    def _mk_output_dict(self):
        return {v.name: v for v in self.outputs}
Esempio n. 20
0
class Chamfer(LocalOperation):
    """ Applies Chamfer operation to the first child shape. 
   
    Attributes
    ----------
    
    distance: Float
       The distance of the chamfer to apply
    distance2: Float
       The second distance of the chamfer to apply
    edges: List of edges, optional
       List of edges to apply the operation to. If not given all edges will
       be used.  Used in conjunction with the `shape_edges` attribute.
    faces: List of faces, optional
       List of faces to apply the operation to. If not given, all faces will
       be used.  Used in conjunction with the `shape_edges` attribute. 
    
    Examples
    --------
    
    Chamfer:
        #: Fillet the top of the cylinder
        faces = [cyl.shape_faces[0]]
        distance = 0.2
        Cylinder: cyl:
           pass
       
    """
    #: Reference to the implementation control
    proxy = Typed(ProxyChamfer)

    #: Distance of chamfer
    distance = d_(Float(1, strict=False)).tag(view=True, group='Chamfer')

    #: Second of chamfer (leave 0 if not used)
    distance2 = d_(Float(0, strict=False)).tag(view=True, group='Chamfer')

    #: Edges to apply chamfer to
    #: Leave blank to use all edges of the shape
    edges = d_(ContainerList()).tag(view=True, group='Chamfer')

    #: Faces to apply the chamfer to
    faces = d_(ContainerList()).tag(view=True, group='Chamfer')

    @observe('distance', 'distance2', 'edges', 'faces')
    def _update_proxy(self, change):
        super(Chamfer, self)._update_proxy(change)
Esempio n. 21
0
class Wire(Shape):
    proxy = Typed(ProxyWire)

    #: Edges used to create this wire
    edges = d_(ContainerList((TopoDS_Edge, TopoDS_Wire)))

    @observe('edges')
    def _update_proxy(self, change):
        super(Wire, self)._update_proxy(change)
Esempio n. 22
0
class MonitorPlugin(Plugin):
    add_newline = Bool(False).tag(config=True)
    strip_whitespace = Bool(False).tag(config=True)
    input_enabled = Bool(True).tag(config=True)
    output_enabled = Bool(True).tag(config=True)
    autoscroll = Bool(True).tag(config=True)

    #: Command history
    history = ContainerList(Str()).tag(config=True)
Esempio n. 23
0
class Transform(Operation):
    """ An operation that Transform's an existing shape (or a copy).
    
    Attributes
    ----------
    
    shape: Shape or None
        Shape to transform. If none is given it will use the first child. If
        given it will make a transformed copy the reference shape.
    mirror: Tuple or List
        Mirror transformation to apply to the shape. Should be a list for each
        axis (True, False, True).
    scale: Tuple or List
        Scale to apply to the shape. Should be a list of float values 
        for each axis ex. (2, 2, 2).
    rotate: Tuple or List
        Rotation to apply to the shape. Should be a list of float values 
        (in radians) for each axis ex. (0, math.pi/2, 0).
    translate: Tuple or List
        Translation to apply to the shape. Should be a list of float values 
        for each axis ex. (0, 0, 100).
        
    Examples
    --------
    
    Transform:
        operations = [Rotate(direction=(1, 0, 0), angle=math.pi/4)]
        Box: box:
            pass
            
    #: Or
    Cylinder: cyl
        pass
    
    Transform:
        #: Create a copy and move it
        shape = cyl
        operations = [
            Translate(x=10, y=20, z=0),
            Scale(s=2),
            Rotate(direction=(0,0,1), angle=math.pi/2)
        ]
        
    """
    #: Reference to the implementation control
    proxy = Typed(ProxyTransform)

    #: Shape to transform
    #: if none is given the first child will be used
    shape = d_(Instance(Shape))

    #: Transform ops
    operations = d_(ContainerList(TransformOperation))

    @observe('operations')
    def _update_proxy(self, change):
        super(Transform, self)._update_proxy(change)
Esempio n. 24
0
class TypeRegistry(Atom):
    node_types = ContainerList(NodeType)
    edge_types = ContainerList(EdgeType)

    node_type_name_map = Dict()
    edge_type_name_map = Dict()

    def _observe_node_types(self, change):
        self.node_type_name_map = {v.id: v for v in self.node_types}

    def _observe_edge_types(self, change):
        self.edge_type_name_map = {v.id: v for v in self.edge_types}

    def register_node_type(self, node_type):
        self.node_types.append(node_type)

    def register_edge_type(self, edge_type):
        self.edge_types.append(edge_type)
Esempio n. 25
0
class ContoursList(Atom):
    items = ContainerList()
    selected_items = ContainerList()

    def toggle_item(self, item, toggled):
        if toggled:
            self.selected_items.append(item)
        else:
            self.selected_items.remove(item)

    def toggle_all(self, toggled):
        if toggled:
            self.selected_items = self.items
        else:
            self.selected_items = []

    def items_at_point(self, x, y):
        return [contour for contour in self.items if contour.point_test(x, y)]
Esempio n. 26
0
class ThickSolid(Offset):
    #: Reference to the implementation control
    proxy = Typed(ProxyThickSolid)

    #: Closing faces
    closing_faces = d_(ContainerList()).tag(view=True, group='ThickSolid')

    @observe('closing_faces')
    def _update_proxy(self, change):
        super(ThickSolid, self)._update_proxy(change)
Esempio n. 27
0
class VNAYokoSweep(DataRead):
    Yoko = ContainerList().tag(inside_type=float, plot=True)
    VNA = ContainerList().tag(inside_type=float, xdata='Yoko', plot=True)

    @observe('read_file.read_event')
    def obs_read_event(self, change):
        startYoko = self.read_file.data["Step config"]['Yokogawa - Voltage'][
            'Step items']["data"][0][3]
        stopYoko = self.read_file.data["Step config"]['Yokogawa - Voltage'][
            'Step items']["data"][0][4]
        stepYoko = self.read_file.data["Step config"]['Yokogawa - Voltage'][
            'Step items']["data"][0][8]
        self.Yoko = ascontiguousarray(
            linspace(startYoko, stopYoko, stepYoko),
            dtype=float)  #self.data="".join(str(self.read_file.data))
        self.VNA = ascontiguousarray(
            self.read_file.data["Traces"]
            ['Rohde&Schwarz Network Analyzer - S21']['data'],
            dtype=float)
Esempio n. 28
0
class AbstractMonitorRule(PrefAtom):
    """
    """
    name = Str().tag(pref=True)
    suffixes = ContainerList(Str()).tag(pref=True)

    def try_apply(self, new_entry, entries):
        """
        """
        raise NotImplementedError()
Esempio n. 29
0
class Chamfer(LocalOperation):
    #: Reference to the implementation control
    proxy = Typed(ProxyChamfer)

    #: Distance of chamfer
    distance = d_(Float(1, strict=False)).tag(view=True, group='Chamfer')

    #: Second of chamfer (leave 0 if not used)
    distance2 = d_(Float(0, strict=False)).tag(view=True, group='Chamfer')

    #: Edges to apply fillet to
    #: Leave blank to use all edges of the shape
    edges = d_(ContainerList()).tag(view=True, group='Chamfer')

    faces = d_(ContainerList()).tag(view=True, group='Chamfer')

    @observe('distance', 'distance2', 'edges', 'faces')
    def _update_proxy(self, change):
        super(Chamfer, self)._update_proxy(change)
Esempio n. 30
0
class TreeViewItem(AbstractWidgetItem):
    #: Proxy reference
    proxy = Typed(ProxyTreeViewItem)

    #: The child items
    items = d_(ContainerList(default=[]))

    #: First visible row
    visible_row = d_(Int(0))

    #: Number of rows visible
    visible_rows = d_(Int(100))

    #: First visible column
    visible_column = d_(Int(0))

    #: Number of columns visible
    visible_columns = d_(Int(1))

    def _get_items(self):
        """ Items should be a list of child TreeViewItems excluding
            columns.
        """
        return [c for c in self.children if isinstance(c, TreeViewItem)]

    def _get_columns(self):
        """ List of child TreeViewColumns including 
            this item as the first column
        """
        return [self] + [
            c for c in self.children if isinstance(c, TreeViewColumn)
        ]

    #: Columns
    _columns = Property(lambda self: self._get_columns(), cached=True)

    def child_added(self, child):
        super(TreeViewItem, self).child_added(child)
        self.get_member('_columns').reset(self)
        self._update_rows()

    def child_removed(self, child):
        super(TreeViewItem, self).child_removed(child)
        self.get_member('_columns').reset(self)
        self._update_rows()

    def _update_rows(self):
        """ Update the row and column numbers of child items. """
        for row, item in enumerate(self._items):
            item.row = row  # Row is the Parent item
            item.column = 0

        for column, item in enumerate(self._columns):
            item.row = self.row  # Row is the Parent item
            item.column = column