wxPython - 检查空文本对话框
wxPython - checking for empty text dialogs
我有一些 python 代码,使用 wxpython,将执行以下操作:
- 使用 wxpython 对话框向用户询问号码
- 检查该号码当前是否正在使用,如果是,则会出现再次询问号码的框
- 输入未使用的号码后,将出现一个新对话框,要求输入姓名。如果正在使用,它会再次询问
- 新的号码和名字都被存储以备后用
代码看起来像这样:
while True:
codeNumberPrompt = wx.TextEntryDialog(self, "New code #: ", "Add New Code", str(len(self.codes)), style=wx.OK)
codeNumberPrompt.ShowModal()
self.codeNumber = codeNumberPrompt.GetValue()
#check if number is in use
if int(self.codeNumber) not in self.numbersInUse:
#new code name input
while True:
codeNamePrompt = wx.TextEntryDialog(self, "New code name: ", "Add New Code", style=wx.OK)
codeNamePrompt.ShowModal()
self.codeName = codeNamePrompt.GetValue()
#check if name is in use
if self.codeName.lower() not in self.namesInUse:
break
wx.MessageBox('Code name is currently in use', 'Warning', wx.OK | wx.ICON_INFORMATION)
break
else:
wx.MessageBox('Code number is currently in use', 'Warning', wx.OK | wx.ICON_INFORMATION)
我的第一个问题,是否有 better/cleaner 方法来做到这一点?
我的第二个问题(卡住的地方):我需要能够处理一些异常情况。例如:
- 如果用户 X 不在第一个对话框中,我不想显示第二个对话框,我想继续进行,就好像什么都没发生一样(即不尝试存储数字或名称值)
- 如果用户将号码或姓名对话框条目留空,我想再次询问他们该信息
我似乎无法找出 wxpython 如何处理对话框中的 X 按钮。目前,如果用户在第一个(数字)框中保留默认值,然后是 X,第二个框(名称)仍会显示
您应该能够捕获 wx.CLOSE
事件并防止对话框关闭。但是,我相信您最好使用向导型方法。在第一步中,您将检查号码,然后点击下一步。然后您将接受该名称并关闭对话框。我觉得这对用户来说是更自然的流程。
我整理了一个有趣的小例子,但您会注意到我没有以任何有意义的方式保存数据。您需要自己添加:
import wx
########################################################################
class MyDialog(wx.Dialog):
""""""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
wx.Dialog.__init__(self, None, title="Information")
self.numbers = [1, 2, 3]
self.names = ['mike', 'nick', 'george']
#--------------------------------------------------
# create the number panel
self.number_panel = wx.Panel(self)
self.number_text = wx.TextCtrl(self.number_panel)
self.number_text.SetFocus()
next_btn = wx.Button(self.number_panel, label='Next')
next_btn.Bind(wx.EVT_BUTTON, self.onNext)
panel_sizer = wx.BoxSizer(wx.VERTICAL)
panel_sizer.Add(self.number_text, 0, wx.ALL|wx.EXPAND, 5)
panel_sizer.Add(next_btn, 0, wx.ALL, 5)
self.number_panel.SetSizer(panel_sizer)
#--------------------------------------------------
# create the name panel
self.name_panel = wx.Panel(self)
self.name_panel.Hide()
self.name_text = wx.TextCtrl(self.name_panel)
ok_btn = wx.Button(self.name_panel, label='OK')
ok_btn.Bind(wx.EVT_BUTTON, self.onOK)
name_sizer = wx.BoxSizer(wx.VERTICAL)
name_sizer.Add(self.name_text, 0, wx.ALL, 5)
name_sizer.Add(ok_btn, 0, wx.ALL, 5)
self.name_panel.SetSizer(name_sizer)
#--------------------------------------------------
# layout panels
self.my_sizer = wx.BoxSizer(wx.VERTICAL)
self.my_sizer.Add(self.number_panel, 1, wx.EXPAND)
self.my_sizer.Add(self.name_panel, 1, wx.EXPAND)
self.SetSizer(self.my_sizer)
#--------------------------------------------------
self.ShowModal()
wx.CallAfter(self.my_sizer.Layout)
#----------------------------------------------------------------------
def onNext(self, event):
""""""
number = int(self.number_text.GetValue())
if number in self.numbers:
wx.MessageBox('Code number is currently in use',
'Warning', wx.OK | wx.ICON_INFORMATION)
self.number_text.SetFocus()
return
else:
self.my_sizer.Detach(self.number_panel)
self.name_panel.Show()
self.Layout()
self.numbers.append(number)
#----------------------------------------------------------------------
def onOK(self, event):
""""""
name = self.name_text.GetValue()
if name.lower() in self.names:
wx.MessageBox('Code name is currently in use',
'Warning', wx.OK | wx.ICON_INFORMATION)
return
else:
self.names.append(name)
self.Close()
########################################################################
class MyPanel(wx.Panel):
""""""
#----------------------------------------------------------------------
def __init__(self, parent):
"""Constructor"""
wx.Panel.__init__(self, parent)
info_button = wx.Button(self, label="Get Info")
info_button.Bind(wx.EVT_BUTTON, self.onGetInfo)
#----------------------------------------------------------------------
def onGetInfo(self, event):
""""""
dlg = MyDialog()
dlg.Destroy()
########################################################################
class MyFrame(wx.Frame):
""""""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
wx.Frame.__init__(self, None, title='Demo')
panel = MyPanel(self)
self.Show()
if __name__ == '__main__':
app = wx.App(False)
frame = MyFrame()
app.MainLoop()
我有一些 python 代码,使用 wxpython,将执行以下操作:
- 使用 wxpython 对话框向用户询问号码
- 检查该号码当前是否正在使用,如果是,则会出现再次询问号码的框
- 输入未使用的号码后,将出现一个新对话框,要求输入姓名。如果正在使用,它会再次询问
- 新的号码和名字都被存储以备后用
代码看起来像这样:
while True:
codeNumberPrompt = wx.TextEntryDialog(self, "New code #: ", "Add New Code", str(len(self.codes)), style=wx.OK)
codeNumberPrompt.ShowModal()
self.codeNumber = codeNumberPrompt.GetValue()
#check if number is in use
if int(self.codeNumber) not in self.numbersInUse:
#new code name input
while True:
codeNamePrompt = wx.TextEntryDialog(self, "New code name: ", "Add New Code", style=wx.OK)
codeNamePrompt.ShowModal()
self.codeName = codeNamePrompt.GetValue()
#check if name is in use
if self.codeName.lower() not in self.namesInUse:
break
wx.MessageBox('Code name is currently in use', 'Warning', wx.OK | wx.ICON_INFORMATION)
break
else:
wx.MessageBox('Code number is currently in use', 'Warning', wx.OK | wx.ICON_INFORMATION)
我的第一个问题,是否有 better/cleaner 方法来做到这一点?
我的第二个问题(卡住的地方):我需要能够处理一些异常情况。例如:
- 如果用户 X 不在第一个对话框中,我不想显示第二个对话框,我想继续进行,就好像什么都没发生一样(即不尝试存储数字或名称值)
- 如果用户将号码或姓名对话框条目留空,我想再次询问他们该信息
我似乎无法找出 wxpython 如何处理对话框中的 X 按钮。目前,如果用户在第一个(数字)框中保留默认值,然后是 X,第二个框(名称)仍会显示
您应该能够捕获 wx.CLOSE
事件并防止对话框关闭。但是,我相信您最好使用向导型方法。在第一步中,您将检查号码,然后点击下一步。然后您将接受该名称并关闭对话框。我觉得这对用户来说是更自然的流程。
我整理了一个有趣的小例子,但您会注意到我没有以任何有意义的方式保存数据。您需要自己添加:
import wx
########################################################################
class MyDialog(wx.Dialog):
""""""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
wx.Dialog.__init__(self, None, title="Information")
self.numbers = [1, 2, 3]
self.names = ['mike', 'nick', 'george']
#--------------------------------------------------
# create the number panel
self.number_panel = wx.Panel(self)
self.number_text = wx.TextCtrl(self.number_panel)
self.number_text.SetFocus()
next_btn = wx.Button(self.number_panel, label='Next')
next_btn.Bind(wx.EVT_BUTTON, self.onNext)
panel_sizer = wx.BoxSizer(wx.VERTICAL)
panel_sizer.Add(self.number_text, 0, wx.ALL|wx.EXPAND, 5)
panel_sizer.Add(next_btn, 0, wx.ALL, 5)
self.number_panel.SetSizer(panel_sizer)
#--------------------------------------------------
# create the name panel
self.name_panel = wx.Panel(self)
self.name_panel.Hide()
self.name_text = wx.TextCtrl(self.name_panel)
ok_btn = wx.Button(self.name_panel, label='OK')
ok_btn.Bind(wx.EVT_BUTTON, self.onOK)
name_sizer = wx.BoxSizer(wx.VERTICAL)
name_sizer.Add(self.name_text, 0, wx.ALL, 5)
name_sizer.Add(ok_btn, 0, wx.ALL, 5)
self.name_panel.SetSizer(name_sizer)
#--------------------------------------------------
# layout panels
self.my_sizer = wx.BoxSizer(wx.VERTICAL)
self.my_sizer.Add(self.number_panel, 1, wx.EXPAND)
self.my_sizer.Add(self.name_panel, 1, wx.EXPAND)
self.SetSizer(self.my_sizer)
#--------------------------------------------------
self.ShowModal()
wx.CallAfter(self.my_sizer.Layout)
#----------------------------------------------------------------------
def onNext(self, event):
""""""
number = int(self.number_text.GetValue())
if number in self.numbers:
wx.MessageBox('Code number is currently in use',
'Warning', wx.OK | wx.ICON_INFORMATION)
self.number_text.SetFocus()
return
else:
self.my_sizer.Detach(self.number_panel)
self.name_panel.Show()
self.Layout()
self.numbers.append(number)
#----------------------------------------------------------------------
def onOK(self, event):
""""""
name = self.name_text.GetValue()
if name.lower() in self.names:
wx.MessageBox('Code name is currently in use',
'Warning', wx.OK | wx.ICON_INFORMATION)
return
else:
self.names.append(name)
self.Close()
########################################################################
class MyPanel(wx.Panel):
""""""
#----------------------------------------------------------------------
def __init__(self, parent):
"""Constructor"""
wx.Panel.__init__(self, parent)
info_button = wx.Button(self, label="Get Info")
info_button.Bind(wx.EVT_BUTTON, self.onGetInfo)
#----------------------------------------------------------------------
def onGetInfo(self, event):
""""""
dlg = MyDialog()
dlg.Destroy()
########################################################################
class MyFrame(wx.Frame):
""""""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
wx.Frame.__init__(self, None, title='Demo')
panel = MyPanel(self)
self.Show()
if __name__ == '__main__':
app = wx.App(False)
frame = MyFrame()
app.MainLoop()