How do I save user's selection when using listbox?

...
    def OnOkClick(self, event):
        choice = self.listBox.GetStringSelection()
        print choice
        self.Destroy()

    def OnCancelClick(self, event):
        choice = None
        self.Destroy()

In both functions, the "choice" variables are local to the function and
disappear as soon as the function ends. If you want these to be
instance variables, which you certainly do, use "self.choice" instead of
"choice".

···

On Wed, 8 Nov 2006 06:53:15, wccppp@gmail.com wrote:

Hello group,

How do I save user's selection when using listbox? In the code below,
in the function OnOkClick, user's selection is saved in the frame
object's attriute choice. But after MainLoop, I guess since the frame
is destroyed, the attribute becomes None. How do I get around this?
Not sure if I made myself understood. Thanks for your help!

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

Thank you, Phil, John and Tim.

I followed Phil’s 2nd suggestion and got it to work. Regarding Tim’s advice, if I use self.choice, I still won’t be able to refer to it after MainLoop, right? Since the frame instance will have been destroyed by then.

Btw, this is the revised code. Suggestions to improve appreciated.

import wx

class DialogResult(object):
choice = None

class LstBoxFrame(wx.Frame):

def __init__(self, lst, title = "List of items", msg = "Select item"):

    wx.Frame.__init__(self, None, -1, title, pos = (300, 200))
    panel = wx.Panel(self)

    msgLbl = wx.StaticText(panel, -1, msg)
    topSizer = wx.BoxSizer(wx.HORIZONTAL)
    topSizer.Add

(msgLbl,0)

    self.okBtn = wx.Button(panel, -1, "Ok")
    self.cancelBtn = wx.Button(panel, -1, "Cancel")
    btnSizer = wx.BoxSizer(wx.VERTICAL)
    btnSizer.Add(self.okBtn, 0)
    btnSizer.Add((10,10), 0)       
    btnSizer.Add(self.cancelBtn, 0)
   
    self.Bind(wx.EVT_BUTTON, self.OnOkClick, self.okBtn)
    self.Bind(wx.EVT_BUTTON

, self.OnCancelClick, self.cancelBtn)

    self.listBox = wx.ListBox(panel, -1, (0, 0), (200, 400), lst, wx.LB_SINGLE)
   
    botSizer = wx.BoxSizer(wx.HORIZONTAL)
    botSizer.Add

(self.listBox, 1, wx.GROW|wx.ALL, 10)
botSizer.Add(btnSizer, 0, wx.EXPAND|wx.ALL, 10)

    # mainSizer is the top-level one that manages everything
    mainSizer = wx.BoxSizer

(wx.VERTICAL)

    # now add the sizers to the mainSizer
    mainSizer.Add(topSizer, 0, wx.GROW|wx.ALL, 10)
    mainSizer.Add(botSizer, 1, wx.EXPAND|wx.ALL, 10)

    panel.SetSizer(mainSizer)

    # Fit the frame to the needs of the sizer.  The frame will
    # automatically resize the panel as needed.  Also prevent the
    # frame from getting smaller than this size.
    mainSizer.Fit

(self)
mainSizer.SetSizeHints(self)

def OnOkClick(self, event):       
    DialogResult.choice = self.listBox.GetStringSelection()
    self.Destroy()

def OnCancelClick(self, event):

    DialogResult.choice = None
    self.Destroy()

if name == “main”:
lst = [‘zero’, ‘one’, ‘two’, ‘three’, ‘four’, ‘five’,
‘six’, ‘seven’, ‘eight’, ‘nine’, ‘ten’, ‘eleven’,

              'twelve', 'thirteen', 'fourteen', 'fifteen']
app = wx.PySimpleApp()
LstBoxFrame(lst).Show()
app.MainLoop()
print "After MainLoop."
print DialogResult.choice

Regards,
-wcc

It works, and that's the main thing, but it's not quite what I had in mind. when you write:
class DialogResult(object):
     choice = None
and
     DialogResult.choice = None
you are actually using class globals. Included is a version that:
1. creates instance variables choice2 and bonus
2. passes in an instance of the class
3. puts the result into that instance
4. puts a bonus result in, too
5. gets those results out after main loop has finished.

import wx

class DialogResult(object):
     choice = None # this is global to the class -- all instances will share it
     def __init__(self):
         self.choice2 = None # this is on a per-instance basis
         self.bonus = None

class LstBoxFrame(wx.Frame):

     def __init__(self, lst, data, title = "List of items", msg = "Select item"):
         wx.Frame.__init__(self, None, -1, title, pos = (300, 200))
         panel = wx.Panel(self)
         self.data = data

         msgLbl = wx.StaticText(panel, -1, msg)
         topSizer = wx.BoxSizer(wx.HORIZONTAL)
         topSizer.Add (msgLbl,0)

         self.okBtn = wx.Button(panel, -1, "Ok")
         self.cancelBtn = wx.Button(panel, -1, "Cancel")
         btnSizer = wx.BoxSizer(wx.VERTICAL)
         btnSizer.Add(self.okBtn, 0)
         btnSizer.Add((10,10), 0)
         btnSizer.Add(self.cancelBtn, 0)

         self.Bind(wx.EVT_BUTTON, self.OnOkClick, self.okBtn)
         self.Bind(wx.EVT_BUTTON , self.OnCancelClick, self.cancelBtn)

         self.listBox = wx.ListBox(panel, -1, (0, 0), (200, 400), lst, wx.LB_SINGLE)

         botSizer = wx.BoxSizer(wx.HORIZONTAL)
         botSizer.Add (self.listBox, 1, wx.GROW|wx.ALL, 10)
         botSizer.Add(btnSizer, 0, wx.EXPAND|wx.ALL, 10)

         # mainSizer is the top-level one that manages everything
         mainSizer = wx.BoxSizer (wx.VERTICAL)

         # now add the sizers to the mainSizer
         mainSizer.Add(topSizer, 0, wx.GROW|wx.ALL, 10)
         mainSizer.Add(botSizer, 1, wx.EXPAND|wx.ALL, 10)

         panel.SetSizer(mainSizer)

         # Fit the frame to the needs of the sizer. The frame will
         # automatically resize the panel as needed. Also prevent the
         # frame from getting smaller than this size.
         mainSizer.Fit (self)
         mainSizer.SetSizeHints(self)

     def OnOkClick(self, event):
         self.data.choice2 = self.listBox.GetStringSelection()
         self.data.bonus = self.data.choice2.capitalize().swapcase()
         self.Destroy()

     def OnCancelClick(self, event):
         self.data.choice2 = None
         self.Destroy()

if __name__ == "__main__":
     lst = ['zero', 'one', 'two', 'three', 'four', 'five',
                   'six', 'seven', 'eight', 'nine', 'ten', 'eleven',
                   'twelve', 'thirteen', 'fourteen', 'fifteen']
     app = wx.PySimpleApp()
     data = DialogResult()
     LstBoxFrame(lst, data).Show()
     app.MainLoop()
     print "After MainLoop."
     print data.choice2
     print data.bonus

···

At 02:51 PM 11/8/2006, you wrote:

Thank you, Phil, John and Tim.

I followed Phil's 2nd suggestion and got it to work. Regarding Tim's advice, if I use self.choice, I still won't be able to refer to it after MainLoop, right? Since the frame instance will have been destroyed by then.

Btw, this is the revised code. Suggestions to improve appreciated.

Thanks a lot Phil. This is very helpful.

Regards,

  • wcc
···

On 11/8/06, Phil Mayes phil@philmayes.com wrote:

At 02:51 PM 11/8/2006, you wrote:

Thank you, Phil, John and Tim.

I followed Phil’s 2nd suggestion and got it to work. Regarding Tim’s
advice, if I use self.choice, I still won’t be able to refer to it after

MainLoop, right? Since the frame instance will have been destroyed by then.

Btw, this is the revised code. Suggestions to improve appreciated.

It works, and that’s the main thing, but it’s not quite what I had in mind.

when you write:
class DialogResult(object):
choice = None
and
DialogResult.choice = None
you are actually using class globals. Included is a version that:

  1. creates instance variables choice2 and bonus

  2. passes in an instance of the class

  3. puts the result into that instance

  4. puts a bonus result in, too

  5. gets those results out after main loop has finished.

import wx

class DialogResult(object):

 choice = None # this is global to the class -- all instances will share it
 def __init__(self):
     self.choice2 = None # this is on a per-instance basis
     self.bonus = None

class LstBoxFrame(
wx.Frame):