Search code examples
pythonwxpythonwxtextctrl

wxPython wx.TextCtrl tab width


How to set the Tab width to 4 rather than 8 in wx.TextCtrl?
if not possible what is the alternative to use instead of wx.TextCtrl?

Note:
mytxtCtrl.setDefaultStyle(wx.TextAttr().setTabs([...]) not working!


Solution

  • SetTabs are set in tenths of millimeter. Not sure why, that is brutal to work with!

    import wx
    
    TAB = 4
    
    TEST = "".join([" "*i*TAB + "|\n" + "\t"*i + "|\n" for i in range(1, 30, 2)])
    
    class MainWindow(wx.Frame):
        def __init__(self, *args, **kwargs):
            wx.Frame.__init__(self, *args, **kwargs)
    
            self.panel = wx.Panel(self)
            self.text = wx.TextCtrl(self.panel, style=wx.TE_PROCESS_TAB | wx.TE_RICH | wx.TE_MULTILINE)
    
            self.sizer = wx.BoxSizer()
            self.sizer.Add(self.text, 1, wx.ALL | wx.EXPAND)
    
            self.text.Bind(wx.EVT_SIZE, self.SetTabs)
    
            self.panel.SetSizerAndFit(self.sizer)
            self.Show()
    
            self.text.SetValue(TEST)
    
        def SetTabs(self, e):  
            pixel_width_in_mm = 25.4 / wx.ScreenDC().GetPPI()[0]
            space_width_in_pixels = self.text.GetTextExtent(" ")[0]
            tab_width_in_tenth_of_mm = (10 * TAB * space_width_in_pixels * pixel_width_in_mm)
            textctrl_width_in_mm = (10 * self.text.GetSize()[0] * (1 / pixel_width_in_mm))
            nr_of_tabs = int(textctrl_width_in_mm / tab_width_in_tenth_of_mm)
            tabs = [int((i+1)*tab_width_in_tenth_of_mm) for i in range(nr_of_tabs)]
            attr = wx.TextAttr()
            attr.SetTabs(tabs)
            self.text.SetDefaultStyle(attr)
    
    app = wx.App(False)
    win = MainWindow(None)
    app.MainLoop()