I am new to the list. I’m learning a lot of great stuff from you guys–wish I had looked into this a long time ago!
I have been working on a problem where I want to change the choices list on a combobox control after it has been created. I have two simple questions plus a general one:
-
I am guessing that you are not able to change the choices list once the combobox has been added to the frame by Layout(). I can’t find a Set() method like with wx.ListBox. I think this is probably due to the potential that changing the list could change the basic layout of the control itself. Correct me if I am wrong. This would be the ideal solution but I am not hopeful.
-
Is there a way to change the sequence of tab traversal through the widgets in a dialog? I explain below why I am asking if you want to invest the time to look.
-
Is there a good workaround than what I have come up with? This requires you to look at my situation in more detail.
The details of my situation are this: I define a wx.Dialog. In init I define ‘myCbx’ as a wx.ComboBox with choices=oldlist and place it in a gridsizer which is nested within other sizers. The dialog is opened with ShowModal(). An event occurs (a button is clicked) which is handled by an eventhandler function. In this function oldlist is changed to newlist. Before leaving the function, I want to replace oldlist with newlist in myCbx. I have tried the following:
- Replace the control. I used this method:
gsizer.Detach(myCbx)
myCbx.Destroy()
myCbx = wx.ComboBox(self,id#,…choices=newlist…)
self.Bind(wx.EVT_COMBOBOX, …)
gsizer.Insert(index,myCbx)
self.Layout()
This is simple and works very well. The combobox has the required choices list and everything works as expected except that myCbx is now at the end of the tab traversal order. I thought that using the identical name and id# in the new widget would correct this, so I set arbitrary idnumbers for all the widgets in the gridsizer (in init) and then used the same id# for the new combobox as for the old, but it didn’t help. Does anyone know how to change the order of tab traversal?
- Redefine the topsizer. I thought maybe if I did a new layout for the entire dialog that the tab traversal would work right. So I did this, still within the event handler function:
myCbx.Destroy()
myCbx = wx.ComboBox(self,id#,…choices=newlist…)
self.Bind(wx.EVT_COMBOBOX, …)
topsizer.Destroy()
call a function (also used in init ) to:
…define subsizers and add widgets
…define the gridsizer and add widgets including the new myCbx
…define other subsizers and add widgets
…add all subsizers to topsizer
self.Layout()
This works as well as replacing the combobox, but doesn’t affect the tab traversal problem. [By the way, before I did this I tried just replacing the gridsizer–same result.]
- Redefine all the widgets. It seems that the tabs follow the order in which the widgets are created–the new myCbx always goes to the end of the traversal order. I haven’t tried this, but maybe I would have to do the following, still within the eventhandler function:
a) gather all the current data values for the widgets in the dialog–not too hard, but maybe harder than I think
b) define wlist = [list of all widgets except the button that binds to the eventhandler function which is now executing]
c) for w in wlist : w.Destroy()
d) pass the current data values (including the newlist for myCbx) for all the destroyed widgets to a function that defines all those widgets again (I could use this function in init as well)
e) then do the same as above–destroy the topsizer, define all the sizers again, do self.Layout()
I think this might work, but it ain’t pretty. The button that isn’t destroyed and redefined will probably still be out of taborder. One last idea is to close the dialog and pass the current data back to a new instance of the dialog. Can someone suggest a better way?
Thanks in advance for your help. Maybe sometime soon I will know enough to contribute.