Валидаторы wxPython в фреймах/панели не работают

Я новичок в python и wx, я делаю приложение, и я сделал некоторые формы и прочее на wxPython через рамки и панель. Теперь я хочу проверить поля, поэтому мне нужно проверить TextCtrl, но у меня так много проблем.

Я много читал об этом, и у меня ничего не работает, кажется, что все валидаторы предназначены для работы с wx.Dialogs, но не с фреймами или панелями.

В документации wx я нашел следующее утверждение, но понятия не имею, как его применить. В Интернете нет учебника или чего-то полезного, поэтому я очень расстроен, любая помощь будет оценена по достоинству!

""Если вы используете окно или панель вместо диалогового окна, вам нужно будет явно вызвать wx.Window.InitDialog, прежде чем показывать окно." https://wxpython.org/Phoenix/docs/html/validator_overview.html

Я адаптировал наиболее похожий пример валидатора, который был сделан с диалогом, я адаптировал его для работы с фреймом, но он не работает.

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

оригинальный рабочий код: http://www.pygopar.com/using-validators-from-wxpython


person Cesar Tabares    schedule 09.02.2020    source источник
comment
что происходит, когда вы запускаете код выше? Вы получаете ошибку? Он принимает все символы, а не только цифры? Он вообще запускается?   -  person Igor    schedule 10.02.2020
comment
Ничего не произошло, ошибки нет, но валидация не проходит   -  person Cesar Tabares    schedule 10.02.2020


Ответы (1)


Валидаторы используются стандартными реализациями функций TransferDataToWindow(), Validate() и TransferDataFromWindow(), которые автоматически вызываются для модальных диалогов, когда диалог отображается и когда он закрывается. Вы по-прежнему можете использовать валидаторы с окнами других типов, но в этом случае вам нужно будет вызывать эти функции самостоятельно. Для первого достаточно просто вызвать его самостоятельно после завершения создания фрейма, но вы также можете вызвать InitDialog(), который сделает это косвенно за вас (хотя я действительно не понимаю, зачем вам это делать). Для последних двух вам нужно вызывать их вручную всякий раз, когда пользователь «принимает» выбор, например. обычно, когда какая-то кнопка нажата, и логика здесь состоит в том, чтобы сначала вызвать Validate(), а затем, если она возвращает true, вызвать TransferDataFromWindow(), чтобы фактически сохранить данные, введенные пользователем, в переменных вашей программы.

Конечно, если вам не нужно ничего передавать (в вашем примере вы этого не делаете), вы можете просто вызвать Validate() и забыть о двух других функциях.

person VZ.    schedule 09.02.2020