Search code examples
pythonpython-3.xwxpythonwxwidgets

Get state of checkboxes in listctrl


I am trying to figure out how to get the state of each checkbox within an ultimatelistctrl. I also need to be able to check or un-check all boxes.

This is my second attempt at this project, the first didn't use any form of listctrl and, although functional, it is quite ugly. I tried to use the same binding techniques on the new version, but they don't seem to apply here. Any help appreciated, thanks.

Rightly or wrongly, as this is a new version, I have started a new thread. Here is the previous one: Previous question/answer

import sys
import wx
import wx.lib.agw.ultimatelistctrl as ULC


class MyFrame(wx.Frame):

    def __init__(self, parent):
        wx.Frame.__init__(self, parent, -1, "Checkbox grid based on UltimateListCtrl Demo", size=(600,300))
        agwStyle = (ULC.ULC_HAS_VARIABLE_ROW_HEIGHT | wx.LC_REPORT | wx.LC_VRULES | wx.LC_HRULES | wx.LC_SINGLE_SEL)
        self.mylist = mylist = ULC.UltimateListCtrl(self, wx.ID_ANY, agwStyle=agwStyle)

        mylist.InsertColumn(0,"", width=100)

        for col in range(1,25):
            col_num=str(col-1)
            if col==0:col_num=""
            mylist.InsertColumn(col,col_num, width=20)


        self.checkboxes = {}
        self.boxes=[]

        for day in range(7):
            days=["Monday", "Sunday", "Saturday", "Friday", "Thursday", "Wednesday", "Tuesday"]
            index = mylist.InsertStringItem(1, "" + days[day])
            mylist.SetStringItem(index, 1, "")


        for boxes in range(1,25):
            for index in range(7):
                mylist.SetStringItem(index, boxes, "")
                checkBox = wx.CheckBox(mylist, wx.ID_ANY, "", wx.DefaultPosition, wx.DefaultSize, 0)
                self.checkboxes[checkBox.GetId()] = index
                mylist.SetItemWindow(index, boxes, checkBox)
                self.boxes.append(self.checkboxes)                

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(mylist, 1, wx.EXPAND)
        self.SetSizer(sizer)




app = wx.App()  
frame = MyFrame(None)
app.SetTopWindow(frame)
frame.Show()
app.MainLoop()

Solution

  • You were adding the dict item not the CheckBox and your days were messed up.

    import sys
    import wx
    import wx.lib.agw.ultimatelistctrl as ULC
    
    
    class MyFrame(wx.Frame):
    
        def __init__(self, parent):
            wx.Frame.__init__(self, parent, -1, "Checkbox grid based on UltimateListCtrl Demo", size=(600,300))
            agwStyle = (ULC.ULC_HAS_VARIABLE_ROW_HEIGHT | wx.LC_REPORT | wx.LC_VRULES | wx.LC_HRULES | wx.LC_SINGLE_SEL)
            self.mylist = mylist = ULC.UltimateListCtrl(self, wx.ID_ANY, agwStyle=agwStyle)
    
            mylist.InsertColumn(0,"", width=100)
    
            for col in range(1,25):
                col_num=str(col-1)
                if col==0:col_num=""
                mylist.InsertColumn(col,col_num, width=20)
    
    
            self.checkboxes = {}
            self.boxes=[]
    
            for day in range(7):
    #            days=["Monday", "Sunday", "Saturday", "Friday", "Thursday", "Wednesday", "Tuesday"]
                days=['Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday']
                mylist.InsertStringItem(day, str(days[day]))
                #index = mylist.InsertStringItem(1, "" + days[day])
                #mylist.SetStringItem(index, 1, "")
    
    
            for boxes in range(1,25):
                for index in range(7):
                    day = days[index]
                    hour = boxes-1
                    name_of_checkbox = "{day}_{hour}".format(day=day, hour=hour)
                    mylist.SetStringItem(index, boxes, "")
                    self.checkBox = wx.CheckBox(mylist, wx.ID_ANY, "", wx.DefaultPosition, wx.DefaultSize, 0,name=name_of_checkbox)
                    #self.checkBox.SetValue(True) #Use this to check all boxes
                    self.checkboxes[self.checkBox.GetId()] = index
                    mylist.SetItemWindow(index, boxes, self.checkBox)
                    self.boxes.append(self.checkBox)
    
            sizer = wx.BoxSizer(wx.VERTICAL)
            sizer.Add(mylist, 1, wx.EXPAND)
            button = wx.Button(self,-1,"Retrieve Data")
            sizer.Add(button)
            self.Bind(wx.EVT_CHECKBOX, self.OnChecked)
            self.Bind(wx.EVT_BUTTON, self.OnGetData)
            self.SetSizer(sizer)
    
        def OnChecked(self,event):
            clicked = event.GetEventObject()
            print (clicked.GetName())
            print (event.IsChecked())
    
        def OnGetData(self,event):
            day_dict = {}
            day_list = []
            for i in self.boxes:
                if i.IsChecked():
                    n = i.GetName()
                    day_dict[n]="Checked"
                    day_list.append((n,"Checked"))
            print (day_dict)
            print (day_list)
    
    
    
    app = wx.App()
    frame = MyFrame(None)
    app.SetTopWindow(frame)
    frame.Show()
    app.MainLoop()
    

    enter image description here

    Output:

    Monday_0
    True
    Tuesday_1
    True
    Wednesday_2
    True
    Thursday_3
    True
    Friday_4
    True
    Saturday_5
    True
    Sunday_6
    True
    Saturday_7
    True
    Friday_8
    True
    Thursday_9
    True
    Wednesday_10
    True
    Tuesday_12
    True
    Tuesday_11
    True
    Tuesday_12
    False
    Monday_12
    True
    {'Thursday_3': 'Checked', 'Tuesday_1': 'Checked', 'Saturday_7': 'Checked', 'Monday_12': 'Checked', 'Friday_8': 'Checked', 'Thursday_9': 'Checked', 'Wednesday_10': 'Checked', 'Saturday_5': 'Checked', 'Tuesday_11': 'Checked', 'Friday_4': 'Checked', 'Wednesday_2': 'Checked', 'Sunday_6': 'Checked', 'Monday_0': 'Checked'}
    
    [('Monday_0', 'Checked'), ('Tuesday_1', 'Checked'), ('Wednesday_2', 'Checked'), ('Thursday_3', 'Checked'), ('Friday_4', 'Checked'), ('Saturday_5', 'Checked'), ('Sunday_6', 'Checked'), ('Saturday_7', 'Checked'), ('Friday_8', 'Checked'), ('Thursday_9', 'Checked'), ('Wednesday_10', 'Checked'), ('Tuesday_11', 'Checked'), ('Monday_12', 'Checked')]