Search code examples
pythonpython-3.xwxpython

Check Time Control and change color in listrCtrl


In the part of the code included between ################ Code ######### I try to do a control with if but doesn't work.
I would like that when the variable 'ts' is equal to the variable 'prova' the line(item) in the same list ctrl becomes red. For all item which I insert in the ctrl list. Thanks so much!

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.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.list_ctrl = wx.ListCtrl(self.Panel, pos=(10,90),size=(-1,300),style=wx.LC_REPORT|wx.BORDER_SUNKEN)
        self.list_ctrl.InsertColumn(0, 'Name')
        self.list_ctrl.InsertColumn(1, 'Time START')
        self.list_ctrl.InsertColumn(2, 'Time FINISH', width=100)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.list_ctrl, 0, wx.ALL|wx.EXPAND, 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())
        global ts
        ts = time.strftime("%H:%M:%S", current)
        self.led.SetValue(ts)
        #print (ts) # In Loop it's OK

############################################################################################################################

        if ts == prova:
            self.list_ctrl.SetItemBackgroundColour(self.index, 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:

            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")

            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()

            print (InsVal)

        prova = InsVal[-9:]

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


Solution

  • repr() is your friend in this question.
    print(repr(self.prova)) would reveal that it contains a newline character, so that needs to be stripped off.
    Also note that the ListCtrl index is zero based, so to apply the colour, you have to use index - 1.
    With these minor adjustments your code works, as I hope you planned it to.

    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.prova = {}
            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.list_ctrl = wx.ListCtrl(self.Panel, pos=(10,90),size=(-1,300),style=wx.LC_REPORT|wx.BORDER_SUNKEN)
            self.list_ctrl.InsertColumn(0, 'Name')
            self.list_ctrl.InsertColumn(1, 'Time START')
            self.list_ctrl.InsertColumn(2, 'Time FINISH', width=100)
    
            sizer = wx.BoxSizer(wx.VERTICAL)
            sizer.Add(self.list_ctrl, 0, wx.ALL|wx.EXPAND, 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.prova:
                self.list_ctrl.SetItemBackgroundColour(self.prova.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:
    
                dataCorrente = datetime.datetime.now()
                oraAttuale =(dataCorrente.strftime("%H:%M:%S"))
                plus = (datetime.datetime.strptime(oraAttuale, "%H:%M:%S") + datetime.timedelta(minutes=1))
                plus2 = plus.strftime("%H:%M:%S")
    
                if plus2 in self.prova:
                    msg = wx.MessageDialog(self, "Duplicated 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.prova[plus2] = self.index -1
    
    app = wx.App()
    frame = CWindow(None, -1, "Example")
    frame.Show()
    frame.Center()
    app.MainLoop()
    

    enter image description here

    Edit: If you want to test for all of the entries, turning them red as they occur, you will have to change the nature of prova.
    One way would be to make prova a dictionary and use the edited code above.
    This provides a method to prevent duplicate entries and a simple method for deleting entries in the dictionary prova reducing the amount of checking required. In this way the code can run continuously for days without hitting duplicates. The dictionary entries are the Finish time and the listctrl's index value, used to perform the highlighting.
    The act of deleting the dictionary entry (pop), returns the index number for the highlight.