Search code examples
pythonwxpython

Wxpython How to get the ComboBox's value of Panel1 from Panel2


Now I have two Panel Panelone and Paneltwo and use notebook in a Frame and When I click the button, I want to return the value of Panelone to PanelTwo like

class PanelTwo(wx.panel):
   def __init__(self,parent):
   super(PanelTwo,self).__init__(parent)
   self.choice1 = wx.ComboBox(self,value=**the Panelone Value**,choices=,style=wx.CB_SORT, pos=(100, 5)) or 
   self.choice1.SetValue(the Panelone Value)
class Panelone(wx.panel):
    def __init__(self,parent):
    choicelist = ['1','2','3','5','6']
    super(Panelone,self).__init__(parent)
    self.choice = wx.ComboBox(self,value="1",choices=choicelist,style=wx.CB_SORT, pos=(100, 5))
    self.btn = wx.Button(self, label="Summit",pos=(250, 10), size=(80, 50))
    self.Bind(wx.EVT_BUTTON, self.BtnCheck, self.btn)
    def BtnCheck(self,event):
        **When I click the button, I want to return the value of Panelone to PanelTwo**
class Game(wx.Frame):
    def __init__(self, parent, title):
        super(Game, self).__init__(parent, title=title, size=(900, 700))
        self.InitUI()

    def InitUI(self):
        nb = wx.Notebook(self)
        nb.AddPage(PanelOne(nb), "PanelOne")
        nb.AddPage(PanelTwo(nb), "PanelTwo")
        self.Centre()
        self.Show(True)

Solution

  • First of all, if you are learning, I recommend that you use WxGlade to build your graphical interfaces. Your code is pure spaghetti and is full of syntactic errors :(.

    In the case of your example, it is very simple since all the elements belong to the same file and are in the same class.

    For example:

    #!/usr/bin/env python
    # -*- coding: UTF-8 -*-    
    
    import wx
    
    # THE MAIN FRAME:
    class MainFrame(wx.Frame):
        def __init__(self, *args, **kwds):
            
            kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE
            wx.Frame.__init__(self, *args, **kwds)
            
            self.SetSize((734, 501))
            # The main notebook:
            self.main_notebook = wx.Notebook(self, wx.ID_ANY)
            # Notebook's panels:
            self.panel1 = wx.Panel(self.main_notebook, wx.ID_ANY)
            self.panel2 = wx.Panel(self.main_notebook, wx.ID_ANY)
            # Content of panel1:
            self.choiceFruits = wx.Choice(self.panel1, wx.ID_ANY, choices=[])
            self.btn_send = wx.Button(self.panel1, wx.ID_ANY, "Send Value to Panel2")
            #Content of panel2:
            self.txt_result = wx.TextCtrl(self.panel2, wx.ID_ANY, "")
    
            #Binding events:
            # event, custom event handler, gui element
            self.Bind(wx.EVT_BUTTON, self.OnBtnSendClick, self.btn_send)
    
            self.__set_properties()
            self.__do_layout()
    
        def __set_properties(self):
    
            self.SetTitle("frame")
    
            choices = ['Apple', 'Banana', 'Peach', 'Strawberry']
            self.choiceFruits.SetItems(choices)
            self.choiceFruits.SetSelection(0)
            
    
        def __do_layout(self):
            # begin wxGlade: MainFrame.__do_layout
            sizer_1 = wx.BoxSizer(wx.VERTICAL)
            grid_sizer_2 = wx.FlexGridSizer(2, 1, 0, 0)
            grid_sizer_1 = wx.FlexGridSizer(2, 2, 0, 10)
            label_1 = wx.StaticText(self.panel1, wx.ID_ANY, "Choose a fruit:")
            grid_sizer_1.Add(label_1, 0, wx.ALL, 10)
            grid_sizer_1.Add((0, 0), 0, 0, 0)
            grid_sizer_1.Add(self.choiceFruits, 0, wx.BOTTOM | wx.EXPAND | wx.LEFT | wx.RIGHT, 10)
            grid_sizer_1.Add(self.btn_send, 0, wx.BOTTOM | wx.EXPAND | wx.RIGHT, 10)
            self.panel1.SetSizer(grid_sizer_1)
            grid_sizer_1.AddGrowableCol(0)
            label_2 = wx.StaticText(self.panel2, wx.ID_ANY, "You have selected:")
            grid_sizer_2.Add(label_2, 0, wx.ALL, 10)
            grid_sizer_2.Add(self.txt_result, 0, wx.ALL | wx.EXPAND, 10)
            self.panel2.SetSizer(grid_sizer_2)
            grid_sizer_2.AddGrowableCol(0)
            self.main_notebook.AddPage(self.panel1, "Panel 1")
            self.main_notebook.AddPage(self.panel2, "Panel 2")
            sizer_1.Add(self.main_notebook, 1, wx.EXPAND, 0)
            self.SetSizer(sizer_1)
            self.Layout()
            # end wxGlade
    
        # Custom event handler:
        def OnBtnSendClick(self, event):
            selectedFruit = self.choiceFruits.GetString(self.choiceFruits.GetSelection())
            self.txt_result.SetValue(selectedFruit)
            wx.MessageBox("You have selected \"%s\"" % selectedFruit)
    
    
    # The Main Class:
    class MyApp(wx.App):
        def OnInit(self):
            self.main_frame = MainFrame(None, wx.ID_ANY, "")
            self.SetTopWindow(self.main_frame)
            self.main_frame.Show()
            return True
    
    
    # Main APP Method.
    if __name__ == "__main__":
        app = MyApp(0)
        app.MainLoop()
    

    But this is not common. Usually each panel will be in a separate file within its own class. In that case, you must pass a reference from the main frame to each panel and then we use this reference to access the elements on the main frame (for example, another panel).

    MAINFRAME

    #!/usr/bin/env python
    # -*- coding: UTF-8 -*-    
    
    import wx
    from panel1 import Panel1
    from panel2 import Panel2
    
    # THE MAIN FRAME:
    class MainFrame(wx.Frame):
        def __init__(self, *args, **kwds):
            
            kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE
            wx.Frame.__init__(self, *args, **kwds)
            
            self.SetSize((734, 501))
            # The main notebook:
            self.main_notebook = wx.Notebook(self, wx.ID_ANY)
            # Notebook's panels:
            self.panel1 = Panel1(self.main_notebook, wx.ID_ANY)
            self.panel2 = Panel2(self.main_notebook, wx.ID_ANY)
    
            # Pass reference of the main frame to each panel:
            self.panel1.SetParent(self)
            self.panel2.SetParent(self)
    
    
            self.__set_properties()
            self.__do_layout()
    
        def __set_properties(self):
            self.SetTitle("frame")
            
    
        def __do_layout(self):        
            sizer_1 = wx.BoxSizer(wx.VERTICAL)
            grid_sizer_2 = wx.FlexGridSizer(2, 1, 0, 0)        
            self.main_notebook.AddPage(self.panel1, "Panel 1")
            self.main_notebook.AddPage(self.panel2, "Panel 2")
            sizer_1.Add(self.main_notebook, 1, wx.EXPAND, 0)
            self.SetSizer(sizer_1)
            self.Layout()        
    
        
    # The Main Class:
    class MyApp(wx.App):
        def OnInit(self):
            self.main_frame = MainFrame(None, wx.ID_ANY, "")
            self.SetTopWindow(self.main_frame)
            self.main_frame.Show()
            return True
    
    
    # Main APP Method.
    if __name__ == "__main__":
        app = MyApp(0)
        app.MainLoop()
    

    PANEL 1

    # -*- coding: UTF-8 -*-
    
    import wx
    
    class Panel1(wx.Panel):
        def __init__(self, *args, **kwds):
            # begin wxGlade: Panel1.__init__
            kwds["style"] = kwds.get("style", 0) | wx.TAB_TRAVERSAL
            wx.Panel.__init__(self, *args, **kwds)
            # Content of panel1:
            self.choiceFruits = wx.Choice(self, wx.ID_ANY, choices=[])
            self.btn_send = wx.Button(self, wx.ID_ANY, "Send Value to Panel2")
    
            self._parent = None
    
            #Binding events:
            # event, custom event handler, gui element
            self.Bind(wx.EVT_BUTTON, self.OnBtnSendClick, self.btn_send)
    
            self.__set_properties()
            self.__do_layout()
    
    
        def __set_properties(self):        
            choices = ['Apple', 'Banana', 'Peach', 'Strawberry']
            self.choiceFruits.SetItems(choices)
            self.choiceFruits.SetSelection(0)        
    
        def __do_layout(self):        
            grid_sizer_2 = wx.FlexGridSizer(2, 2, 0, 0)
            label_2 = wx.StaticText(self, wx.ID_ANY, "Choose a fruit:")
            grid_sizer_2.Add(label_2, 0, wx.LEFT | wx.RIGHT | wx.TOP, 10)
            grid_sizer_2.Add((0, 0), 0, 0, 0)
            grid_sizer_2.Add(self.choiceFruits, 0, wx.ALL | wx.EXPAND, 10)
            grid_sizer_2.Add(self.btn_send, 0, wx.BOTTOM | wx.RIGHT | wx.TOP, 10)
            self.SetSizer(grid_sizer_2)
            grid_sizer_2.Fit(self)
            grid_sizer_2.AddGrowableCol(0)
            self.Layout()
            # end wxGlade
    
        def SetParent(self, parent):
            self._parent = parent
    
        # Custom event handler:
        def OnBtnSendClick(self, event):
            selectedFruit = self.choiceFruits.GetString(self.choiceFruits.GetSelection())
    
            # here is the trick !!!
            self._parent.panel2.txt_result.SetValue(selectedFruit)
            wx.MessageBox("You have selected \"%s\"" % selectedFruit)
    

    PANEL 2

    # -*- coding: UTF-8 -*-
    
    import wx
    
    class Panel2(wx.Panel):
        def __init__(self, *args, **kwds):        
            kwds["style"] = kwds.get("style", 0) | wx.TAB_TRAVERSAL
            wx.Panel.__init__(self, *args, **kwds)
    
            #Content of panel2:
            self.txt_result = wx.TextCtrl(self, wx.ID_ANY, "")
            
            self.__set_properties()
            self.__do_layout()        
    
        def __set_properties(self):       
            pass
           
    
        def __do_layout(self):        
            grid_sizer_2 = wx.FlexGridSizer(2, 1, 0, 0)
            label_2 = wx.StaticText(self, wx.ID_ANY, "You have selected:")
            grid_sizer_2.Add(label_2, 0, wx.LEFT | wx.RIGHT | wx.TOP, 10)
            grid_sizer_2.Add(self.txt_result, 0, wx.ALL | wx.EXPAND, 10)
            self.SetSizer(grid_sizer_2)
            grid_sizer_2.Fit(self)
            grid_sizer_2.AddGrowableCol(0)
            self.Layout()
    
    def SetParent(self, parent):
        self._parent = parent
    

    The trick is in the Panel1's (btn_send) button event handler:

    # self._parent is a reference to MainFrame
    # panel2 is a main_frame's element.
    # txt_result is a TextCtrl in Panel2 class.
    self._parent.panel2.txt_result.SetValue(selectedFruit)