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?