【问题标题】:Change choice in wx.ComboBox() based on TextCtrl() value in another Notebook Tab根据另一个笔记本选项卡中的 TextCtrl() 值更改 wx.ComboBox() 中的选择
【发布时间】:2011-04-07 18:37:06
【问题描述】:

我正在使用 wx 制作用于运行另一个程序的 GUI。我有两个笔记本选项卡:第一个用于输入,第二个用于我的程序的输出。我想设置它,以便用户将在 InputPanel 中指示程序输出的目录,并且 OutputPanel 中的 ComboBox 将使用该目录的内容进行更新。我的代码的精简版本如下所示:

    #!/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()

我尝试了几种不同的方法来获取组合框的选项列表,以通过 InputPanel 中的目录更改来更新,但没有运气。任何帮助将不胜感激。

谢谢,提前, 迈克尔·莱瑟姆

【问题讨论】:

    标签: python wxpython wxwidgets


    【解决方案1】:

    嗯,有一种丑陋的 hack 方法和优雅的方法。实际上,可能有几个黑客。让我们看一下最常见的一种:

    在笔记本的页面更改事件中,您可以告诉输出面板执行以下操作:inputPanelRef.dirFile.GetValue(),然后根据需要更新组合框的条目。您可能需要通过 Notebook 小部件执行此操作。

    我更喜欢在面板之间传递信息的方式是使用 Pubsub。这里有一个很好的例子: http://www.blog.pythonlibrary.org/2010/06/27/wxpython-and-pubsub-a-simple-tutorial/

    【讨论】:

    • 那么我的方式是丑陋的方式吗? :-D
    • 这是一种很老套的方法。不一定不好,但如果您碰巧更改了类的名称、小部件或方法名称,则很容易破坏。我知道在 wxPython 邮件列表中通常不鼓励使用 parent.widget.getter 之类的东西。当然是 YMMV。
    • 其实我现在看,你的方法看起来有点酷,并没有达到我的想法。
    • 感谢大家的帮助!杰克,我试过你的代码,它就像一个魅力。迈克,我会检查那个链接,因为我想在我的应用程序中使用其他 wxWidgets 来做这种事情。再次感谢。
    【解决方案2】:

    您可以像这样为每个面板添加 getter 和 setter:

    #!/usr/bin/python
    
    import wx
    import os
    
    class InputPanel(wx.Panel):
        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=".", 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)
    
            self._dirF = '.'
    
        def EvtText(self, event):
            event.GetString()
            self._dirF = self.dirFile.GetValue()
    
        def GetDirF(self):
            return self._dirF
    
    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.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()
    
        def setDirT(self, dirT):
            self.dirT.Clear()
            for f in dirT:
                self.dirT.Insert(f, 0)
    
    
    class Notebook(wx.Notebook):
        def __init__(self, parent):
            wx.Notebook.__init__(self, parent, id=wx.ID_ANY, style=wx.BK_DEFAULT)
    
            self.tabOne = InputPanel(self)
            self.AddPage(self.tabOne, "Input")
            self.tabTwo = OutputPanel(self)
            self.AddPage(self.tabTwo, "Output")
    
            self.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.onPageChanged)
    
        def onPageChanged(self, event):
            if event.GetSelection() == 1:
                dirf = self.tabOne.GetDirF()
                files = os.listdir(dirf)
                self.tabTwo.setDirT(files)
            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()
    

    您可能想稍微清理一下,但这说明了您可以如何做到这一点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多