0

I'm pretty new to python and wx, I'm making an application and I've made some forms and stuff on wxPython trough frames and panel. Now I want to validate the fields, so i have to validate the TextCtrl, but I'm having so much troubles .

I've read a lot about this, and nothing work to me, all the validators seems to be designed to work with wx.Dialogs but not with frames or panels.

In the wx documentacion I've find the following statement , but I have no idea how to apply. theres is no tutorial on internet or something helpful, so I'm quite frustraded, any help would be appreciated!.

""If you are using a window or panel instead of a dialog, you will need to call wx.Window.InitDialog explicitly before showing the window."" https://wxpython.org/Phoenix/docs/html/validator_overview.html

I've adapted the most similar example of validator that was made with dialog, si I adapted to work with frame but it does not work.

import wx
###############################################################################

class CustomNumValidator(wx.Validator):
    """ Validator for entering custom low and high limits """
    print('creado')
    def __init__(self):
        super(CustomNumValidator, self).__init__()


    # --------------------------------------------------------------------------
    def Clone(self):
        """ """
        return CustomNumValidator()

    # --------------------------------------------------------------------------
    def Validate(self, win):
        """ """
        textCtrl = self.GetWindow()
        text = textCtrl.GetValue()
        print('pasando')
        if text.isdigit():
            return True
        else:
            wx.MessageBox("Please enter numbers only", "Invalid Input",
            wx.OK | wx.ICON_ERROR)
        return False

    # --------------------------------------------------------------------------
    def TransferToWindow(self):
        return True

    # --------------------------------------------------------------------------
    def TransferFromWindow(self):
        return True


class CustomNumbers(wx.Frame):
    """ Dialog for choosing custom numbers """
    def __init__(self, *args, **kwargs):
        super(CustomNumbers, self).__init__(*args, **kwargs)

        wx.Frame.__init__(self, None, wx.ID_ANY, "Software Legal")

        self.SetBackgroundColour("WHITE")
        self.widget_dict = {}

        self.initUI()
        self.SetSizerAndFit(self.main_sizer)

        self.Layout()
        self.Refresh()

    # --------------------------------------------------------------------------
    def initUI(self):
        """ """
        self.createSizer()
        self.createText()
        self.createInputBox()
        self.createButton()
        self.addSizerContent()

    # --------------------------------------------------------------------------
    def createSizer(self):
        self.main_sizer = wx.BoxSizer(wx.VERTICAL)

    # --------------------------------------------------------------------------
    def createText(self):
        """ """
        low_num_text = wx.StaticText(self, -1, "Low Number")
        high_num_text = wx.StaticText(self, -1, "High Number")

        self.widget_dict["low_num_text"] = low_num_text
        self.widget_dict["high_num_text"] = high_num_text

    # --------------------------------------------------------------------------
    def createInputBox(self):
        """ """
        low_input = wx.TextCtrl(self, validator=CustomNumValidator())
        high_input = wx.TextCtrl(self, validator=CustomNumValidator())
        self.widget_dict["low_input"] = low_input
        self.widget_dict["high_input"] = high_input

    # --------------------------------------------------------------------------
    def createButton(self):
        """ """
        ok_btn = wx.Button(self, wx.ID_OK, "Enter")
        cancel_btn = wx.Button(self, wx.ID_CANCEL, "Cancel")

        self.widget_dict["ok_btn"] = ok_btn
        self.widget_dict["cancel_btn"] = cancel_btn

    # --------------------------------------------------------------------------
    def addSizerContent(self):
        """ """
        top_sizer = wx.BoxSizer()
        top_sizer.Add(self.widget_dict["low_num_text"], 3, wx.ALL, 10)
        top_sizer.Add(self.widget_dict["low_input"], 7, wx.ALL ^ wx.RIGHT, 10)

        btm_sizer = wx.BoxSizer()
        btm_sizer.Add(self.widget_dict["high_num_text"], 3, wx.ALL, 10)
        btm_sizer.Add(self.widget_dict["high_input"], 7, wx.ALL, 10)

        btn_sizer = wx.BoxSizer()
        btn_sizer.Add(self.widget_dict["ok_btn"], 0, wx.CENTER | wx.ALL, 10)
        btn_sizer.Add(self.widget_dict["cancel_btn"], 0,
                      wx.CENTER | wx.ALL, 10)

        self.main_sizer.Add(top_sizer)
        self.main_sizer.Add(btm_sizer)
        self.main_sizer.Add(btn_sizer, 0, wx.CENTER | wx.ALL, 10)

    # --------------------------------------------------------------------------
    def getValues(self):
        """ """


###############################################################################


class MyApp(wx.App):
    def OnInit(self):
        self.frame= CustomNumbers()
        self.frame.Show()
        return True       

# Run the program     
app=MyApp()
app.MainLoop()
del app

original working code is this: http://www.pygopar.com/using-validators-from-wxpython

  • what is happening when you run the code above? Do you get an error? Does it takes all characters instead of just numbers? Does it run at all? – Igor Feb 09 '20 at 21:31
  • Nothing happend, no error , but the validation doesn’t get through – Cesar Tabares Feb 10 '20 at 00:45

1 Answers1

0

Validators are used by the default implementations of TransferDataToWindow(), Validate() and TransferDataFromWindow() functions which are called automatically for the modal dialogs when the dialog is shown and when it's dismissed. You can still use validators with the other kinds of windows, but you need to call these functions yourself in this case. For the former, it's easy enough to just call it yourself after finishing constructing your frame, but you can also call InitDialog() which will do it indirectly for you (I don't really see why would you do this though). For the latter two, you need to call them manually whenever the user "accepts" the choice, e.g. typically when some button is clicked and the logic here is to call Validate() first and then, if it returns true, call TransferDataFromWindow() to actually store the data entered by the user in your program variables.

Of course, if you don't need to transfer anything (you don't do this in your example), you can just call Validate() and forget the 2 other functions.

VZ.
  • 21,740
  • 3
  • 39
  • 42