Search code examples
pythonwxpythonlistctrl

Delete item in ListCtrl Python


How can I clear list ctrl in Python?

For example when I insert the 10's item the first 8 item are deleted from the listCtrl with the possibility to continue entering item in a listCtrl.

How can i do this?

Example:

I insert: 1,2,3,4,5,6,7,8,9,10 after the 10 item i see in the listCtrl only 8,9,10 and i can insert item again.

I put some code with my example.

import wx
import wx.gizmos as gizmos
import time
import datetime
from datetime import timedelta

class CWindow(wx.Frame):

    def __init__(self, parent, id, title):

        wx.Frame.__init__(self, parent, id, title, style = wx.DEFAULT_FRAME_STYLE & ~ wx.CLOSE_BOX ^ wx.MAXIMIZE_BOX ^ wx.RESIZE_BORDER, size=(600,500))

        dataCorrente = datetime.datetime.now()


        self.Panel = wx.Panel(self, -1)
        self.index = 0

        self.ceck = {}
        self.ts = ""


        self.CTesto = wx.TextCtrl(self.Panel, 1, pos=(10,40), style=wx.TE_PROCESS_ENTER)
        self.CTesto.Bind(wx.EVT_TEXT_ENTER,self.add_line)

        self.BtnConferma = wx.Button(self.Panel, 12, "Conferma", pos=(130,38))

        self.list_ctrl = wx.ListCtrl(self.Panel, pos=(10,90),size=(-1,330),style=wx.LC_REPORT|wx.BORDER_SUNKEN)
        self.list_ctrl.InsertColumn(0, 'Name')
        self.list_ctrl.InsertColumn(1, 'Start')
        self.list_ctrl.InsertColumn(2, 'Finish', width=100)

        wx.Button(self.Panel, 22, "Exit", pos=wx.Point(470,400))

        self.Bind(wx.EVT_BUTTON, self.close, id=22)

        self.Bind(wx.EVT_BUTTON, self.add_line, self.BtnConferma, id=12)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.list_ctrl, 0, wx.ALL|wx.EXPAND, 5)
        sizer.Add(self.BtnConferma, 0, wx.ALL|wx.CENTER, 5)


        self.led = gizmos.LEDNumberCtrl(self.Panel, -1, pos = (350,25), size = (200,50), style = gizmos.LED_ALIGN_CENTER)
        self.led.SetBackgroundColour("#c0c0c0")
        self.led.SetForegroundColour("black")
        self.OnTimer(None)
        self.timer = wx.Timer(self, -1)
        self.timer.Start(1000)
        self.Bind(wx.EVT_TIMER, self.OnTimer)
        style = gizmos.LED_ALIGN_CENTER


    def OnTimer(self, event):

        current = time.localtime(time.time())
        self.ts = time.strftime("%H:%M:%S", current)
        self.led.SetValue(self.ts)

        if self.ts in self.ceck:
            self.list_ctrl.SetItemTextColour(self.ceck.get(self.ts), wx.WHITE)
            self.list_ctrl.SetItemBackgroundColour(self.ceck.pop(self.ts), wx.RED)


    def add_line(self,event):

        val = str(self.CTesto.GetValue())

        if val== '':

            msg = wx.MessageDialog(self, "Error", "Error", wx.OK| wx.ICON_ERROR)
            msg.ShowModal()
            msg.Destroy()

        else:

            if self.list_ctrl.GetItemCount() == 10:
                for i in range(7):
                    self.list_ctrl.DeleteItem(1)

            dataCorrente = datetime.datetime.now()
            oraAttuale =(dataCorrente.strftime("%H:%M:%S"))
            plus = (datetime.datetime.strptime(oraAttuale, "%H:%M:%S") + datetime.timedelta(minutes=1))
            global plus2
            plus2 = plus.strftime("%H:%M:%S")

            if plus2 in self.ceck:
                msg = wx.MessageDialog(self, "Duplicate Time", "Error", wx.OK| wx.ICON_ERROR)
                msg.ShowModal()
                msg.Destroy()
                return

            self.list_ctrl.InsertItem(self.index, val)
            self.list_ctrl.SetItem(self.index, 1, oraAttuale)
            self.list_ctrl.SetItem(self.index, 2, str(plus2))
            self.index += 1
            InsVal = (val + " - " + oraAttuale + " - " + plus2 + '\n')
            self.CTesto.Clear()
            self.ceck[plus2] = self.index -1


    def close(self,event):

        hDialog=wx.MessageDialog(self, "°°°", "Exit", wx.OK|wx.CANCEL| wx.ICON_EXCLAMATION)
        rispostaDialog=hDialog.ShowModal()
        hDialog.Destroy()

        if rispostaDialog == wx.ID_OK:
            self.Destroy()


app = wx.App()  
frame = CWindow(None, -1, "Example")
frame.Show()
frame.Center()
app.MainLoop()




Solution

  • You appear to have gone back (from your original post) to having the listctrl items in entry order rather than reverse entry order. That means that once again you have to remove index 0 and not index 1.
    You are also not allowing for the fact that the dictionary values are now invalid if you just deleted 7 of the entries. They have to be removed if the item has been deleted and reset to the new index value if they have been left in place.
    Try this, see if it gets you any closer to what you are trying to achieve:

    import wx
    import wx.gizmos as gizmos
    import time
    import datetime
    from datetime import timedelta
    
    class CWindow(wx.Frame):
    
        def __init__(self, parent, id, title):
    
            wx.Frame.__init__(self, parent, id, title, style = wx.DEFAULT_FRAME_STYLE & ~ wx.CLOSE_BOX ^ wx.MAXIMIZE_BOX ^ wx.RESIZE_BORDER, size=(600,500))
    
            dataCorrente = datetime.datetime.now()
    
    
            self.Panel = wx.Panel(self, -1)
            self.index = 0
    
            self.ceck = {}
            self.ts = ""
    
    
            self.CTesto = wx.TextCtrl(self.Panel, 1, pos=(10,40), style=wx.TE_PROCESS_ENTER)
            self.CTesto.Bind(wx.EVT_TEXT_ENTER,self.add_line)
    
            self.BtnConferma = wx.Button(self.Panel, 12, "Conferma", pos=(130,38))
    
            self.list_ctrl = wx.ListCtrl(self.Panel, pos=(10,90),size=(-1,330),style=wx.LC_REPORT|wx.BORDER_SUNKEN)
            self.list_ctrl.InsertColumn(0, 'Name')
            self.list_ctrl.InsertColumn(1, 'Start')
            self.list_ctrl.InsertColumn(2, 'Finish', width=100)
    
            wx.Button(self.Panel, 22, "Exit", pos=wx.Point(470,400))
    
            self.Bind(wx.EVT_BUTTON, self.close, id=22)
    
            self.Bind(wx.EVT_BUTTON, self.add_line, self.BtnConferma, id=12)
    
            sizer = wx.BoxSizer(wx.VERTICAL)
            sizer.Add(self.list_ctrl, 0, wx.ALL|wx.EXPAND, 5)
            sizer.Add(self.BtnConferma, 0, wx.ALL|wx.CENTER, 5)
    
    
            self.led = gizmos.LEDNumberCtrl(self.Panel, -1, pos = (350,25), size = (200,50), style = gizmos.LED_ALIGN_CENTER)
            self.led.SetBackgroundColour("#c0c0c0")
            self.led.SetForegroundColour("black")
            self.OnTimer(None)
            self.timer = wx.Timer(self, -1)
            self.timer.Start(1000)
            self.Bind(wx.EVT_TIMER, self.OnTimer)
            style = gizmos.LED_ALIGN_CENTER
    
    
        def OnTimer(self, event):
    
            current = time.localtime(time.time())
            self.ts = time.strftime("%H:%M:%S", current)
            self.led.SetValue(self.ts)
    
            if self.ts in self.ceck:
                self.list_ctrl.SetItemTextColour(self.ceck.get(self.ts), wx.WHITE)
                self.list_ctrl.SetItemBackgroundColour(self.ceck.pop(self.ts), wx.RED)
    
    
        def add_line(self,event):
    
            val = str(self.CTesto.GetValue())
    
            if val== '':
    
                msg = wx.MessageDialog(self, "Error", "Error", wx.OK| wx.ICON_ERROR)
                msg.ShowModal()
                msg.Destroy()
    
            else:
    
                if self.list_ctrl.GetItemCount() == 10:
                    for i in range(7):
                        d = self.list_ctrl.GetItem(0,2)
                        del_text = d.GetText()
                        #remove the dictionary values for the items being deleted
                        try: # It may already have been popped from the dict if the colour was changed
                            self.ceck.pop(del_text)
                        except:
                            pass
                        self.list_ctrl.DeleteItem(0)
                        self.index -= 1
                    #reset the dictionary vales for the existing ctrl items they have new index values
                    new_idx = 0
                    for i in range (3):
                        item = self.list_ctrl.GetItemText(i,2)
                        self.ceck[item] = new_idx
                        new_idx += 1
    
                dataCorrente = datetime.datetime.now()
                oraAttuale =(dataCorrente.strftime("%H:%M:%S"))
                plus = (datetime.datetime.strptime(oraAttuale, "%H:%M:%S") + datetime.timedelta(minutes=1))
                global plus2
                plus2 = plus.strftime("%H:%M:%S")
    
                if plus2 in self.ceck:
                    msg = wx.MessageDialog(self, "Duplicate Time", "Error", wx.OK| wx.ICON_ERROR)
                    msg.ShowModal()
                    msg.Destroy()
                    return
    
                self.list_ctrl.InsertItem(self.index, val)
                self.list_ctrl.SetItem(self.index, 1, oraAttuale)
                self.list_ctrl.SetItem(self.index, 2, str(plus2))
                self.index += 1
                InsVal = (val + " - " + oraAttuale + " - " + plus2 + '\n')
                self.CTesto.Clear()
                self.ceck[plus2] = self.index -1
    
    
        def close(self,event):
    
            hDialog=wx.MessageDialog(self, "°°°", "Exit", wx.OK|wx.CANCEL| wx.ICON_EXCLAMATION)
            rispostaDialog=hDialog.ShowModal()
            hDialog.Destroy()
    
            if rispostaDialog == wx.ID_OK:
                self.Destroy()
    
    
    app = wx.App()
    frame = CWindow(None, -1, "Example")
    frame.Show()
    frame.Center()
    app.MainLoop()