Search code examples
pythonuser-interfacecomboboxwxpython

Manipulating ComboBoxes in wxPython


I'm using Python and wxPython to create an UI that lets the user select a XML file in the first combobox and all the components (i.e. buttons) in the XML appears as choices of another combobox below. It's clearly reading correctly as it prints out the right thing in the console as I go through all the XMLs, but I just can't seem to link it back to the combobox I'm looking for.

Here's the code:

import wx
import os
import xml.dom.minidom
from xml.dom.minidom import parse


# get all xmls
path = "C:\Users\William\Desktop\RES\Param"
files = os.listdir(path)

class Panel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        self.xmlList = files
        self.xmlPickerTitle = wx.StaticText(self, label="XML Picker", pos=(20, 30))
        self.xmlPicker = wx.ComboBox(self, pos=(100, 30), size=(500, -1), choices=self.xmlList, style=wx.CB_DROPDOWN)

        self.elementsTitle = wx.StaticText(self, label="Elements Found", pos=(20, 100))
        # labels
        self.buttonsPickerTitle = wx.StaticText(self, pos=(20,120), label="Buttons")

        self.buttonList = []

        self.buttonsPicker = wx.ComboBox(self, pos=(100, 120), size=(250, -1), choices=buttonList, style=wx.CB_DROPDOWN)

        self.Bind(wx.EVT_COMBOBOX, self.XMLSelect,)


    def XMLSelect(self, event):
        xmlPicked = self.xmlList[event.GetSelection()]
        DOMTree = xml.dom.minidom.parse(xmlPicked)
        collection = DOMTree.documentElement

        buttons = DOMTree.getElementsByTagName("Button")

        for button in buttons:
            if button.hasAttribute("name"):
                buttonList.append(button.getAttribute("name"))
                print button.getAttribute("name")
app = wx.App(False)
frame = wx.Frame(None, title = "Auto", size = (800, 600))
panel = Panel(frame)
frame.Show()
app.MainLoop()

Any ideas?

Thanks in advance!


Solution

  • I had an issue with the file name not containing the path so I have had to join them to pass into xmlPicked but that might be a difference between linux and Windows.
    The key point is to Clear() and Append() to the ComboBox
    Also, Bind to a specific ComboBox because you have 2.
    Finally, set the selection for the ComboBox so that it is obvious that you have data available.

    import wx
    import os
    import xml.dom.minidom
    from xml.dom.minidom import parse
    
    
    # get all xmls
    path = "/home/whatever"
    files = os.listdir(path)
    
    class Panel(wx.Panel):
        def __init__(self, parent):
            wx.Panel.__init__(self, parent)
            self.xmlList = files
            self.xmlPickerTitle = wx.StaticText(self, label="XML Picker", pos=(20, 30))
            self.xmlPicker = wx.ComboBox(self, pos=(100, 30), size=(500, -1), choices=self.xmlList, style=wx.CB_DROPDOWN)
    
            self.elementsTitle = wx.StaticText(self, label="Elements Found", pos=(20, 100))
            # labels
            self.buttonsPickerTitle = wx.StaticText(self, pos=(20,120), label="Buttons")
    
            self.buttonList = []
    
            self.buttonsPicker = wx.ComboBox(self, pos=(100, 120), size=(250, -1), choices=self.buttonList, style=wx.CB_DROPDOWN)
    
            self.xmlPicker.Bind(wx.EVT_COMBOBOX, self.XMLSelect,)
    
    
    
        def XMLSelect(self, event):
            self.buttonsPicker.Clear()
            xmlPicked = self.xmlList[event.GetSelection()]
            xmlPicked = os.path.join(path,xmlPicked)
            DOMTree = xml.dom.minidom.parse(xmlPicked)
            collection = DOMTree.documentElement
            buttons = DOMTree.getElementsByTagName("Button")
            for button in buttons:
                if button.hasAttribute("name"):
                    button_name = str(button.getAttribute("name"))
                    self.buttonsPicker.Append(button_name)
                    print button_name
            self.buttonsPicker.SetSelection(0)
    
    app = wx.App(False)
    frame = wx.Frame(None, title = "Auto", size = (800, 600))
    panel = Panel(frame)
    frame.Show()
    app.MainLoop()