Search code examples
pythonwxpythonwxwidgets

Change choice in wx.ComboBox() based on TextCtrl() value in another Notebook Tab


I'm using wx to make a GUI for running another program. I have two Notebook tabs: the first for the input and the second for the output of my program. I would like to set it up such that the user will indicate a directory for the program output in the InputPanel, and the ComboBox in the OutputPanel will update with the contents of this directory. A stripped down version of my code looks like:

    #!/usr/bin/python

    import glob
    import wx

    class InputPanel(wx.Panel):
        dirF = 0
        def __init__(self, parent):
            wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)

            self.dirFileText = wx.StaticText(self, label="Output Directory:")
            self.dirFile = wx.TextCtrl(self, value="fuda", style = wx.TE_PROCESS_ENTER)
            self.Bind(wx.EVT_TEXT, self.EvtText, self.dirFile)

            sizer = wx.BoxSizer(wx.HORIZONTAL)
            sizer.Add(self.dirFileText, 0, wx.ALL, 2)
            sizer.Add(self.dirFile, 0, wx.ALL|wx.EXPAND,2)
            self.SetSizer(sizer)
            sizer.Fit(self)

        def EvtText(self, event):
            event.GetString()
            InputPanel.dirF = self.dirFile.GetValue()

    class OutputPanel(wx.Panel):
        def __init__(self, parent):
            wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)

            self.dirText = wx.StaticText(self, label="Choice?")
            self.dirT = wx.ComboBox(self, choices='', style=wx.CB_READONLY)
            self.dirT.SetItems(glob.glob("%s/*.dat" % (InputPanel.dirF)))
            self.Bind(wx.EVT_COMBOBOX, self.onSelect, self.dirT)

            sizer = wx.BoxSizer(wx.HORIZONTAL)
            sizer.Add(self.dirText, 0, wx.ALL, 2)
            sizer.Add(self.dirT, 0, wx.ALL|wx.EXPAND, 2)
            self.SetSizer(sizer)
            sizer.Fit(self)

        def onSelect(self, event):
            event.GetSelection()

    class Notebook(wx.Notebook):
        def __init__(self, parent):
            wx.Notebook.__init__(self, parent, id=wx.ID_ANY, style=wx.BK_DEFAULT)

            tabOne = InputPanel(self)
            self.AddPage(tabOne, "Input")
            tabTwo = OutputPanel(self)
            self.AddPage(tabTwo, "Output")

            self.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.onPageChanged)
            self.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGING, self.onPageChanging)

        def onPageChanged(self, event):
            event.Skip()

        def onPageChanging(self, event):
            event.Skip()

class MainWindow(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, "nmrPipeFit", size=(600,400))
        panel = wx.Panel(self)

        # Setting up the menu
        filemenu = wx.Menu()
        menuExit = filemenu.Append(wx.ID_EXIT, "E&xit", "Exit the program")
        menubar = wx.MenuBar() # Create the menubar
        menubar.Append(filemenu, "&File") # Add file menu to menubar
        self.SetMenuBar(menubar) # Add menubar to frame
        # Set menu events
        self.Bind(wx.EVT_MENU, self.OnExit, menuExit)

        notebook = Notebook(panel)
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(notebook, 1, wx.ALL|wx.EXPAND, 5)
        panel.SetSizer(sizer)
        sizer.Fit(self)
        self.Layout()
        self.Show()

    def OnExit(self, event):
        self.Close(True) # Close the frame

if __name__== "__main__":
    app=wx.PySimpleApp()
    frame = MainWindow()
    app.MainLoop()

I have tried several different things to get the list of choices for the combobox to update with a change in the directory from the InputPanel, but with no luck. Any help will be greatly appreciated.

Thanks, in advance, Michael Latham


Solution

  • Well, there's an ugly hack way to do it and the elegant way to do it. Actually, there are probably several hacks. Let's look at one of the most common:

    In the notebook's page changing event, you can tell the output panel to do something like this: inputPanelRef.dirFile.GetValue() and then update the comboboxe's entries as needed. You'll probably need to do that from the Notebook widget.

    The way I prefer to pass info between panels is to use Pubsub. There's a good example here: http://www.blog.pythonlibrary.org/2010/06/27/wxpython-and-pubsub-a-simple-tutorial/