Search code examples
pythonpython-2.7dialogwxpythonxrc

Replacing widgets in a xrc created dialog


I would like to replace a dialog's object dynamically but didn't find a way. The dialog is created with the help of a xrc definition file.

All what I found is https://www.blog.pythonlibrary.org/2012/05/05/wxpython-adding-and-removing-widgets-dynamically/: needs to access a sizer, but xrc does not provide access to sizer objects as far as I know.

Can anybody help?

My system: python 2.7, wxpython 3.0.2.0, win7

Best regards Humbalan


Solution

  • With the help of Goyo's post I found the following solution:

    def exchange_control( self, control, coded ) :
    """
    Exchanges a wx.TextCtrl (where wx.TE_PASSWORD is set) with a wx.TextCtrl (where
    wx.TE_PASSWORD is not set) and vice versa. A similar code could be used to exchange
    for exampe a DirPickerCtrl with a FilePickerCtrl.
    
    :param wx.TextCtrl control: Contains a coded or encoded text dependend on `coded`.
    :param bool coded: True if the text in `control` is coded, False if it is encoded.
    
    :returns: 
        A new wx.TextCtrl with the coded (`coded` was False) or encoded Text (`coded` was 
        True) of `control`.
    :rtype: wx.TextCtrl
    """
        containing_sizer = control.GetContainingSizer() # get the sizer containing `control`
    
        # Compute arguments for a new TextCtrl. 
        # - The value of style is arbitrary except the TE_PASSWORD part. 
        # - a_validator is a validator checking correctness of the value of `control`, is 
        #   optional.
        kwargs = { 'parent'   : control.Parent,
                   'id'       : wx.ID_ANY,
                   'value'    : control.GetValue(),
                   'size'     : control.Size,
                   'style'    : wx.TE_NO_VSCROLL|wx.TE_PASSWORD if coded  else wx.TE_NO_VSCROLL,
                   'name'     : control.Name,
                   'validator': a_validator
                 }
    
        # Setup a new TextCtrl with the arguments kwargs
        new_text_ctrl = wx.TextCtrl( **kwargs )
    
        containing_sizer.Replace( control, new_text_ctrl )
        containing_sizer.Layout()
    
        return new_text_ctrl
    
    # In the calling code:
    # The returned `the_text_ctrl` is the TextCtrl Field with the (en)coded Text and `coded` 
    # is  the boolean value  which shows if the text whithin this field is coded or encoded. 
    the_text_ctrl = self.exchange_control( the_text_ctrl, coded )
    

    EDIT:

    I changed the code since I found out that the method Replace() is much easier to use than my first attempt.