wxPython: 使用Show()和Hide()
我正在做一个简单的程序,用来收集和检查用户输入的信息。除了在用户输入不符合要求时显示一个提示框外,我还想在输入框的右边加一个提示,告诉用户需要输入什么类型的数据。为此,我创建了一个单行的FlexGridSizer,里面包含了以下内容:
[(wx.StaticText, "姓名"), (wx.TextCtrl, "在这里输入用户信息"), (wx.StaticText, "输入提示")]
在程序初始化时,“输入提示”这个部分是隐藏的。如果用户在输入框里什么都没输入,然后点击确认按钮,我希望能发生三件事情:
- 输入框的颜色改变,以提醒用户有问题
- 第三个部分“输入提示”变得可见
- 对话框会自动调整大小,以适应现在可见的部分
到目前为止,我只实现了第一点,正在寻找帮助来完成第二点和第三点。
import wx
class Not_Empty(wx.PyValidator):
def __init__(self):
wx.PyValidator.__init__(self)
def Clone(self):
return Not_Empty()
################################################################################
def Validate(self, win):
""""""
evt_location = self.GetWindow()
val = evt_location.GetValue()
if val == "":
evt_location.SetBackgroundColour(wx.Color(250,200,230))
MyDialog().nameWarning_ST.Show(True)
return False
else:
return True
################################################################################
def TransferToWindow(self):
return True
def TransferFromWindow(self):
return True
class MyDialog(wx.Dialog):
def __init__(self):
wx.Dialog.__init__(self, parent=None, id=-1, title="Getting Input", style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER)
# Create field labels
name = wx.StaticText(self, -1, "Name")
# Create user-input widgets
name_TC = wx.TextCtrl(self, validator=Not_Empty())
# Create and hide warning boxes
self.nameWarning_ST = wx.StaticText(self, label="Field cannot be left empty", name="emptyAlert")
# to see what I want the dialog to look like AFTER the user has entered an
# empty string change 'False' to 'True' in the line below.
self.nameWarning_ST.Show(False)
# Create accept/cancel buttons
btns = self.CreateButtonSizer(flags=wx.OK|wx.CANCEL)
self.mainSizer = wx.BoxSizer(wx.VERTICAL)
fgs = wx.FlexGridSizer(cols = 3, rows = 1)
fgs.AddMany([(name, -1, wx.ALL, 5), (name_TC, -1, wx.ALL, 5), (self.nameWarning_ST, -1, wx.ALL, 5)])
self.mainSizer.AddMany([(fgs, 1, wx.ALL, 0), (btns, 1, wx.ALL|wx.EXPAND, 5)])
self.SetSizer(self.mainSizer)
self.mainSizer.Fit(self)
if __name__ == '__main__':
app = wx.App()
dlg = MyDialog()
dlg.Center()
dlg.ShowModal()
dlg.Destroy()
app.MainLoop()
1 个回答
3
编辑:对于新的问题,我建议使用pubsub来解决。你可以在MyDialog类的初始化时设置一个监听器,然后在另一个类的Validate方法运行时向它发布一条消息。在你理论上会在MyDialog中创建的消息处理器里,你需要显示其他的控件,并在对话框上调用Layout()。这样应该会让它适当地调整大小。
你可以在这里阅读关于pubsub的教程:http://www.blog.pythonlibrary.org/2010/06/27/wxpython-and-pubsub-a-simple-tutorial/
以下内容是针对原始问题的:
你的Validate方法从来没有被触发,所以我把你的Validate和OnChar方法重新排列成了下面的样子:
import string
def Validate(self, win):
"""
Enter your code here...
"""
return True
def OnChar(self, event):
txtObj = event.GetEventObject()
txt = txtObj.GetValue()
if txt == "": txt = '0'
key = chr(event.GetKeyCode())
if key in string.digits:
if int(txt+str(key)) < 150:
event.Skip()
else:
msg = "You have entered an age greater than 150!"
wx.MessageBox(msg, "Improbable entry", style=wx.OK|wx.ICON_ERROR)
# PROBLEM ARISES HERE
# ===================
MyDialog().ageWarning_ST.Show()
MyDialog().mainSizer.Fit(MyDialog())
return False
key = event.GetKeyCode()
if key in(wx.WXK_RETURN, wx.WXK_DELETE, wx.WXK_BACK):
event.Skip()
elif (chr(key)).isdigit():
event.Skip()
else:
return
另外,我还导入了字符串模块,这样会让事情变得简单一些。代码可能还需要一些整理,但在我的机器上是可以运行的。