wxPython:使用Show()和Hide()

时间:2011-11-01 17:24:41

标签: python wxpython hide show validation

我正在开发一个收集和检查用户输入的简单程序。除了显示 一个消息框,如果用户提供的输入未通过检查,我还想添加提示 在输入字段的右侧,告诉用户需要什么类型的数据。为此,我创建了一个由以下组成的单行FlexGridSizer:

  

[(wx.StaticText,“Name”),(wx.TextCtrl,“这里的用户输入”),(wx.StaticText,“输入指导”)]

初始化时,隐藏“输入指导”小部件。如果用户未能在提供的字段中输入任何内容,然后点击“确定”按钮,我希望发生三件事

  1. 字段更改颜色以提醒用户注意问题
  2. “输入指南”小部件(上一行中的第三个)变为可见
  3. DialogBox会自动调整大小以考虑现在可见的小部件
  4. 到目前为止,我只能(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()
    

1 个答案:

答案 0 :(得分:3)

编辑:对于新问题,我会使用pubsub来解决这个问题。将侦听器放入MyDialog类的init,然后在另一个类中运行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

另请注意,我导入了字符串模块,使事情变得更容易一些。代码可能需要一些清理,但它可以在我的机器上运行。