-1

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

Humbalan
  • 677
  • 3
  • 14
  • How are sizers different than other widgets? – Stop harming Monica Jun 13 '17 at 09:49
  • sizers have no name in XRC. If I add one, it is ignored. Example: XRC: . Instantiation it the code is with self.my_text_ctrl = wx.xrc.XRCCTRL( self, "myTextCtrl"), XRCCTRL returns an instance of wx.TextCtrl. On the other hand if I declare and instantiate with self.my_grid_bag=wx.xrc.XRCCTRL( self, "myGridBag") XRCCTRL returns None. – Humbalan Jun 13 '17 at 10:03
  • To the one who downvoted my question: I always want to learn how to do better. Could you please tell me why you downvoted? – Humbalan Jun 13 '17 at 10:18
  • This is old but I guess things have not improved much. http://wxwidgets.10942.n7.nabble.com/Access-a-sizer-loaded-from-XRC-td1788.html – Stop harming Monica Jun 13 '17 at 10:25
  • Thanks, Goyo, that is exactly what I needed. Have still some difficulties with the layout but I hope to solve that soon. If you copy your advice to an answer field I coud mark my question as "solved." – Humbalan Jun 13 '17 at 11:16
  • I just found that in Google, I don't have much knowledge about wx and don't have it installed. I don't feel like writing an answer without code I can test. I encourage you to write an answer including a minimal example of what worked for your specific case. – Stop harming Monica Jun 13 '17 at 11:35

1 Answers1

0

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.

Humbalan
  • 677
  • 3
  • 14