Combo Box List in Collapsible Pane not updating

Hello Robin,

···

It took some time but here is the ‘small’ code.

The list of the collapsible pane is not updating.

The wx(statictext and textbox) do update correctly but not the list in the list box.

Any ideas ?

Best Regards,

Robert

Code follows and it is also in attachment - only import if wx:

import wx
#----------------------------------------------------------------------

I have a BUG on the combobox inside a collapsible panel

the static text and ctrltext change BUT not the combobox list

may be there is a way around or i use comboxo badly ?

#----------------------------------------------------------------------

label1 = “Click here to show pane”
label2 = “Click here to hide pane”
btnlbl1 = “call Expand(True)”
btnlbl2 = “call Expand(False)”

class
Panel1(wx.Panel):

def __init__(self,parent,log):
    wx.Panel.__init__(self,parent,-1)
    self._thevalue= thevalue = True
    self.sizero=wx.BoxSizer(wx.VERTICAL)
    self.TheTextControl = wx.TextCtrl(self, -1, str(self._thevalue))
    self.sizero.Add(self.TheTextControl,1,wx.EXPAND)
    self.sizero.AddSpacer(5)
    self.mybutton = wx.Button(self, wx.ID_ANY, "PRESS TO CHANGE THE LABELS IN THE COLAPSIBLE PANE")
    self.sizero.Add(self.mybutton, 1, wx.EXPAND)
    self.sizero.AddSpacer(5)

self.SetSizer(self.sizero)
self.SetAutoLayout(True)
self.sizero.Fit(self)
self.Bind(wx.EVT_BUTTON, self.onbutton, self.mybutton)

def onbutton(self,evt):

    if self._thevalue == True:
        self._thevalue = False
    else:
        self._thevalue = True
       
    thevalue = self._thevalue
    self.TheTextControl.SetValue(str(self._thevalue))
    self.TheTextControl.Update()

 def

getthevalue(self):
print"return the value "+str(self._thevalue)
return self._thevalue

class TestPanel(wx.Panel):
def init(self, parent, log):
#self.log = log
wx.Panel.init(self, parent, -1)

    title = wx.StaticText(self, label="wx.CollapsiblePane")
    title.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.BOLD))
    title.SetForegroundColour("blue")

    self.cp = cp = wx.CollapsiblePane(self, label=label1)
     self.Bind(wx.EVT_COLLAPSIBLEPANE_CHANGED, self.OnPaneChanged,

cp)
self.MakePaneContent(cp.GetPane())

    sizer = wx.BoxSizer(wx.VERTICAL)
    self.SetSizer(sizer)
    sizer.Add(title, 0, wx.ALL, 25)
    sizer.Add(cp, 0, wx.RIGHT|wx.LEFT|wx.EXPAND, 25)

    self.btn = btn = wx.Button(self, label=btnlbl1)
    self.Bind(wx.EVT_BUTTON, self.OnToggle, btn)
    sizer.Add(btn, 0, wx.ALL, 25)


def OnToggle(self, evt):
    self.cp.Collapse(self.cp.IsExpanded())
    self.OnPaneChanged()


 def OnPaneChanged(self,

evt=None):
prt = self.GetParent()
nthevalue = prt.myfirstpane.getthevalue()
#if evt:
# self.log.write(‘wx.EVT_COLLAPSIBLEPANE_CHANGED: %s’ % evt.Collapsed)
print “OnPaneChange”
print "thevalue "+str(nthevalue)
#And we force the redraw -
self.MakePaneContent(self.cp.GetPane())
# redo the layout
self.Layout()
# and also change the labels
if self.cp.IsExpanded():
self.cp.SetLabel(label2)
self.btn.SetLabel(btnlbl2)
else:
self.cp.SetLabel(label1)
self.btn.SetLabel(btnlbl1)
self.btn.SetInitialSize()

def MakePaneContent(self, pane):
    '''Just make a few controls to put on the collapsible pane'''
    ulabel=""
    labels=""
    prt = self.GetParent()
    mthevalue = prt.myfirstpane.getthevalue()
    
    if mthevalue == False :
        labels=['column1','column2']#labels=['thevalue1','tehvalue2']
        ulabel ="MUSTBECOLMN"
    else:
        labels=['thevalue1','tehvalue2']#labels=['column1','column2']
        ulabel = "MUSTBEVALUE"
    #Robin: I suspect either a wrong way of me using combox or an underlying
    #pointer of combobox which stays stuck on the original label list
    #but on the MakeContent I would have say that all variable name woul be reset ?
    
    print "INSIDE THE MakePaneContent"
    print "thevalue "+str(mthevalue)
    print "the labels " +str(labels)
   
    nameLbl = wx.StaticText(pane, -1, ulabel)
    name = wx.TextCtrl(pane, -1, ulabel);
    cbx1 = wx.ComboBox(pane, wx.ID_ANY , "default value" , (90, 80), (95, -1),labels, wx.CB_DROPDOWN)
    #pane.Bind(wx.EVT_COMBOBOX, self.EvtComboBox, cbx1)
   
    hsizer=wx.BoxSizer(wx.HORIZONTAL)
    hsizer.Add(nameLbl,1)
     hsizer.Add(name,1)
    hsizer.Add(cbx1)
    vsizer=wx.BoxSizer(wx.VERTICAL)
    vsizer.Add(hsizer, wx.EXPAND|wx.ALL)
   
    pane.SetSizer(vsizer)

class QME_MainWindow(wx.Frame):
def init(self,parent,id,title):
wx.Frame.init(self,parent,wx.ID_ANY, title, size = (200,100))

    self.mfsizer=wx.BoxSizer(wx.VERTICAL)
    self.myfirstpane = Panel1(self,-1)
    self.mysecondpane = TestPanel(self,-1)

    #Sizers
     self.mfsizer.Add(self.myfirstpane,1,wx.EXPAND)
    self.mfsizer.AddSpacer(2)
    self.mfsizer.Add(self.mysecondpane,1,wx.EXPAND)

    #Layout sizers
    self.mfsizer.SetMinSize((500,500))
    self.SetSizer(self.mfsizer)
    self.SetAutoLayout(True)
    self.mfsizer.Fit(self)

app = wx.PySimpleApp(0)

qme_debug_level = 1 # 1 or 2 - we set the verbose/debug

3 for serious debug

#we redirect output for debugging when log has problem …
if qme_debug_level==0: # All to qme-dev general log
sys.stdout = GenLog()
sys.stderr = GenLog()

elif qme_debug_level==1: # separate windows for the stdio/stderr
app.RedirectStdio()

elif qme_debug_level==3: # goes back to the original call for serious debug
pass

frame = QME_MainWindow(None,-1,"CollapsCombo TestApp for Robin ‘wxpy’ Dunn :wink: ")

frame.Show(1)
app.MainLoop()


Découvrez une nouvelle façon d’obtenir des réponses à toutes vos questions ! Profitez des connaissances, des opinions et des expériences des internautes sur Yahoo! Questions/Réponses.import wx
#----------------------------------------------------------------------

I have a BUG on the combobox inside a collapsible panel

the static text and ctrltext change BUT not the combobox list

may be there is a way around or i use comboxo badly

?
#----------------------------------------------------------------------

label1 = “Click here to show pane”
label2 = “Click here to hide pane”
btnlbl1 = “call Expand(True)”
btnlbl2 = “call Expand(False)”

class Panel1(wx.Panel):

def __init__(self,parent,log):
    wx.Panel.__init__(self,parent,-1)
    self._thevalue= thevalue = True
    self.sizero=wx.BoxSizer(wx.VERTICAL)
    self.TheTextControl = wx.TextCtrl(self, -1, str(self._thevalue))
    self.sizero.Add(self.TheTextControl,1,wx.EXPAND)
    self.sizero.AddSpacer(5)
    self.mybutton = wx.Button(self, wx.ID_ANY, "PRESS TO CHANGE THE LABELS IN THE COLAPSIBLE PANE")
    self.sizero.Add(self.mybutton, 1, wx.EXPAND)
    self.sizero.AddSpacer(5)
    self.SetSizer(self.sizero)
    self.SetAutoLayout(True)
    self.sizero.Fit(self)
    self.Bind(wx.EVT_BUTTON, self.onbutton,

self.mybutton)

def onbutton(self,evt):

    if self._thevalue == True:
        self._thevalue = False
    else:
        self._thevalue = True

    thevalue = self._thevalue
    self.TheTextControl.SetValue(str(self._thevalue))
    self.TheTextControl.Update()

def getthevalue(self):
    print"return the value "+str(self._thevalue)
    return self._thevalue

class TestPanel(wx.Panel):
def init(self, parent, log):
#self.log = log
wx.Panel.init(self, parent, -1)

    title = wx.StaticText(self, label="wx.CollapsiblePane")
    title.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.BOLD))
    title.SetForegroundColour("blue")

    self.cp = cp = wx.CollapsiblePane(self, label=label1)
    self.Bind(wx.EVT_COLLAPSIBLEPANE_CHANGED, self.OnPaneChanged, cp)

self.MakePaneContent(cp.GetPane())

    sizer = wx.BoxSizer(wx.VERTICAL)
    self.SetSizer(sizer)
    sizer.Add(title, 0, wx.ALL, 25)
    sizer.Add(cp, 0, wx.RIGHT|wx.LEFT|wx.EXPAND, 25)

    self.btn = btn = wx.Button(self, label=btnlbl1)
    self.Bind(wx.EVT_BUTTON, self.OnToggle, btn)
    sizer.Add(btn, 0, wx.ALL, 25)


def OnToggle(self, evt):
    self.cp.Collapse(self.cp.IsExpanded())
    self.OnPaneChanged()


def OnPaneChanged(self, evt=None):
    prt = self.GetParent()
    nthevalue = prt.myfirstpane.getthevalue()
    #if evt:
    # self.log.write('wx.EVT_COLLAPSIBLEPANE_CHANGED: %s' % evt.Collapsed)
    print "OnPaneChange"
    print "thevalue "+str(nthevalue)
    #And we force the redraw -
    self.MakePaneContent(self.cp.GetPane())
    # redo the layout
    self.Layout()
    # and also change

the labels
if self.cp.IsExpanded():
self.cp.SetLabel(label2)
self.btn.SetLabel(btnlbl2)
else:
self.cp.SetLabel(label1)
self.btn.SetLabel(btnlbl1)
self.btn.SetInitialSize()

def MakePaneContent(self, pane):
    '''Just make a few controls to put on the collapsible pane'''
    ulabel=""
    labels=""
    prt = self.GetParent()
    mthevalue = prt.myfirstpane.getthevalue()

    if mthevalue == False :
        labels=['column1','column2']#labels=['thevalue1','tehvalue2']
        ulabel ="MUSTBECOLMN"
    else:
        labels=['thevalue1','tehvalue2']#labels=['column1','column2']
        ulabel = "MUSTBEVALUE"
    #Robin: I suspect either a wrong way of me using combox or an underlying
    #pointer of combobox which stays stuck on the original label list

 #but on the MakeContent I would have say that all variable name woul be reset ?

    print "INSIDE THE MakePaneContent"
    print "thevalue "+str(mthevalue)
    print "the labels " +str(labels)

    nameLbl = wx.StaticText(pane, -1, ulabel)
    name = wx.TextCtrl(pane, -1, ulabel);
    cbx1 = wx.ComboBox(pane, wx.ID_ANY , "default value" , (90, 80), (95, -1),labels, wx.CB_DROPDOWN)
    #pane.Bind(wx.EVT_COMBOBOX, self.EvtComboBox, cbx1)

    hsizer=wx.BoxSizer(wx.HORIZONTAL)
    hsizer.Add(nameLbl,1)
    hsizer.Add(name,1)
    hsizer.Add(cbx1)
    vsizer=wx.BoxSizer(wx.VERTICAL)
    vsizer.Add(hsizer, wx.EXPAND|wx.ALL)

    pane.SetSizer(vsizer)

class QME_MainWindow(wx.Frame):
def init(self,parent,id,title):
wx.Frame.init(self,parent,wx.ID_ANY, title, size = (200,100))

self.mfsizer=wx.BoxSizer(wx.VERTICAL)
self.myfirstpane = Panel1(self,-1)
self.mysecondpane = TestPanel(self,-1)

    #Sizers
    self.mfsizer.Add(self.myfirstpane,1,wx.EXPAND)
    self.mfsizer.AddSpacer(2)
    self.mfsizer.Add(self.mysecondpane,1,wx.EXPAND)

    #Layout sizers
    self.mfsizer.SetMinSize((500,500))
    self.SetSizer(self.mfsizer)
    self.SetAutoLayout(True)
    self.mfsizer.Fit(self)

app = wx.PySimpleApp(0)

qme_debug_level = 1 # 1 or 2 - we set the verbose/debug

3 for serious debug

#we redirect output for debugging when log has problem …
if qme_debug_level==0: # All to qme-dev general log
sys.stdout = GenLog()
sys.stderr = GenLog()

elif qme_debug_level==1: # separate windows for the stdio/stderr
app.RedirectStdio()

elif qme_debug_level==3: # goes back to the original call for serious
debug
pass

frame = QME_MainWindow(None,-1,"CollapsCombo TestApp for Robin ‘wxpy’ Dunn :wink: ")

frame.Show(1)
app.MainLoop()


Découvrez une nouvelle façon d’obtenir des réponses à toutes vos questions ! Profitez des connaissances, des opinions et des expériences des internautes sur Yahoo! Questions/Réponses.

Hi Robert,

I tried to have a look at this and found a little code mistake.

AddSpacer(5)

Should be:
AddSpacer((5, 5))

There is also a dependency to "genlog", so I just commented all between PySimpleApp and when the frame is created.

Why are you recreating the controls on the pane each time? Don't you just want to change the choices?

I actually think this has to do with your problem, because if I change the combobox to:
        cbx1 = wx.ComboBox(pane, wx.ID_ANY , "default value" , (-1, -1), (-1, -1),labels, wx.CB_DROPDOWN)

Use default size and position I can see two combobox's on your pane.

So, I added this to the beginning of MakePaneContent:

        for child in pane.GetChildren():
            child.Destroy()
               sizer = pane.GetSizer()
        del sizer

Werner