wxPython。同步选择组合框

时间:2018-10-09 12:40:57

标签: python wxpython

wxPython 我有带三个面板的框架。 每个面板都有wx.ComboBox 不可能为几个父母制作一个wx.ComboBox,所以我在三个面板上有三个不同的组合框,它们具有相同的选择列表。

是否有一种简单的方法来同步这些组合框的选择?例如。如果在第一个面板的第一个组合框中选择某项,则应在其他隐藏面板的第二个和第三个组合框中选择。

3 个答案:

答案 0 :(得分:0)

我认为最简单的方法是使用pubsub。您可以让每个面板实例都订阅一个侦听器,然后在更改组合框时,它可以向侦听器发送一条消息,告诉他们进行更新。

我创建了一个简单的Notebook,其中包含三个面板,用于演示该概念:

import wx
from wx.lib.pubsub import pub 


class TabPanel(wx.Panel):

    def __init__(self, parent):
        wx.Panel.__init__(self, parent)

        languages = ['Python', 'C++', 'PHP', 'Go']
        self.combo = wx.ComboBox(self, value='Python', choices=languages, 
                                 size=(80, -1))
        self.combo.Bind(wx.EVT_COMBOBOX, self.on_selection)

        pub.subscribe(self.update_selection, 'combo_update')

    def update_selection(self, selection):
        """
        pubsub listener
        """
        self.combo.SetSelection(selection)

    def on_selection(self, event):
        """
        combobox event handler
        """
        selection = self.combo.GetSelection()
        pub.sendMessage('combo_update', selection=selection)


class MyFrame(wx.Frame):

    def __init__(self):
        wx.Frame.__init__(self, None, title='Comboboxes!')
        panel = wx.Panel(self)
        notebook = wx.Notebook(panel)

        for page in range(1, 4):
            tab = TabPanel(notebook)
            notebook.AddPage(tab, 'Tab {}'.format(page))
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(notebook, 1, wx.ALL|wx.EXPAND, 5)
        panel.SetSizer(sizer)

        self.Show()

if __name__ == '__main__':
    app = wx.App(False)
    frame = MyFrame()
    app.MainLoop()

答案 1 :(得分:0)

您只需在事件回调中使用GetSelection()并将所有组合框设置为获得的结果即可。

import wx

class MyFrame(wx.Frame):

    def __init__(self):
        wx.Frame.__init__(self, None, title="Test")
        self.MyList = ["Abc","Def","Ghi"]
        self.panel1 = wx.Panel(self,-1)
        self.panel2 = wx.Panel(self,-1)
        self.panel3 = wx.Panel(self,-1)
        self.Picker1 = wx.ComboBox(self.panel1, pos=(10,10), value="1", size=(100, -1), choices=self.MyList)
        self.text1 = wx.StaticText(self.panel1, -1, "1", pos=(120,10))
        self.Picker2 = wx.ComboBox(self.panel2, pos=(10,10), value="2", size=(100, -1), choices=self.MyList)
        self.text2 = wx.StaticText(self.panel2, -1, "2", pos=(120,10))
        self.Picker3 = wx.ComboBox(self.panel3, pos=(10,10), value="3", size=(100, -1), choices=self.MyList)
        self.text3 = wx.StaticText(self.panel3, -1, "3", pos=(120,10))
        self.Bind(wx.EVT_COMBOBOX, self.EvtComboBox)
        vbox = wx.BoxSizer(wx.VERTICAL)
        vbox.Add(self.panel1)
        vbox.Add(self.panel2)
        vbox.Add(self.panel3)
        self.SetSizer(vbox)
        self.Show()
        self.panel1.SetFocus()
        self.panel2.Hide()
        self.panel3.Hide()

    def EvtComboBox(self,event):
        ev = event.GetSelection()
        self.Picker1.SetSelection(ev)
        self.Picker2.SetSelection(ev)
        self.Picker3.SetSelection(ev)
        self.panel2.Show()
        self.panel3.Show()
        self.Layout()

if __name__ == "__main__":
    app = wx.App()
    frame = MyFrame()
    app.MainLoop()

为了清楚起见,我在每个组合框旁边添加了一条简单的文字,并在您暗示问题中最初隐藏的面板2和3时将其隐藏。注意self.Layout()是显示未隐藏面板所必需的。

答案 2 :(得分:0)

我为我找到了决定。可以为框架创建组合框并在每个面板中使用它。我在这里举一个例子。也许对某人会有帮助。

import wx

########################################################################
class PanelOne(wx.Panel):

    def __init__(self, parent, selection):
        """Constructor"""
        wx.Panel.__init__(self, parent=parent)

        self.sizer1 = wx.BoxSizer(wx.VERTICAL)
        self.label = wx.StaticText(self, label='Firs panel')

        self.sizer1.Add(selection, 1, wx.EXPAND)
        self.sizer1.Add(self.label, 1, wx.EXPAND)
        self.SetSizer(self.sizer1)


########################################################################
class PanelTwo(wx.Panel):

    def __init__(self, parent, selection):
        """Constructor"""
        wx.Panel.__init__(self, parent=parent)

        self.sizer2 = wx.BoxSizer(wx.VERTICAL)
        self.labe2 = wx.StaticText(self, label='Second panel')

        self.sizer2.Add(selection, 1, wx.EXPAND)
        self.sizer2.Add(self.labe2, 1, wx.EXPAND)
        self.SetSizer(self.sizer2)


########################################################################
class MyForm(wx.Frame):

    # ----------------------------------------------------------------------
    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY,
                          "Panel Switcher Tutorial")

        self.selection = wx.ComboBox(self, size=(200, -1), choices=['One', 'Two', 'Three'], style=wx.CB_DROPDOWN, value='select')

        self.panel_one = PanelOne(self, self.selection)
        self.panel_two = PanelTwo(self, self.selection)
        self.panel_two.Hide()

        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.panel_one, 1, wx.EXPAND)
        self.sizer.Add(self.panel_two, 1, wx.EXPAND)
        self.SetSizer(self.sizer)

        # make menu
        menubar = wx.MenuBar()
        fileMenu = wx.Menu()
        switch_panels_menu_item = fileMenu.Append(wx.ID_ANY,
                                                  "Switch Panels",
                                                  "Some text")
        self.Bind(wx.EVT_MENU, self.onSwitchPanels,
                  switch_panels_menu_item)
        menubar.Append(fileMenu, '&File')
        self.SetMenuBar(menubar)

    # ----------------------------------------------------------------------
    def onSwitchPanels(self, event):
        """"""
        if self.panel_one.IsShown():
            self.SetTitle("Panel Two Showing")
            self.panel_one.Hide()
            self.panel_two.Show()
        else:
            self.SetTitle("Panel One Showing")
            self.panel_one.Show()
            self.panel_two.Hide()
        self.Layout()


# Run the program
if __name__ == "__main__":
    app = wx.App(False)
    frame = MyForm()
    frame.Show()
    app.MainLoop()