Modifying list of checkboxes - Old version and new version overlap

I am attempting to change a set of checkboxes.

These are options that the user can
select from and are a subset of all possible options. I created a window
that will show all possible options and allows the user to change the set
of options shown them. I then call the same function I called from init
to replace the existing checklist with the new version. The checkboxes
are stored in a dictionary, and I delete each member of the dictionary
before assigning new members when a change is made (should this not do
the trick?), also I call self.Layout() afterword to relayout the window.

The result is that both are placed in
the exact same location. A simplified version of the code follows:

import wx

class ControlPanel(wx.Panel):

“”“The control
system for the Manager”""

def init(self, parent):

  wx.Panel.__init__(self,parent)

  PreviousHeadingChecks={"heading1":True,"heading3":False,"heading6":True}

From save file (saved on close)

  self.parent=parent

  self.requestSizer

= wx.BoxSizer(orient=wx.VERTICAL)

  self.check={}

  self.DataHeadings(True,DefaultDict=PreviousHeadingChecks)

  self.SetSizer(self.requestSizer)

def DataHeadings(self,
isInit, DefaultDict={}):

  """Changes

the available headings on the fly"""

  dataHeadings=self.parent.dataHeadings

  for key in self.check.keys():

     self.check[key]

     del

self.check[key]

this should remove the checkboxes, right?

  self.check={}

  self.requestSizer.Clear()

  for heading in

dataHeadings:

     self.check[heading]

= wx.CheckBox(self, label=heading)

     self.check[heading].SetValue(DefaultDict.get(heading,

True))

     self.requestSizer.Add(self.check[heading])

  if not isInit:

     self.Layout()

class HeadingEdit(wx.Panel):

def init(self,parent,main):

  wx.Panel.__init__(self,

parent)

  self.main=main

  self.parent=parent

  headings = ["heading1","heading2","heading3",

       
  "heading4","heading5","heading6",

       
  "heading7","heading8","heading9"]

  colsizer = wx.BoxSizer(orient=wx.HORIZONTAL)

  sizercols = [wx.BoxSizer(orient=wx.VERTICAL),

       
  wx.BoxSizer(orient=wx.VERTICAL),

       
  wx.BoxSizer(orient=wx.VERTICAL)]

  for col in sizercols:

     colsizer.Add(col)

  self.check={}

  for heading in

headings:

     self.check[heading]

= wx.CheckBox(self, label=heading)

     self.check[heading].SetValue(heading

in self.main.dataHeadings)

     sizercols[headings.index(heading)%len(sizercols)].Add(self.check[heading])

 

  self.SubmitButton

= wx.Button(self, wx.ID_ANY, “OK”)

  self.SubmitButton.Bind(wx.EVT_BUTTON,

self.OnSubmit)

  sizer = wx.GridBagSizer()

  sizer.Add(colsizer,

pos=(1,1))

  sizer.Add(self.SubmitButton,

pos=(3,1), flag=wx.ALIGN_CENTER)

  sizer.Add(wx.StaticText(self,

wx.ID_ANY, “”), pos=(4,2))

  self.SetSizer(sizer)

  sizer.Fit(self.parent)

def OnSubmit(self, event):

  headings=[]

  for heading in

self.check.keys():

     if

self.check[heading].GetValue():

headings.append(heading)

  self.main.dataHeadings=headings

  self.main.Control.DataHeadings(False)

  self.GetParent().Destroy()

class EditFrame(wx.Frame):

“”“The frame
where groups and headings are edited”""

def init(self,parent):

  wx.Frame.__init__(self,

parent, wx.ID_ANY, ‘Edit Heading’)

  panel = HeadingEdit(self,parent)

ID_EDIT_HEADING=101

class MainFrame(wx.Frame):

def init(self):

  wx.Frame.__init__(self,

None, wx.ID_ANY, ‘Heading Changer’)

  self.dataHeadings=["heading1","heading3","heading6"]

from external file

  self.Control =

ControlPanel(self)

  menuBar = wx.MenuBar()

  editmenu = wx.Menu()

  editmenu.Append(ID_EDIT_HEADING,"Edit

&Headings",“Edit headings”)

  menuBar.Append(editmenu,"&Edit")

  self.SetMenuBar(menuBar)

Adding the MenuBar to the Frame content.

  wx.EVT_MENU(self,

ID_EDIT_HEADING, self.OnEditHeading)

def OnEditHeading(self,
event):

  editframe=EditFrame(self).Show()

Run the program

if name == ‘main’:

app = wx.App(redirect=False)

frame = MainFrame().Show()

app.MainLoop()

I am using python 2.5.2 and running
under windows xp.

I have been stuck on this problem for
a very long time. I have implimented the solutions I found as best as I
understand them, but I seem to be missing something.

-Brian

Brian Fett

1280 Disc Dr

SHK224

Shakopee, MN 55379

Phone: (952)402-2595

Brian.D.Fett@seagate.com

I am attempting to change a set of checkboxes.

These are options that the user can select from and are a subset of all possible options. I created a window that will show all possible options and allows the user to change the set of options shown them. I then call the same function I called from __init__ to replace the existing checklist with the new version. The checkboxes are stored in a dictionary, and I delete each member of the dictionary before assigning new members when a change is made (should this not do the trick?), also I call self.Layout() afterword to relayout the window.

Why don't you just call SetValue to change the label on the existing checkboxes? Wouldn't that be a lot quicker?

   def DataHeadings(self, isInit, DefaultDict={}):
      """Changes the available headings on the fly"""
      dataHeadings=self.parent.dataHeadings
      for key in self.check.keys():
         self.check[key]
         del self.check[key] # this should remove the checkboxes, right?
      self.check={}
      self.requestSizer.Clear()
      for heading in dataHeadings:
         self.check[heading] = wx.CheckBox(self, label=heading)
         self.check[heading].SetValue(DefaultDict.get(heading, True))
         self.requestSizer.Add(self.check[heading])
      if not isInit:
         self.Layout()

No, that doesn't remove the checkboxes. It removes the key and value from the self.check dictionary, but the window still exists. When you call wx.CheckBox, it stores a link to the object in the parent object. To remove the checkbox, you'll have to remove it from the sizer, and then call the Destroy() method of the checkbox.

Again, if all you are doing is changing the heading, just call SetValue on the existing checkbox.

···

brian.d.fett@seagate.com wrote:

--
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.

I can think of 2 ways that could work. You could make the EditFrame class into a wx.Dialog and if the result is the "OK" button getting pushed, update the main frame using the sizer's various methods: wxPython API Documentation — wxPython Phoenix 4.2.2 documentation

There's Add(), Detach(), Hide(), Insert() and Remove() methods that I think you'll find helpful.

My other idea would be to use pubsub to communicate between the dialog and the main frame and still use the sizer methods above. You could even put ALL the optional heading on the panel and hide the ones you don't want until the user picks them from the dialog, then Show() them as needed. It's also possible that I am completely mis-understanding your issue and just babbling... :slight_smile:

···

brian.d.fett@seagate.com wrote:

I am attempting to change a set of checkboxes.

These are options that the user can select from and are a subset of all possible options. I created a window that will show all possible options and allows the user to change the set of options shown them. I then call the same function I called from __init__ to replace the existing checklist with the new version. The checkboxes are stored in a dictionary, and I delete each member of the dictionary before assigning new members when a change is made (should this not do the trick?), also I call self.Layout() afterword to relayout the window.

The result is that both are placed in the exact same location. A simplified version of the code follows:

import wx

class ControlPanel(wx.Panel):
   """The control system for the Manager"""
   def __init__(self, parent):
      wx.Panel.__init__(self,parent)
      PreviousHeadingChecks={"heading1":True,"heading3":False,"heading6":True} # From save file (saved on close)
      self.parent=parent
      self.requestSizer = wx.BoxSizer(orient=wx.VERTICAL)
      self.check={}
      self.DataHeadings(True,DefaultDict=PreviousHeadingChecks)
      self.SetSizer(self.requestSizer)
        def DataHeadings(self, isInit, DefaultDict={}):
      """Changes the available headings on the fly"""
      dataHeadings=self.parent.dataHeadings
      for key in self.check.keys():
         self.check[key]
         del self.check[key] # this should remove the checkboxes, right?
      self.check={}
      self.requestSizer.Clear()
      for heading in dataHeadings:
         self.check[heading] = wx.CheckBox(self, label=heading)
         self.check[heading].SetValue(DefaultDict.get(heading, True))
         self.requestSizer.Add(self.check[heading])
      if not isInit:
         self.Layout()

class HeadingEdit(wx.Panel):
   def __init__(self,parent,main):
      wx.Panel.__init__(self, parent)
      self.main=main
      self.parent=parent

      headings = ["heading1","heading2","heading3",
                  "heading4","heading5","heading6",
                  "heading7","heading8","heading9"]

      colsizer = wx.BoxSizer(orient=wx.HORIZONTAL)
      sizercols = [wx.BoxSizer(orient=wx.VERTICAL),
                  wx.BoxSizer(orient=wx.VERTICAL),
                  wx.BoxSizer(orient=wx.VERTICAL)]
      for col in sizercols:
         colsizer.Add(col)

      self.check={}
      for heading in headings:
         self.check[heading] = wx.CheckBox(self, label=heading)
         self.check[heading].SetValue(heading in self.main.dataHeadings)
         sizercols[headings.index(heading)%len(sizercols)].Add(self.check[heading])

           self.SubmitButton = wx.Button(self, wx.ID_ANY, "OK")
      self.SubmitButton.Bind(wx.EVT_BUTTON, self.OnSubmit)
           sizer = wx.GridBagSizer()
      sizer.Add(colsizer, pos=(1,1))
      sizer.Add(self.SubmitButton, pos=(3,1), flag=wx.ALIGN_CENTER) sizer.Add(wx.StaticText(self, wx.ID_ANY, ""), pos=(4,2))
      self.SetSizer(sizer)
      sizer.Fit(self.parent)
      def OnSubmit(self, event):
      headings=
      for heading in self.check.keys():
         if self.check[heading].GetValue():
            headings.append(heading)
      self.main.dataHeadings=headings
      self.main.Control.DataHeadings(False)
      self.GetParent().Destroy()

class EditFrame(wx.Frame):
   """The frame where groups and headings are edited"""
   def __init__(self,parent):
      wx.Frame.__init__(self, parent, wx.ID_ANY, 'Edit Heading')
      panel = HeadingEdit(self,parent)

ID_EDIT_HEADING=101
   class MainFrame(wx.Frame):
   def __init__(self):
      wx.Frame.__init__(self, None, wx.ID_ANY, 'Heading Changer')
      self.dataHeadings=["heading1","heading3","heading6"] # from external file
      self.Control = ControlPanel(self)
           menuBar = wx.MenuBar()
      editmenu = wx.Menu()
      editmenu.Append(ID_EDIT_HEADING,"Edit &Headings","Edit headings")
      menuBar.Append(editmenu,"&Edit")
      self.SetMenuBar(menuBar) # Adding the MenuBar to the Frame content.
      wx.EVT_MENU(self, ID_EDIT_HEADING, self.OnEditHeading)
        def OnEditHeading(self, event):
      editframe=EditFrame(self).Show()
   # Run the program
if __name__ == '__main__':
   app = wx.App(redirect=False)
   frame = MainFrame().Show()
   app.MainLoop()

I am using python 2.5.2 and running under windows xp.

I have been stuck on this problem for a very long time. I have implimented the solutions I found as best as I understand them, but I seem to be missing something.

-Brian

Brian Fett
1280 Disc Dr
SHK224
Shakopee, MN 55379

Phone: (952)402-2595
Brian.D.Fett@seagate.com

-------------------
Mike Driscoll

Blog: http://blog.pythonlibrary.org
Python Extension Building Network: http://www.pythonlibrary.org

I am not just changing the names of
the values on the checkboxes, I need to be able to change the number of
checkboxes as well.

Thank you for the advice on destroying
the checkboxes, this seems to have done the trick:

def DataHeadings(self,
isInit):

  """Changes

the available headings on the fly"“”

  dataHeadings=self.parent.dataHeadings

  self.requestSizer.Clear(True)
···
            #

clear the sizer and delete everything in it

  for heading in

dataHeadings:

     self.check[heading]

= wx.CheckBox(self, label=heading)

     self.check[heading].SetValue(self.PreviousHeadingChecks.get(heading,

True))

     self.requestSizer.Add(self.check[heading])

  if not isInit:

     self.Layout()

Seems I read the documentation too fast
and missed that I needed to call self.requestSizer.Clear with ‘True’
as an arguement.

-Brian

Brian Fett

1280 Disc Dr

SHK224

Shakopee, MN 55379

Phone: (952)402-2595

Brian.D.Fett@seagate.com

Tim Roberts timr@probo.com

Sent by: wxpython-users-bounces@lists.wxwidgets.org

No Phone Info Available
08/11/2008 03:15 PM

Please respond to

wxpython-users@lists.wxwidgets.org

To

wxpython-users@lists.wxwidgets.org
cc

Subject

Re: [wxpython-users] Modifying list
of checkboxes - Old version and new
version overlap

`brian.d.fett@seagate.com wrote:

I am attempting to change a set of checkboxes.

These are options that the user can select from and are a subset of

all possible options. I created a window that will show all possible

options and allows the user to change the set of options shown them.
I

then call the same function I called from init to replace the

existing checklist with the new version. The checkboxes are stored
in

a dictionary, and I delete each member of the dictionary before

assigning new members when a change is made (should this not do the

trick?), also I call self.Layout() afterword to relayout the window.

Why don’t you just call SetValue to change the label on the existing

checkboxes? Wouldn’t that be a lot quicker?

def DataHeadings(self, isInit, DefaultDict={}):

  """Changes the available headings

on the fly"“”

  dataHeadings=self.parent.dataHeadings
  for key in self.check.keys():
     self.check[key]
     del self.check[key]    
       #  this should  remove

the

checkboxes, right?

  self.check={}
  self.requestSizer.Clear()
  for heading in dataHeadings:
     self.check[heading] = wx.CheckBox(self,

label=heading)

     self.check[heading].SetValue(DefaultDict.get(heading,

True))

     self.requestSizer.Add(self.check[heading])
  if not isInit:
     self.Layout()

No, that doesn’t remove the checkboxes. It removes the key and value

from the self.check dictionary, but the window still exists. When
you

call wx.CheckBox, it stores a link to the object in the parent object.

To remove the checkbox, you’ll have to remove it from the sizer, and

then call the Destroy() method of the checkbox.

Again, if all you are doing is changing the heading, just call SetValue

on the existing checkbox.

Tim Roberts, timr@probo.com

Providenza & Boekelheide, Inc.


wxpython-users mailing list

wxpython-users@lists.wxwidgets.org

http://lists.wxwidgets.org/mailman/listinfo/wxpython-users

`

Mike Driscoll wrote:

`> My other idea would be to use pubsub to communicate
between the dialog

and the main frame and still use the sizer methods above. You could
even

put ALL the optional heading on the panel and hide the ones you don’t

want until the user picks them from the dialog, then Show() them as

needed. It’s also possible that I am completely mis-understanding
your

issue and just babbling… :)`

That sounds like a good solution to my problem, however, since I found why my version failed to work, and don't really have time to learn pubsub I think I will use the method I posted a few minutes ago.

Thanks however, for the idea, I may yet need to use pubsub, if I do, I will likely change this bit of code over to that method, it does feel cleaner.

-Brian

Brian Fett

1280 Disc Dr

SHK224

Shakopee, MN 55379

Phone: (952)402-2595

Brian.D.Fett@seagate.com

Mike Driscoll mike@pythonlibrary.org

Sent by: wxpython-users-bounces@lists.wxwidgets.org

No Phone Info Available
08/11/2008 03:32 PM

Please respond to

wxpython-users@lists.wxwidgets.org

To

wxpython-users@lists.wxwidgets.org
cc

Subject

Re: [wxpython-users] Modifying list
of checkboxes - Old version and new
version overlap

I am attempting to change a set of checkboxes.

These are options that the user can select from and are a subset of

all possible options. I created a window that will show all possible

options and allows the user to change the set of options shown them.
I

then call the same function I called from init to replace the

existing checklist with the new version. The checkboxes are stored
in

a dictionary, and I delete each member of the dictionary before

assigning new members when a change is made (should this not do the

trick?), also I call self.Layout() afterword to relayout the window.

The result is that both are placed in the exact same location. A

simplified version of the code follows:

import wx

class ControlPanel(wx.Panel):

“”“The control system for the Manager”“”

def init(self, parent):

  wx.Panel.__init__(self,parent)

PreviousHeadingChecks={“heading1”:True,“heading3”:False,“heading6”:True}

From save file (saved on close)

  self.parent=parent
  self.requestSizer = wx.BoxSizer(orient=wx.VERTICAL)
  self.check={}
  self.DataHeadings(True,DefaultDict=PreviousHeadingChecks)
  self.SetSizer(self.requestSizer)

def DataHeadings(self, isInit, DefaultDict={}):

  """Changes the available headings

on the fly"“”

  dataHeadings=self.parent.dataHeadings
  for key in self.check.keys():
     self.check[key]
     del self.check[key]    
       #  this should  remove

the

checkboxes, right?

  self.check={}
  self.requestSizer.Clear()
  for heading in dataHeadings:
     self.check[heading] = wx.CheckBox(self,

label=heading)

     self.check[heading].SetValue(DefaultDict.get(heading,

True))

     self.requestSizer.Add(self.check[heading])
  if not isInit:
     self.Layout()

class HeadingEdit(wx.Panel):

def init(self,parent,main):

  wx.Panel.__init__(self, parent)
  self.main=main
  self.parent=parent
  headings = ["heading1","heading2","heading3",
              "heading4","heading5","heading6",
              "heading7","heading8","heading9"]
  colsizer = wx.BoxSizer(orient=wx.HORIZONTAL)
  sizercols = [wx.BoxSizer(orient=wx.VERTICAL),
              wx.BoxSizer(orient=wx.VERTICAL),
              wx.BoxSizer(orient=wx.VERTICAL)]
  for col in sizercols:
     colsizer.Add(col)
  self.check={}
  for heading in headings:
     self.check[heading] = wx.CheckBox(self,

label=heading)

     self.check[heading].SetValue(heading

in self.main.dataHeadings)

sizercols[headings.index(heading)%len(sizercols)].Add(self.check[heading])

  self.SubmitButton = wx.Button(self, wx.ID_ANY,

“OK”)

  self.SubmitButton.Bind(wx.EVT_BUTTON, self.OnSubmit)
  sizer = wx.GridBagSizer()
  sizer.Add(colsizer, pos=(1,1))
  sizer.Add(self.SubmitButton, pos=(3,1), flag=wx.ALIGN_CENTER)
  sizer.Add(wx.StaticText(self, wx.ID_ANY, ""),

pos=(4,2))

  self.SetSizer(sizer)
  sizer.Fit(self.parent)

def OnSubmit(self, event):

  headings=[]
  for heading in self.check.keys():
     if self.check[heading].GetValue():
        headings.append(heading)
  self.main.dataHeadings=headings
  self.main.Control.DataHeadings(False)
  self.GetParent().Destroy()

class EditFrame(wx.Frame):

“”“The frame where groups and headings
are edited”“”

def init(self,parent):

  wx.Frame.__init__(self, parent, wx.ID_ANY, 'Edit

Heading’)

  panel = HeadingEdit(self,parent)

ID_EDIT_HEADING=101

class MainFrame(wx.Frame):

def init(self):

  wx.Frame.__init__(self, None, wx.ID_ANY, 'Heading

Changer’)

  self.dataHeadings=["heading1","heading3","heading6"]

from

external file

  self.Control = ControlPanel(self)  
  menuBar = wx.MenuBar()
  editmenu = wx.Menu()
  editmenu.Append(ID_EDIT_HEADING,"Edit &Headings","Edit

headings")

  menuBar.Append(editmenu,"&Edit")
  self.SetMenuBar(menuBar)  # Adding the MenuBar

to the Frame

content.

  wx.EVT_MENU(self, ID_EDIT_HEADING, self.OnEditHeading)

def OnEditHeading(self, event):

  editframe=EditFrame(self).Show()

Run the program

if name == ‘main’:

app = wx.App(redirect=False)

frame = MainFrame().Show()

app.MainLoop()

I am using python 2.5.2 and running under windows xp.

I have been stuck on this problem for a very long time. I have

implimented the solutions I found as best as I understand them, but
I

seem to be missing something.

-Brian

Brian Fett

1280 Disc Dr

SHK224

Shakopee, MN 55379

Phone: (952)402-2595

Brian.D.Fett@seagate.com

I can think of 2 ways that could work. You could make the EditFrame

class into a wx.Dialog and if the result is the “OK” button getting

pushed, update the main frame using the sizer’s various methods:

http://wxpython.org/docs/api/wx.Sizer-class.html

There’s Add(), Detach(), Hide(), Insert() and Remove() methods that I

think you’ll find helpful.

My other idea would be to use pubsub to communicate between the dialog

and the main frame and still use the sizer methods above. You could even

put ALL the optional heading on the panel and hide the ones you don’t

want until the user picks them from the dialog, then Show() them as

needed. It’s also possible that I am completely mis-understanding your

issue and just babbling… :slight_smile:

···

`brian.d.fett@seagate.com wrote:


Mike Driscoll

Blog: http://blog.pythonlibrary.org

Python Extension Building Network: http://www.pythonlibrary.org


wxpython-users mailing list

wxpython-users@lists.wxwidgets.org

http://lists.wxwidgets.org/mailman/listinfo/wxpython-users

`