.. include:: headings.inc


.. _validator overview:

=======================================
|phoenix_title|  **Validator Overview**
=======================================


.. _validator basic concepts:

Validator basic concepts
------------------------

The aim of the validator concept is to make dialogs very much easier
to write. A validator is an object that can be plugged into a control
(such as a :ref:`wx.TextCtrl`), and mediates between Python data and
the control, transferring the data in either direction and validating
it. It also is able to intercept events generated by the control,
providing filtering behaviour without the need to derive a new control
class.

:ref:`wx.Validator` can also be used to intercept keystrokes and other
events within an input field. To use a validator, you have to create
your own sub-class of :ref:`wx.Validator` (neither `TextValidator` nor
`GenericValidator` are implemented in wxPython). This sub-class is
then associated with your input field by calling::

     myInputField.SetValidator(myValidator)
     
     
.. note:: Your :ref:`wx.Validator` sub-class must implement the
   :meth:`wx.Validator.Clone` method.


.. note:: 

   Note that any :ref:`wx.Window` may have a validator; using the
   ``WS_EX_VALIDATE_RECURSIVELY`` style (see :ref:`Window extended
   styles <window-extra-styles>`) you can also implement recursive
   validation.
   


.. _anatomy of a validator:

Anatomy of a Validator
----------------------

A programmer creating a new validator class should provide the
following functionality.

A validator constructor is responsible for allowing the programmer to
specify the kind of validation required, and perhaps a pointer to a
Python variable that is used for storing the data for the control. If
such a variable address is not supplied by the user, then the
validator should store the data internally.

The :meth:`wx.Validator.Validate` method should return true if the
data in the control (not the Python variable) is valid.  It should
also show an appropriate message if data was not valid.

The :meth:`wx.Validator.TransferToWindow` member function should
transfer the data from the validator or associated Python variable to
the control.

The :meth:`wx.Validator.TransferFromWindow` member function should
transfer the data from the control to the validator or associated
Python variable.

There should be a copy constructor, and a :meth:`wx.Validator.Clone`
function which returns a copy of the validator object.  This is
important because validators are passed by reference to window
constructors, and must therefore be cloned internally.

You can optionally define event handlers for the validator, to
implement filtering. These handlers will capture events before the
control itself does (see :ref:`How Events are Processed <how events
are processed>`).



.. _how validators interact with dialogs:

How Validators Interact with Dialogs
------------------------------------


For validators to work correctly, validator functions must be called
at the right times during dialog initialisation and dismissal.

When a :meth:`wx.Dialog.Show` is called (for a modeless dialog) or
:meth:`wx.Dialog.ShowModal` is called (for a modal dialog), the
function :meth:`wx.Window.InitDialog` is automatically called. This in
turn sends an initialisation event to the dialog. The default handler
for the ``wxEVT_INIT_DIALOG`` event is defined in the :ref:`wx.Window`
class to simply call the function
:meth:`wx.Window.TransferDataToWindow`. This function finds all the
validators in the window's children and calls the
:meth:`wx.Validator.TransferToWindow` function for each. Thus, data is
transferred from Python variables to the dialog just as the dialog is
being shown.

.. note:: If you are using a window or panel instead of a dialog, you
    will need to call :meth:`wx.Window.InitDialog` explicitly before
    showing the window.
   

When the user clicks on a button, for example the ``OK`` button, the
application should first call :meth:`wx.Window.Validate`, which
returns ``False`` if any of the child window validators failed to
validate the window data. The button handler should return immediately
if validation failed. Secondly, the application should call
:meth:`wx.Window.TransferDataFromWindow` and return if this failed.
It is then safe to end the dialog by calling
:meth:`wx.Dialog.EndModal` (if modal) or :meth:`wx.Dialog.Show` (if
modeless).

In fact, :ref:`wx.Dialog` contains a default command event handler for
the ``ID_OK`` button. It goes like this::

	def OnOK(self, event):

	    if self.Validate() and self.TransferDataFromWindow():

		if self.IsModal():
		    self.EndModal(wx.ID_OK)
		else:
		    self.SetReturnCode(wx.ID_OK)
		    self.Show(False)



So if using validators and a normal ``OK`` button, you may not even
need to write any code for handling dialog dismissal.

If you load your dialog from a resource file, you will need to iterate
through the controls setting validators, since validators can't be
specified in a dialog resource.

