python-2.7wxpythonwx.textctrl

wx.TextCtrl is blank for very long strings


I'm trying to display the string representation of a list of many float items in a wx.TextCtrl using the SetValue() method.

As soon as the length of the string to be displayed reaches 6151 characters the TextCtrl goes blank and does not display the string. I can still copy portions of the text control as normal and paste them somewhere (such as a text editor) but the characters in the text control itself don't appear on the screen.

Why isn't the text control's value displayed in the text control? How do I make it display the string if it's longer than 6150 characters?

This happens when setting the text control's value using the SetValue method and when typing in the text control.

Changing the max length for the text control didn't help.

Environment:

Example code:

import wx
import os
class MainWindow(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, title=title, size=(200,-1))
        self.control = wx.TextCtrl(self)
        self.control.SetMaxLength(10000) #doesn't help

        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.control, 1, wx.EXPAND)

        self.SetSizer(self.sizer)
        self.SetAutoLayout(1)
        self.sizer.Fit(self)

        self.Show(True)


app = wx.App(False)
frame = MainWindow(None, "Sample editor")
app.MainLoop()

Solution

  • It looks like a bug. According to the this, it should max out at 64K since Windows 98 unless the operating system you have has some kind of odd limit. You can actually increase the number of characters displayed by using one of the wx.TE_RICH style flags.

    I was able to replicate your issue on Windows 7 with Python 2.7 and wxPython 3.0.2 using the following code:

    import wx
    
    ########################################################################
    class MyPanel(wx.Panel):
        """"""
    
        #----------------------------------------------------------------------
        def __init__(self, parent):
            """Constructor"""
            super(MyPanel, self).__init__(parent)
    
            self.text = wx.TextCtrl(self, value="y"*7000)
            btn = wx.Button(self, label='Line Length')
            btn.Bind(wx.EVT_BUTTON, self.onLength)
    
            sizer = wx.BoxSizer(wx.VERTICAL)
            sizer.Add(self.text, 0, wx.EXPAND|wx.ALL, 5)
            sizer.Add(btn, 0, wx.CENTER|wx.ALL, 5)
            self.SetSizer(sizer)
    
    
        #----------------------------------------------------------------------
        def onLength(self, event):
            """"""
            print len(self.text.GetValue())
    
    ########################################################################
    class MyFrame(wx.Frame):
        """"""
    
        #----------------------------------------------------------------------
        def __init__(self):
            """Constructor"""
            super(MyFrame, self).__init__(parent=None, title='Test')
            panel = MyPanel(self)
            self.Show()
    
    
    if __name__ == '__main__':
        app = wx.App(False)
        frame = MyFrame()
        app.MainLoop()
    

    If I add the wx.TE_RICH flag and call Layout(), I can make it work though:

    import wx
    
    ########################################################################
    class MyPanel(wx.Panel):
        """"""
    
        #----------------------------------------------------------------------
        def __init__(self, parent):
            """Constructor"""
            super(MyPanel, self).__init__(parent)
    
            self.text = wx.TextCtrl(self, value="y"*7000, style=wx.TE_RICH)
            btn = wx.Button(self, label='Line Length')
            btn.Bind(wx.EVT_BUTTON, self.onLength)
    
            sizer = wx.BoxSizer(wx.VERTICAL)
            sizer.Add(self.text, 0, wx.EXPAND|wx.ALL, 5)
            sizer.Add(btn, 0, wx.CENTER|wx.ALL, 5)
            self.SetSizer(sizer)
            self.Layout()
    
    
        #----------------------------------------------------------------------
        def onLength(self, event):
            """"""
            print len(self.text.GetValue())
    
    ########################################################################
    class MyFrame(wx.Frame):
        """"""
    
        #----------------------------------------------------------------------
        def __init__(self):
            """Constructor"""
            super(MyFrame, self).__init__(parent=None, title='Test')
            panel = MyPanel(self)
            self.Show()
    
    
    if __name__ == '__main__':
        app = wx.App(False)
        frame = MyFrame()
        app.MainLoop()
    

    You should report this bug here: http://trac.wxwidgets.org/