不幸的是,因为它的巨人并依赖于很多其他的东西,我无法发布适当的代码供你们测试,所以对不起提前
所以一般的想法是我有一个显示日志信息的面板(dict
称为CRDict
)。此日志包含过去的修订版本,我希望用户能够选择他们查看的修订版本。因此,我将整个设置(基于self.CRDict
中的内容创建和填充sizer)移动到名为Display()
的函数中。此函数设置下拉列表并将其绑定到函数OnRevDrop()
,该函数允许用户选择要显示的修订版本。函数OnRevDrop()
决定将self.CRDict
指定为dict
,其中包含所选修订的信息。
问题是它只能工作一次。用户打开面板,显示当前修订版,用户选择不同的修订版,面板刷新并显示所选修订版的信息,然后用户选择另一个修订版,并且它会中断KeyError
。错误是因为调用下拉列表中的GetValue()
函数会返回一个空字符串。这是我的问题的根源,虽然我不知道如何解决它。
有没有人知道为什么会这样?
提前致谢
import wx
from wx.lib.scrolledpanel import ScrolledPanel
rev1 = {"A": "a", "B": "b", "C": "c"}
rev2 = {"A": "d", "B": "e", "C": "f"}
rev3 = {"A": "g", "B": "h", "C": "i"}
RevHist = {"1":rev1, "2":rev2, "3":rev3}
class TestGui(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1, "Hey, a GUI!", size=(400,400))
self.panel = ScrolledPanel(parent=self, id=-1)
self.revsList = sorted(RevHist.keys())
self.CRDict = rev3
self.Display()
self.revDrop.SetValue("3")
def Display(self):
crrev = wx.StaticText(self.panel, -1, "Revision:")
self.revDrop = wx.ComboBox(self.panel, choices=self.revsList, style = wx.CB_READONLY)
self.Bind(wx.EVT_COMBOBOX, self.OnRevDrop, self.revDrop)
hboxRev = wx.BoxSizer(wx.HORIZONTAL)
hboxRev.Add((20,20), 1)
hboxRev.Add(crrev)
hboxRev.Add((0,0), 1)
hboxRev.Add(self.revDrop)
hboxRev.Add((20,20), 1)
sbox1 = wx.StaticBox(self.panel, wx.ID_ANY, u"Here's where the information goes")
sbox1.SetFont(wx.Font(9, wx.SWISS, wx.NORMAL, wx.BOLD))
self.staticbox1 = wx.StaticBoxSizer(sbox1, wx.VERTICAL)
infoA = wx.StaticText(self.panel, -1, "A: {}".format(self.CRDict["A"]))
infoB = wx.StaticText(self.panel, -1, "B: {}".format(self.CRDict["B"]))
infoC = wx.StaticText(self.panel, -1, "C: {}".format(self.CRDict["C"]))
self.staticbox1.Add(infoA, flag=wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP|wx.BOTTOM, border=10)
self.staticbox1.Add(infoB, flag=wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP|wx.BOTTOM, border=10)
self.staticbox1.Add(infoC, flag=wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP|wx.BOTTOM, border=10)
self.vbox = wx.BoxSizer(wx.VERTICAL)
self.vbox.Add(hboxRev, flag=wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP|wx.BOTTOM, border=10)
self.vbox.Add(self.staticbox1, flag=wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP|wx.BOTTOM, border=10)
self.panel.SetSizer(self.vbox)
self.panel.Layout()
def OnRevDrop(self, event):
rev = self.revDrop.GetValue()
print rev
self.CRDict = RevHist[rev]
self.Display()
app = wx.PySimpleApp()
gui = TestGui()
gui.Show()
app.MainLoop()
答案 0 :(得分:2)
问题在于您每次都在创建新的GUI元素,而不是简单地更新原始GUI元素
import wx
from wx.lib.scrolledpanel import ScrolledPanel
rev1 = {"A": "a", "B": "b", "C": "c"}
rev2 = {"A": "d", "B": "e", "C": "f"}
rev3 = {"A": "g", "B": "h", "C": "i"}
RevHist = {"1":rev1, "2":rev2, "3":rev3}
class TestGui(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1, "Hey, a GUI!", size=(400,400))
self.panel = ScrolledPanel(parent=self, id=-1)
self.revsList = sorted(RevHist.keys())
self.CRDict = rev3
self.CreateGui()
self.revDrop.SetValue("3")
def CreateGui(self):
crrev = wx.StaticText(self.panel, -1, "Revision:")
self.revDrop = wx.ComboBox(self.panel, choices=self.revsList, style = wx.CB_READONLY)
self.Bind(wx.EVT_COMBOBOX, self.OnRevDrop, self.revDrop)
hboxRev = wx.BoxSizer(wx.HORIZONTAL)
hboxRev.Add((20,20), 1)
hboxRev.Add(crrev)
hboxRev.Add((0,0), 1)
hboxRev.Add(self.revDrop)
hboxRev.Add((20,20), 1)
sbox1 = wx.StaticBox(self.panel, wx.ID_ANY, u"Here's where the information goes")
sbox1.SetFont(wx.Font(9, wx.SWISS, wx.NORMAL, wx.BOLD))
self.staticbox1 = wx.StaticBoxSizer(sbox1, wx.VERTICAL)
self.infoA = wx.StaticText(self.panel, -1, "A: {0}".format(self.CRDict["A"]))
self.infoB = wx.StaticText(self.panel, -1, "B: {0}".format(self.CRDict["B"]))
self.infoC = wx.StaticText(self.panel, -1, "C: {0}".format(self.CRDict["C"]))
self.staticbox1.Add(self.infoA, flag=wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP|wx.BOTTOM, border=10)
self.staticbox1.Add(self.infoB, flag=wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP|wx.BOTTOM, border=10)
self.staticbox1.Add(self.infoC, flag=wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP|wx.BOTTOM, border=10)
self.vbox = wx.BoxSizer(wx.VERTICAL)
self.vbox.Add(hboxRev, flag=wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP|wx.BOTTOM, border=10)
self.vbox.Add(self.staticbox1, flag=wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP|wx.BOTTOM, border=10)
self.panel.SetSizer(self.vbox)
self.panel.Layout()
def UpdateValues(self,valueDict):
for k,v in valueDict.items():
if hasattr(self,"info{0}".format(k)):
getattr(self,"info{0}".format(k)).SetLabel(v)
def OnRevDrop(self, event):
event.Skip()
rev = self.revDrop.GetValue()
print rev
self.CRDict = RevHist[rev]
self.UpdateValues(self.CRDict )
app = wx.PySimpleApp()
gui = TestGui()
gui.Show()
app.MainLoop()
虽然对于这样的东西我喜欢创建一个mixin
class EasyWidgetUpdater:
widgets = {}
def SetValue(self,valueDict):
for k,v in valueDict.items():
if k in self.widgets:
set_widget_value(self.widgets[k],v)
def GetValue(self):
result = {}
for k,widget in self.widgets:
result[k] = get_widget_value(widget)
return result
你需要getter和setter
def get_widget_value(widget):
if isinstance(widget,wx.TextCtrl):
return widget.GetLabel()
if hasattr(widget,"GetValue"):
return widget.GetValue()
raise Exception,"Unknown Widget {0}".format(widget)
def set_widget_value(widget,value):
if isinstance(widget,wx.TextCtrl):
return widget.SetLabel(value)
if hasattr(widget,"SetValue"):
return widget.SetValue(value)
raise Exception,"Unknown Widget {0}".format(widget)
然后你就可以做类似的事了
class WidgetFrame(wx.Frame,EasyWidgetUpdater):
def __init__(self,*args,**kwargs):
wx.Frame.__init__(self,*args,**kwargs)
sz = wx.BoxSizer()
sz.Add(self.CreateGUI())
self.SetSizer(sz)
self.Layout()
self.Fit()
def CreateGUI(self):
return wx.BoxSizer()
class TestGui(WidgetFrame):
def CreateGui(self):
self.panel = ScrolledPanel(parent=self, id=-1)
self.widgets['revision'] = wx.ComboBox(self,-1,choices=[...])
self.widgets['infoA'] = wx.Label(self,-1,"asdasd")
....
return self.panel
def OnRevDrop(self,evt):
CRDict = RevHist[self.GetValue()['revision']]
self.SetValue(CRDict)