基于另一个笔记本选项卡中TextCtrl()的值,更改wx.ComboBox()中的选择

3

我正在使用wx制作一个GUI来运行另一个程序。我有两个Notebook选项卡:第一个用于输入,第二个用于我的程序的输出。我想设置这样一个功能,即用户将在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更改目录,但都没有成功。非常感谢您的帮助。

提前致谢, Michael Latham

2个回答

3

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

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

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


那么我的方式是丑陋的方式吗?:-D - Jake
这是一种不太正规的方法。并不一定是坏事,但如果你恰好更改了类、小部件或方法名称,它很容易被破坏。我知道像parent.widget.getter这样的东西通常在wxPython邮件列表上是不被鼓励的。当然,你的情况可能会有所不同。 - Mike Driscoll
其实现在我看了一下,你的方法看起来很酷,而且并不是我想象中的那样。 - Mike Driscoll
谢谢大家的帮助! Jake,我试了一下你的代码,它完美地运行了。 Mike,我会查看那个链接,因为我将要在我的应用程序中使用其他wxWidgets来完成这种类型的事情。 再次感谢。 - Michael Latham

0
你可以为每个面板添加一个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()

你可能想要稍微整理一下,但这展示了你可以如何做到。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接