根据另一个Notebook标签中TextCtrl()的值改变wx.ComboBox()的选项
我正在使用wx来制作一个图形界面,用于运行另一个程序。我有两个选项卡:第一个是输入,第二个是输出。我想设置一个功能,让用户在输入面板中指定一个目录,然后输出面板中的下拉框会根据这个目录的内容进行更新。以下是我代码的简化版本:
#!/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()
我尝试了几种不同的方法,希望能让下拉框的选项随着输入面板中目录的变化而更新,但都没有成功。任何帮助都将非常感谢。
提前谢谢你们,
迈克尔·拉瑟姆
2 个回答
0
你可以为每个面板添加一个获取器和设置器,方法如下:
#!/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()
你可能想稍微整理一下这个代码,但这展示了你可以这样做。
3
好吧,有一种比较笨的方法和一种优雅的方法来解决这个问题。其实,可能还有几种笨办法。我们先来看一种最常见的:
在笔记本页面切换的事件中,你可以让输出面板做一些事情,比如使用 inputPanelRef.dirFile.GetValue(),然后根据需要更新下拉框的内容。你可能需要从笔记本小部件中去做这个操作。
我更喜欢在面板之间传递信息的方法是使用 Pubsub。这里有一个不错的例子:http://www.blog.pythonlibrary.org/2010/06/27/wxpython-and-pubsub-a-simple-tutorial/