wxPython:使用 Show() 和 Hide()
我正在开发一个收集和检查用户输入的简单程序。除了展示之外 如果用户提供的输入未通过检查,则会出现一个消息框,我还想添加一个提示 就在输入字段的右侧,告诉用户需要什么类型的数据。为了实现此目的,我创建了一个单行 FlexGridSizer,其中包含以下内容:
[(wx.StaticText, "名称"), (wx.TextCtrl, "用户在此输入"), (wx.StaticText, "输入指导")]
在初始化时,“输入指导”小部件被隐藏。如果用户未能在提供的字段中输入任何内容,然后单击“确定”按钮,我希望发生三件事
- 字段会更改颜色以提醒用户有问题
- “输入指导”小部件(上行中的第三个)变得
- 可见DialogBox 会自动调整大小以考虑现在可见的小部件
到目前为止,我只能使(1)工作,并且正在寻求有关(2)和(3)的帮助。
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()
I'm working on a simple program that collects and checks user-input. In addition to displaying
a message box if the user-supplied input fails the checks, I'd also like to add a prompt
just to the right of the input field telling the user what type of data is required. To accomplish this I've created a single-row FlexGridSizer consisting of the following:
[(wx.StaticText, "Name"), (wx.TextCtrl, "user inputs here"), (wx.StaticText, "Input Guidance")]
On initialization the "Input Guidance" widget is hidden. If the user fails to enter anything in provided field, and then hits the OK button, I want three things to happen
- Field changes colour to alert user to a problem
- The "input guidance" widget (the third in the above row) becomes visible
- The DialogBox is automatically resized to take account of the now visible widget
So far I can only get (1) to work, and am looking for help with (2) and (3).
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()
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
编辑:对于新问题,我将使用 pubsub 来解决这个问题。将侦听器放置在 MyDialog 类的 init 中,然后在另一个类中运行 Validate 方法时向其发布消息。在理论上您将在 MyDialog 中创建的消息处理程序中,您需要显示其他小部件并在对话框上调用 Layout()。这应该会导致它适当调整大小。
您可以在此处阅读有关 pubsub 的教程: http://www.blog.pythonlibrary.org/2010/06/27/wxpython-and-pubsub-a-simple-tutorial/
以下内容适用于原始问题:
您的 Validate 方法永远不会触发,因此我重新排列了您的 Validate 和 OnChar 方法,如下所示:
另请注意,我导入了 string 模块以使事情变得更容易一些。该代码可能需要一些清理,但它在我的机器上运行。
EDIT: For the new question(s), I would use pubsub to solve this. Put a listener the init of the MyDialog class and then publish a message to it when the Validate method is run in the other class. In the message handler that you will theoretically create in MyDialog, you'll want Show your other widget and call Layout() on the dialog. That should cause it to resize appropriately.
You can read a tutorial on pubsub here: http://www.blog.pythonlibrary.org/2010/06/27/wxpython-and-pubsub-a-simple-tutorial/
The following was for the original question:
Your Validate method doesn't ever fire, so I rearranged your Validate and OnChar methods to look like the following:
Also note that I imported the string module to makes things a little easier. The code probably needs some clean up, but it worked on my machine.