Items on dataviewlistctrl

Im confused with Item on dataviewlistctrl the items just can be array or can be other type and how to delete that some item selected?
I was using a list of model on myclass extend from wxdataviewIndexlistmodel and override some method but cant deleted when call DeleteAllItems at DataviewListStore how to see the code below.
view=wx.DataViewListCtrl()
View.AssociationModel(myclass([mymodel of sqlalchemy]))
view.Getstore().DeleteAllITems()
In it stop and closed the programs hay happens that?

Note.
Im using persistant database with sqlalchemy and i have using wxdataviewlistctrl..

Sorry for my bad English try to explain again my problem, I can’t delete all item in my DataviewListCtrl class when a call to self.DeleteAllItems() then my app stop, why happends that? my all class below

···

#-------------------------------------------------------------------------------------------------------------

class DataViewListCtrl(dv.DataViewListCtrl):

    def __init__(self, *args, **kw):
        super(DataViewListCtrl, self).__init__(*args, **kw)
        self.Bind(wx.EVT_MENU, self.OnMenu)
        self.Bind(dv.EVT_DATAVIEW_ITEM_CONTEXT_MENU, self.OnContextMenu)
        self.Bind(EVT_DATAVIEW_ITEM_DELETED, self.OnDelete)
        self.Bind(EVT_DATAVIEW_ITEM_UPDATE, self.OnUpdate)

    def OnMenu(self, evt):
        model = self.GetModel()
        if evt.Id== ID_DELETE:
            new_evt=EventDataViewItemDeleted(self.GetId(), model.Data[self.SelectedRow])
        elif evt.Id == ID_UPDATE:
            new_evt = EventDataViewItemUpdate(self.GetId(), model.Data[self.SelectedRow])
        else:
            evt.Skip()
        if new_evt:
            new_evt.SetEventObject(self)
            wx.PostEvent(self.GetEventHandler(), new_evt)

    def OnContextMenu(self, evt):
        if self.GetItemCount() > 0:
            if self.GetSelectedItemsCount()>0:
                menu=wx.Menu()
                if not isinstance(self.GetModel(), DetallesIndexListModel):
                    menu.Append(ID_UPDATE, 'actualizar')
                menu.Append(ID_DELETE, 'eliminar')
                self.PopupMenu(menu)
                del menu

    def OnDelete(self, evt):
        if evt.EventObject:
            model = evt.GetDBModel()
            if model:
                del model
            evt.EventObject.GetStore().RowDeleted(self.SelectedRow)

    def OnUpdate(self, evt):
        pass

    def DeleteAllItems(self):
        if isinstance(self.Store, dv.DataViewListStore):
            self.Store.DeleteAllItems() #when i call on it my app to stop


#----------------------------------------------------------------------

class DataViewIndexListModel(dv.DataViewIndexListModel):
__columnsView=
__listModel =

@property
def Data(self):
    return self.__listModel

@Data.setter
def Data(self, value):
    if isinstance(value, list):
        self.__listModel=value

@property
def ColumnView(self):
    return self.__columnsView

@ColumnView.setter
def ColumnView(self, value):
    if not value:
        if isinstance(self.Data, list) and len(self.Data) > 0:
            for colmun in self.Data.pop(0).__table__.columns:
                self.__columnsView.append(colmun.key)
    elif isinstance(value, list):
        self.__columnsView=value

def __init__(self, data, columnView=None, log=sys.stdout):
    dv.DataViewVirtualListModel.__init__(self, len(data))
    self.Data = data
    self.ColumnView=columnView
    self.log = log

def GetColumnCount(self):
    return len(self.ColumnView)

# Report the number of rows in the model
def GetCount(self):
    # self.log.write('GetCount')
    return len(self.Data)

# Map the data column numbers to the data type
def GetColumnType(self, col):
    return 'string'

# This method is called to provide the data object for a
# particular row,col
def GetValueByRow(self, row, col):
    # self.log.write('GetValueByRow:row<{0}>col<{1}>'.format(row, col))
    value = self.Data[row].__getattribute__(self.ColumnView[col])
    if isinstance(value, int):
        value=str(value)
    return value if value else ''

# This method is called when the user edits a data item in the view.
def SetValueByRow(self, value, row, col):
    # self.log.write("SetValueByRow: (%d,%d) %s\n" % (row, col, value))
    self.Data[row].__setattr__(self.ColumnView[col], value)
    return True

def DeleteRows(self, rows):
    # make a copy since we'll be sorting(mutating) the list
    rows = list(rows)
    # use reverse order so the indexes don't change as we remove items
    rows.sort(reverse=True)

    for row in rows:
        # remove it from our data structure
        del self.Data[row]
        # notify the view(s) using this model that it has been removed
        self.RowDeleted(row)

def AddRow(self, value):
    # update data structure
    self.Data.append(value)
    # notify views
    self.RowAppended()
#----------------------------------------------------------------------
class VentasIndexListModel(DataViewIndexListModel):

    # Report how many columns this model provides data for.
    def GetColumnCount(self):
        return 5

    # Map the data column numbers to the data type
    def GetColumnType(self, col):
        mapper = {
            0: 'date', #fecha
            1: 'wxDataViewIconText', #descripcion del producto
            2: 'float', #cantidad
            3: 'float', #precio
            4: 'float', #descuento bs
            5: 'float', #descuento %
            6: 'float', #monto
        }
        return mapper[col]

    # This method is called to provide the data object for a
    # particular row,col
    def GetValueByRow(self, row, col):
        # self.log.write('GetValueByRow:row<{0}>col<{1}>'.format(row, col))
        model = self.Data[row]
        kwargs = dict()
        kwargs['text'] = model.producto.nombre
        if model.producto.Image:
            kwargs['icon'] = wx.Icon(model.producto.Image.Scale(10, 10, wx.IMAGE_QUALITY_HIGH).ConvertToBitmap())
        mapper = {
            0: model.venta.fecha,
            1: dv.DataViewIconText(**kwargs),
            2: model.cantidad,
            3: model.precio,
            4: model.descuentoMoneda if model.descuentoMoneda else 0.0,
            5: model.descuentoPorcentaje if model.descuentoPorcentaje else 0.0,
            6: model.monto
        }
        return mapper[col]

    # This method is called when the user edits a data item in the view.
    def SetValueByRow(self, value, row, col):
        # self.log.write("SetValueByRow: (%d,%d) %s\n" % (row, col, value))

        model = self.Data[row]
        mapper = {
            2: 'cantidad',
            3: 'precio',
            4: 'descuentoMoneda',
            5: 'descuentoPorcentaje',
            6: 'monto'
        }
        if hasattr(model, mapper[col]):
            model.__setattr__(mapper[col], value)

        return True

    # Called to check if non-standard attributes should be used in the
    # cell at (row, col)
    '''
    def GetAttrByRow(self, row, col, attr):
        ##self.log.write('GetAttrByRow: (%d, %d)' % (row, col))
        if col == 3:
            attr.SetColour('blue')
            attr.SetBold(True)
            return True
        return False
    '''

**above all class are about DataViewListCtrl for to show my data and below to show my other class because i have using the MVP pattern for doing that project**

all = [‘VentaPresenter’, ‘FormVentaInteractor’]

import wx
import wx.adv as adv
import wx.lib.agw.floatspin as floatspin
from lib import Presenter, FormInteractor, XrcViewFrame
from lib.dataview import DataViewListCtrl, DataViewNumRender, DetallesIndexListModel, DataViewIndexListModel, VentasIndexListModel
import wx.dataview as dv
from . import (ClientePresenter, ProductoPresenter, FormClienteInteractor, FormProductoInteractor)
from models import (Base, DetalleVenta, Cliente, Producto, Ferreteria, Venta)
from sqlalchemy import or_, String, Column
import re
import sys
import datetime
from dateutil.parser import parse

class VentaPresenter(Presenter):
__modelCliente =
__modelProducto =
__modelDetalleVenta =
__newModelDetalleVenta = None
__actionDetalleVenta={}

@property
def cliente(self):
    return self.__modelCliente

@cliente.setter
def cliente(self, value):
    if isinstance(value, Base):
        self.__modelCliente.append(value)
    if isinstance(value, list) or isinstance(value, tuple):
        self.__modelCliente = value

@property
def producto(self):
    return self.__modelProducto

@producto.setter
def producto(self, value):
    if isinstance(value, Base):
        self.__modelProducto.append(value)
    if isinstance(value, list) or isinstance(value, tuple):
        self.__modelProducto = value

@property
def detalleVentas(self):
    return self.__modelDetalleVenta

@detalleVentas.setter
def detalleVentas(self, value):
    if isinstance(value, Base):
        self.__modelDetalleVenta.append(value)
    if isinstance(value, list) or isinstance(value, tuple):
        self.__modelDetalleVenta = value

@property
def newDetalleVenta(self):
    if not self.__newModelDetalleVenta:
        self.__newModelDetalleVenta = DetalleVenta()
    return self.__newModelDetalleVenta

@newDetalleVenta.setter
def newDetalleVenta(self, value):
    if isinstance(value, Base) or value == None:
        self.__newModelDetalleVenta = value
    else:
        raise TypeError

def initView(self):
    if isinstance(self.model, list):
        ctrl = self.view.GetCtrl('list')
        if ctrl:
            ctrl.AppendDateColumn('Fecha', 0, width=100)
            #render = DataViewNumRender(sys.stdout, mode=dv.DATAVIEW_CELL_INERT, fractionWidth=0)
            #column = dv.DataViewColumn('Nro. Item', render, 1, width=85)
            # column.Alignment = wx.ALIGN_LEFT
            #ctrl.AppendColumn(column, 'int')
            ctrl.AppendIconTextColumn('Producto', dv.DATAVIEW_CELL_INERT, width=300)
            # ctrl.AppendTextColumn('Producto', dv.DATAVIEW_CELL_EDITABLE, width=400)
            render = DataViewNumRender(sys.stdout, mode=dv.DATAVIEW_CELL_INERT, fractionWidth=2)
            column = dv.DataViewColumn('Cantidad', render, 2, width=80)
            # column.Alignment = wx.ALIGN_LEFT
            ctrl.AppendColumn(column, 'float')

            render = DataViewNumRender(sys.stdout, mode=dv.DATAVIEW_CELL_EDITABLE, fractionWidth=2)
            column = dv.DataViewColumn('Precio', render, 3, width=80)
            # column.Alignment = wx.ALIGN_LEFT
            ctrl.AppendColumn(column, 'float')

            render = DataViewNumRender(sys.stdout, mode=dv.DATAVIEW_CELL_EDITABLE, fractionWidth=2)
            column = dv.DataViewColumn('Descuento(Bs)', render, 4, width=90)
            # column.Alignment = wx.ALIGN_LEFT
            ctrl.AppendColumn(column, 'float')

            render = DataViewNumRender(sys.stdout, mode=dv.DATAVIEW_CELL_INERT, fractionWidth=2, min=0.0,
                                       max=100.0)
            column = dv.DataViewColumn('Descuento(%)', render, 5, width=90)
            # column.Alignment = wx.ALIGN_LEFT
            ctrl.AppendColumn(column, 'float')

            render = DataViewNumRender(sys.stdout, mode=dv.DATAVIEW_CELL_INERT, fractionWidth=2)
            column = dv.DataViewColumn('Monto', render, 6, width=100)
            # column.Alignment = wx.ALIGN_LEFT
            ctrl.AppendColumn(column, 'float')
            ctrl.AssociateModel(VentasIndexListModel(self.model, sys.stdout))

    else:
        super(VentaPresenter, self).initView()
        ctrl = self.view.GetCtrl('detalleVentas')
        if ctrl:
            ctrl.AppendIconTextColumn('Producto', dv.DATAVIEW_CELL_INERT, width=400)
            #ctrl.AppendTextColumn('Producto', dv.DATAVIEW_CELL_EDITABLE, width=400)
            render = DataViewNumRender(sys.stdout, mode=dv.DATAVIEW_CELL_EDITABLE, fractionWidth=2)
            column = dv.DataViewColumn('Cantidad', render, 1, width=100)
            #column.Alignment = wx.ALIGN_LEFT
            ctrl.AppendColumn(column, 'float')

            render = DataViewNumRender(sys.stdout, mode=dv.DATAVIEW_CELL_EDITABLE,fractionWidth=2)
            column = dv.DataViewColumn('Precio', render, 2, width=100)
            #column.Alignment = wx.ALIGN_LEFT
            ctrl.AppendColumn(column, 'float')

            render = DataViewNumRender(sys.stdout, mode=dv.DATAVIEW_CELL_EDITABLE, fractionWidth=2)
            column = dv.DataViewColumn('Descuento(Bs)', render, 3, width=100)
            #column.Alignment = wx.ALIGN_LEFT
            ctrl.AppendColumn(column, 'float')

            render = DataViewNumRender(sys.stdout, mode=dv.DATAVIEW_CELL_EDITABLE, fractionWidth=2, min=0.0, max=100.0)
            column = dv.DataViewColumn('Descuento(%)', render, 4, width=100)
            #column.Alignment = wx.ALIGN_LEFT
            ctrl.AppendColumn(column, 'float')

            render = DataViewNumRender(sys.stdout, mode=dv.DATAVIEW_CELL_EDITABLE, fractionWidth=2)
            column = dv.DataViewColumn('Monto', render, 5, width=100)
            #column.Alignment = wx.ALIGN_LEFT
            ctrl.AppendColumn(column, 'float')

            ctrl.AssociateModel(DetallesIndexListModel(self.model.detalleVentas, sys.stdout))

def CtrlChange(self, ctrl, model=None):
    if hasattr(self.newDetalleVenta, ctrl.Name):
        super(VentaPresenter, self).CtrlChange(ctrl, self.newDetalleVenta)
        if ctrl.Name!='producto':
            if not self.newDetalleVenta.producto:
                _ctrl = self.view.GetCtrl('producto')
                if _ctrl:
                    _ctrl.SetFocus()
                return

            if ctrl.Name=='cantidad':
                #self.newDetalleVenta.monto=self.newDetalleVenta.cantidad*self.newDetalleVenta.precio
                _ctrl = self.view.GetCtrl('monto')
                if _ctrl:
                    _ctrl.SetValue(self.newDetalleVenta.monto)

            if ctrl.Name == "descuentoMoneda":
                if self.newDetalleVenta.cantidad <= 0.0:
                    _ctrl = self.view.GetCtrl('cantidad')
                    if _ctrl:
                        _ctrl.SetFocus()
                '''
                self.newDetalleVenta.monto = (self.newDetalleVenta.cantidad*self.newDetalleVenta.precio)-self.newDetalleVenta.descuentoMoneda
                self.newDetalleVenta.descuentoPorcentaje=(100*self.newDetalleVenta.descuentoMoneda)/self.newDetalleVenta.monto
                '''
                _ctrl = self.view.GetCtrl('monto')
                if _ctrl:
                    _ctrl.SetValue(self.newDetalleVenta.monto)
                _ctrl = self.view.GetCtrl('descuentoPorcentaje')
                if _ctrl:
                    _ctrl.SetValue(self.newDetalleVenta.descuentoPorcentaje)

            if ctrl.Name == "descuentoPorcentaje":
                if self.newDetalleVenta.cantidad <= 0.0:
                    _ctrl = self.view.GetCtrl('cantidad')
                    if _ctrl:
                        _ctrl.SetFocus()
                '''
                self.newDetalleVenta.monto = (self.newDetalleVenta.cantidad*self.newDetalleVenta.precio)*(self.newDetalleVenta.descuentoPorcentaje/100)
                self.newDetalleVenta.descuentoMoneda=(self.newDetalleVenta.monto*self.newDetalleVenta.descuentoPorcentaje)/100
                '''
                _ctrl=self.view.GetCtrl('monto')
                if _ctrl:
                    _ctrl.SetValue(self.newDetalleVenta.monto)
                _ctrl=self.view.GetCtrl('descuentoMoneda')
                if _ctrl:
                    _ctrl.SetValue(self.newDetalleVenta.descuentoMoneda)
    else:
        super(VentaPresenter, self).CtrlChange(ctrl, self.model)
        if ctrl.Name=='efectivo':
            #self.model.cambio = self.model.total-self.model.efectivo
            _ctrl = self.view.GetCtrl('cambio')
            if _ctrl:
                _ctrl.SetValue(self.model.cambio)

def addNewCliente(self):
    model = Cliente()
    model.ferreteria = Ferreteria.query.first()
    if not model.ferreteria:
        wx.MessageBox('No existe Ferreteria Registrado!.',
                      style=wx.CENTER|wx.ICON_QUESTION|wx.OK)
        return
    ClientePresenter(model, XrcViewFrame(self.view, 'views/rc/FormCliente.xrc', 'FormCliente'), FormClienteInteractor())

def addNewProducto(self):
    ProductoPresenter(Producto(), XrcViewFrame(self.view, 'views/rc/FormProducto.xrc', 'FormProducto'), FormProductoInteractor())

def addDetalle(self):
    if self.newDetalleVenta:
        if not isinstance(self.newDetalleVenta.producto, Base):
            ctrl = self.view.GetCtrl('producto')
            if ctrl:
                tooltip = wx.adv.RichToolTip("No selecciona", 'Debe selecciona un producto')
                tooltip.ShowFor(ctrl)
                ctrl.SetFocus()
            return
        if self.newDetalleVenta.precio <= 0.0:
            ctrl = self.view.GetCtrl('precio')
            if ctrl:
                tooltip = wx.adv.RichToolTip("Sin precio", 'Debe ingresar el precio del producto seleccionado')
                tooltip.ShowFor(ctrl)
                ctrl.SetFocus()
            return
        if self.newDetalleVenta.cantidad <= 0.0:
            ctrl = self.view.GetCtrl('cantidad')
            if ctrl:
                tooltip = wx.adv.RichToolTip("Sin cantidad", 'Debe ingresar la cantidad del producto seleccionado')
                tooltip.ShowFor(ctrl)
                ctrl.SetFocus()
            return

        self.detalleVenta = self.newDetalleVenta
        self.model.detalleVentas.append(self.newDetalleVenta)
        if self.model.total:
            self.model.total += self.newDetalleVenta.monto
        else:
            self.model.total=self.newDetalleVenta.monto

        _ctrl = self.view.GetCtrl('detalleVentas')
        if isinstance(_ctrl, dv.DataViewListCtrl):
            model=_ctrl.GetModel()
            if isinstance(model, DetallesIndexListModel):
                model.RowAppended()
            _ctrl.Refresh()

        ctrl = self.view.GetCtrl('total')
        if ctrl:
            ctrl.SetValue(self.model.total)

        self.newDetalleVenta = DetalleVenta()
        for column in self.newDetalleVenta.__table__.columns:
            _ctrl=self.view.GetCtrl(column.key)
            if isinstance(_ctrl, floatspin.FloatSpin):
                if not _ctrl.Enable:
                    _ctrl.Enable(True)
                _ctrl.SetValue(_ctrl._defaultvalue)
        ctrl = self.view.GetCtrl('producto')
        if ctrl:
            self.producto = []
            ctrl.Clear()

def CtrlSelected(self, ctrl):
    if ctrl.Name=='producto':
        if ctrl.Selection != wx.NOT_FOUND:
            self.newDetalleVenta.__setattr__(ctrl.Name, self.__getattribute__(ctrl.Name)[ctrl.Selection])
            if self.newDetalleVenta.producto:
                self.newDetalleVenta.precio=self.newDetalleVenta.producto.precio
                _ctrl = self.view.GetCtrl('precio')
                if _ctrl:
                    _ctrl.SetValue(self.newDetalleVenta.precio)
                    _ctrl.Enable(False)
    else:
        super(VentaPresenter, self).CtrlSelected(ctrl)

def deleteItem(self, item):
    if isinstance(item, wx.ListItem):
        match = re.compile('\[(.*?)\]').match(item.Data)
        if not match:
            return
        detalleVentas = []
        for detalleVenta in self.model.detalleVentas:
            if detalleVenta.id == match[1]:
                continue
            detalleVentas.append(detalleVenta)
        self.model.detalleVentas = detalleVentas

def print(self):

    html = "<div>fecha:{0}\n nit/ci:{1}\nseñor(es):{2}\n\n</div>".format(self.model.fecha, self.model.cliente.cinit, self.model.cliente.nombre)
    html_detalle="<table><tr> \
                    <th>Cantidad</th> \
                    <th>Producto</th> \
                    <th>Precio</th> \
                    <th>Decuento(Bs)</th> \
                    <th>Descento(%)</th> \
                    <th>SubTotal</th> \
                </tr>"
    for detalle in self.model.detalleVentas:
        html_detalle += "<tr> \
                    <td>{0}</td> \
                    <td>{1}</td> \
                    <td>{2}</td> \
                    <td>{3}</td> \
                    <td>{4}</td> \
                    <td>{5}</td> \
                </tr>".format(detalle.cantidad, detalle.producto.nombre, detalle.producto.precio, detalle.descuentoPorcentaje, detalle.descuentoMoneda, detalle.monto)
    html_detalle += "</table>"

    html +="<div>{0}</div><div>Total a paga:{1}\nPago efectivo:{2}\nCambio:{3}</div>".format(html_detalle, self.model.total, self.model.efectivo, self.model.cambio)
    #eprint = PrintRecibo()
    #eprint.Print(html, "Test - Page @PAGENUM@/@PAGESCNT@ @TITLE@")
def Search(self, ctrl):
    value = ctrl.GetValue()
    print(value)
    if ctrl.Name == 'buscar':
        if re.match('^[0-3]?[0-9].[0-3]?[0-9].(?:[0-9]{2})?[0-9]{2}$', value):
            date = parse(value)
            self.model = Venta.query.with_entities(DetalleVenta).filter(
                Venta.fecha.between(date, date.replace(day=date.day + 1))).all()
        else:
            self.model = Producto.query.with_entities(DetalleVenta).filter(
                Producto.nombre.like("%{0}%".format(value))).all()
        _ctrl = self.view.GetCtrl('list')
        if isinstance(_ctrl, DataViewListCtrl) and self.model:
            _ctrl.DeleteAllItems() # in it to stop my app
            #_ctrl.AssociateModel(VentasIndexListModel(self.model, sys.stdout))
            #_ctrl.Refresh()

#------------------------------------------------------------------------------

from lib.interactor import ListInteractor
class ListVentaInteractor(ListInteractor):
    def Bind(self):
        super(ListVentaInteractor, self).Bind()
        ctrl = self.view.GetCtrl('buscar')
        if ctrl:
            ctrl.Bind(wx.EVT_TEXT, self.OnSearch)

        ctrl = self.view.GetCtrl('fechaInicial')
        if ctrl:
            ctrl.Bind(wx.EVT_TEXT, self.OnSearch)

        ctrl = self.view.GetCtrl('fechaFinal')
        if ctrl:
            ctrl.Bind(wx.EVT_TEXT, self.OnSearch)
    def OnSearch(self, evt):
        self.presenter.Search(evt.GetEventObject())

So I load two image when to show my GUI and when to stop my app I don't understand why happend that
so thanks for your help me.
sorry for my bad english again so thanks to all

El jueves, 23 de noviembre de 2017, 4:38:57 (UTC-8), Juvenal Claros escribió:

Note.
Im using persistant database with sqlalchemy and i have using wxdataviewlistctrl…

Im confused with Item on dataviewlistctrl the items just can be array or can be other type and how to delete that some item selected?
I was using a list of model on myclass extend from wxdataviewIndexlistmodel and override some method but cant deleted when call DeleteAllItems at DataviewListStore how to see the code below.
view=wx.DataViewListCtrl()
View.AssociationModel(myclass([mymodel of sqlalchemy]))
view.Getstore().DeleteAllITems()
In it stop and closed the programs hay happens that?

https://wiki.wxpython.org/MakingSampleApps

Please provide a small runnable sample application that demonstrates just your problem.

···

On Saturday, November 25, 2017 at 12:10:37 AM UTC-8, Juvenal Claros wrote:

Sorry for my bad English try to explain again my problem, I can’t delete all item in my DataviewListCtrl class when a call to self.DeleteAllItems() then my app stop, why happends that? my all class below

Robin Dunn

Software Craftsman

So thanks i find the problem I Deleterow and after call to rowappens for to notifiar