How to get initial MaxLength of a wx.TextCtrl?

1,188 views
Skip to first unread message

DevPlayer

unread,
Sep 23, 2011, 12:05:02 PM9/23/11
to wxPython-users
How do I what the max length of a wx.TextCtrl. I've looked at source
for if. I was unable to find the cpp files for _control_.pyd


"why would you need that?"

There's a wx.TextCtrl.SetMaxLength(). I wanted to fire an event for
user action if that limit is hit.

There's lots of examples out there of limiting a log file's size. But
if you want the log data displayed live for long periods collecting
lots of text, I'd imagine that's be something to keep an eye on. It
seems the wx.TextCtrl's value length limit is not often accounted for;
at least in my hunting in examples and google and such, for it.

The current default behavor if you exceed that limit is to just drop
the new data instead of appending it to the wx.TextCtrl's -value-
attribute. I'm fine with the default behavior normally. But I'd rather
it behave like a deque and drop the oldest (line 0) data instead of
just not appending the latest info when using the textctrl for
collecting live text, like chat or webtraffic, logs and the like.

So my class "class dequeTextCtrl(wx.TextCtrl)" In the AppendText()
method I'd like to see if the incoming text will exceed the
wx.TextCtrls max length _before_ generatign the
wx.EVT_COMMAND_TEXT_MAXLEN or wx.EVT_TEXT_MAXLEN events. Where I'd
delete the old line(s) at the top of the control, equalling new text
length and then append the new text. Otherwise you can loose the
latest text (if you're not logging to file or some kinda of memory
hungry queue) or if you don't do some other preemtive length magic.

"Can you not just bind EVT_COMMAND_TEXT_MAXLEN ?"

I'm creating a little tester app to throw me a print of
len(widigt.GetValue()) when the EVT_COMMAND_TEXT_MAXLEN is fired. I'll
make a property of that value into my custom wxTextCtrl, but that's
hackish and is not likely the same for each platform.

Another way I can do this is to bind on "changed text" events and test
if the new text was successfully appended.

But I'm still curious of where the wx.TextCtrl is storing or
calculating that MaxLength value to. The "Set" part of
wx.TextCtrl.SetMaxLength() makes me think of some attribute or
property. but doing a dir(wx.TextCtrl) or even
dir(wx.TextCtrl.SetMaxLength) I'm not seeing where it's stuffing that
number. Perhaps it's an attribute of the method itselfwx.TextCtrl.
SetMaxLength.__somemax_value

I did find this
http://groups.google.com/group/wxpython-users/browse_thread/thread/45b253ee06b8e534/66abc69be234d975?hl=en&lnk=gst&q=SetMaxLength#66abc69be234d975
and a reply to it but that doesn't yield an initial max length value
before using SetMaxLength()

Cody

unread,
Sep 23, 2011, 12:18:52 PM9/23/11
to wxpytho...@googlegroups.com
Hi,

On Fri, Sep 23, 2011 at 11:05 AM, DevPlayer <devp...@gmail.com> wrote:
> How do I what the max length of a wx.TextCtrl. I've looked at source
> for if. I was unable to find the cpp files for _control_.pyd
>

Did you read the Docs? I think the description is quite concise:

http://docs.wxwidgets.org/2.8/wx_wxtextctrl.html#wxtextctrlsetmaxlength

Initially there is no limit, the limit is based off of whatever the
native control can handle which is noted as usually being 32kb.

As another example may want to take a look at my OutputBuffer class in
the Editra Control Library. It uses the STC for the display which
generally deals with large amounts of data and performance better than
the regular TextCtrl. I think it implements a lot of what your looking
for.

http://editra.org/eclib/outputbuffer
http://editra.org/docs/editra_api/class_editra_1_1src_1_1eclib_1_1outbuff_1_1_output_buffer.html


Cody

DevPlayer

unread,
Sep 23, 2011, 1:00:52 PM9/23/11
to wxPython-users
Hi Cody,

Yup, read the docs which say: "(typically at least 32Kb)." which is
vague at best. Not very concise. "(typically...", but not always, is
this lower sized? larger sized?. Which oses, 64bit, 32 bit? Then
there's "at least" as in "at least" but not on average 64Kb?, 1 Meg?
is it a "memory chuck" a virtual memory alloc. To many variables to be
concise.

As to the links to Editra. WOW you've been active on that. Lots more
documentation then when I first found Editra. There's a lot of good
stuff in that app. I haven't worked with it in a while though. When I
had that odd tab switching behavior several beta revisions back I got
spooked when it was messing with my source code and I unknowningly
save garbled files I had open. Thought I'd wait until it became more
stable. That was back before the refactoring/restructure I though I
read about.

btw you pop in on the irc #wxpython rowley.freenode server?

werner

unread,
Sep 23, 2011, 1:34:53 PM9/23/11
to wxpytho...@googlegroups.com
On 09/23/2011 07:00 PM, DevPlayer wrote:
Hi Cody,

Yup, read the docs which say: "(typically at least 32Kb)." which is
vague at best. Not very concise. "(typically...", but not always, is
this lower sized? larger sized?. Which oses, 64bit, 32 bit?  Then
there's "at least" as in "at least" but not on average 64Kb?, 1 Meg?
is it a "memory chuck" a virtual memory alloc. To many variables to be
concise.
A bit more info on this from:

http://xoomer.virgilio.it/infinity77/wxPython/Widgets/wx.TextCtrl.html

wx.TE_RICH Use rich text control under Win32, this allows to have more than 64KB of text in the control even under Win9x. This style is ignored under other platforms.
wx.TE_RICH2 Use rich text control version 2.0 or 3.0 under Win32, this style is ignored under other platforms
SetMaxLength(len)

This function sets the maximum number of characters the user can enter into the control. In other words, it allows to limit the text value length to len not counting the terminating NUL character.

If len is 0, the previously set max length limit, if any, is discarded and the user may enter as much text as the underlying native text control widget supports (typically at least 32Kb).

If the user tries to enter more characters into the text control when it already is filled up to the maximal length, a wx.wxEVT_COMMAND_TEXT_MAXLEN event is sent to notify the program about it (giving it the possibility to show an explanatory message, for example) and the extra input is discarded.

Note

Note that under GTK+, this function may only be used with single line text controls.

Werner

Cody

unread,
Sep 23, 2011, 2:23:33 PM9/23/11
to wxpytho...@googlegroups.com
Hi,

On Fri, Sep 23, 2011 at 12:00 PM, DevPlayer <devp...@gmail.com> wrote:
> Hi Cody,
>
> Yup, read the docs which say: "(typically at least 32Kb)." which is
> vague at best. Not very concise. "(typically...", but not always, is
> this lower sized? larger sized?. Which oses, 64bit, 32 bit?  Then
> there's "at least" as in "at least" but not on average 64Kb?, 1 Meg?
> is it a "memory chuck" a virtual memory alloc. To many variables to be
> concise.
>

I think it as about as concise as it can be. You need to consult the
documentation of the target library to find out. The implementation of
the control on different versions of the same operating system or
versions of the runtimes / target library can and will vary. It does
clearly state that no limit is imposed by default and that the limit
is only set when you call the method to set the limit at which point
you will get event callbacks when it is reached.

Edit boxes are not typically intended for working with large amounts
of text. If you are needing to be able to store and display large
amounts of data its better to not store all the data in the control
and only put in what needs to be viewed (i.e virtualize it).

> As to the links to Editra. WOW you've been active on that. Lots more
> documentation then when I first found Editra. There's a lot of good
> stuff in that app. I haven't worked with it in a while though. When I
> had that odd tab switching behavior several beta revisions back I got
> spooked when it was messing with my source code and I unknowningly
> save garbled files I had open. Thought I'd wait until it became more
> stable. That was back before the refactoring/restructure I though I
> read about.
>

? There have never been any reports of any issues with files getting
corrupted or otherwise 'messed' with. It doesn't do any thing
'autonomously'. There was one short lived release that under a non
standard workflow where there was some tab activation issues

> btw you pop in on the irc #wxpython rowley.freenode server?
>

No, life has been too busy, haven't been on irc in a long time.


Cody

DevPlayer

unread,
Sep 23, 2011, 5:00:20 PM9/23/11
to wxPython-users
Here is a quick test of the wx.TextCtrl's text limit. There were some
oddities.

http://pastebin.com/UWUnTxy1

I went up to 4 million characters. Just to test it and effects of
memory usage.
On my system it ran fine. I had 4 gig memory with lots of apps open
and no speed issues.

Robin Dunn

unread,
Sep 23, 2011, 10:20:19 PM9/23/11
to wxpytho...@googlegroups.com
On 9/23/11 10:00 AM, DevPlayer wrote:
> Hi Cody,
>
> Yup, read the docs which say: "(typically at least 32Kb)." which is
> vague at best. Not very concise. "(typically...", but not always, is
> this lower sized? larger sized?. Which oses, 64bit, 32 bit? Then
> there's "at least" as in "at least" but not on average 64Kb?, 1 Meg?
> is it a "memory chuck" a virtual memory alloc. To many variables to be
> concise.

For a plain wx.TextCtrl on Windows I think it was 32k on Win95 and
earlier, and 64K starting with win98. When using one of the wxTE_RICH
flags then on Windows it will be either 2 billion or 4 billion, I've
forgotten which it is. For the other platforms I'm not sure if there
are hard limits or not, but you can probably depend on it being "a large
amount."


--
Robin Dunn
Software Craftsman
http://wxPython.org

Dev Player

unread,
Sep 24, 2011, 10:15:21 PM9/24/11
to wxpytho...@googlegroups.com
In that little test app I wrote there was two weird hiccups. When the textctrl hit 30000 chars and when it hit 63000 chars. The 63000 chars mark, I think, shows something to be very aware of. When I append 1000 more chars to the control onto the already 62000 chars in the textctrl buffer the control did not append the whole 1000 characters, but only a portion of it, but only for THAT single AppendText() call. The following AppendText() call and all the subsequent AppendText() calls then again appended the enire 1000 chars. It went from 62000 to 62768. Oddly you'd think that'd be at 32768 (2^15) or at 65536 (2^16). It is as if the widget/control added a 2nd "big" buffer after the maxlength event.
 
The script shows I was in WinXP SP3 32Bit and perhaps the native widget on that OS has this behavior.
 
But this does tell me that if you do not explicidly test if all the text is in fact appended to the widget (in a logging like usage) that that widget can loose characters in that "internal" buffer without warning.
 

Vlastimil Brom

unread,
Sep 25, 2011, 3:32:19 AM9/25/11
to wxpytho...@googlegroups.com
2011/9/24 Robin Dunn <ro...@alldunn.com>:
Sorry, if I misunderstood something, does the MaxLength mean, that it
isn't possible to display longer text in plain TextCtrl than, say, 64
kB (as I would primarily interpret it)? Or does the limit get
automatically higher somehow, if none is set explicitly?

I normally use richtext variant with texts up to several megabytes and
in several cases switching to plain TextCtrl seemed to speed it up
without discarding anything (unless I missed something).

Thanks and regards,
Vlastimil Brom

Dev Player

unread,
Sep 25, 2011, 11:11:57 AM9/25/11
to wxpytho...@googlegroups.com
Robin Dunn:
"> For a plain wx.TextCtrl on Windows I think it was 32k on Win95 and earlier,
> and 64K starting with win98. "
 
> "that it isn't possible to display longer text in plain TextCtrl than, say, 64 kB..."?
That's about Win95 and Win98. I think Python 2.7 doesn't even support those OSes anymore.
 
> Or does the limit get automatically higher somehow, if none is set explicitly?
 
I was guessing that the WinXP Pro 32bit native OS TextCtrl() malloc'd more buffer. But I am only speculating. I'm a novice. Noone of experience supported my theory. I understood them to have said: The default behavior is that wx.TextCtrl() is unlimited when not explicidly set..
 
There is no MaxLength attribute but there is an added method/property SetMaxLength() that you -can- use to limit it.
 
Using the SetMaxLength(1000) for example will generate a EVT_TEXT_MAXLENGTH event on the appending of the 1001th or more text.
 
The little program I ran on WinXP Pro SP3 showed loss of data when appending 1000 chars to the wx.TextCtrl.Value using AppendText() only at the 62K mark; an odd place for that. But not appending before or after that.
 
In my testing using that little script I wrote at http://pastebin.com/UWUnTxy1 I ran it up to 4++ million chars length without any notice in computer performance. Again that's WinXP 32 bit. And it was the wx.TextCtrl  and NOT the STC or RichText widget.
 
Cody said, using the wx.TextCtrl() widget to display streams of text is not a good practice. It makes sense to use a buffered widget to show only a portion of that text stream. And he wrote a widget that does just that in his app/package. Links above.
 
 

Robin Dunn

unread,
Sep 26, 2011, 1:17:25 PM9/26/11
to wxpytho...@googlegroups.com
On 9/25/11 12:32 AM, Vlastimil Brom wrote:
> 2011/9/24 Robin Dunn<ro...@alldunn.com>:
>> On 9/23/11 10:00 AM, DevPlayer wrote:
>>>
>>> Hi Cody,
>>>
>>> Yup, read the docs which say: "(typically at least 32Kb)." which is
>>> vague at best. Not very concise. "(typically...", but not always, is
>>> this lower sized? larger sized?. Which oses, 64bit, 32 bit? Then
>>> there's "at least" as in "at least" but not on average 64Kb?, 1 Meg?
>>> is it a "memory chuck" a virtual memory alloc. To many variables to be
>>> concise.
>>
>> For a plain wx.TextCtrl on Windows I think it was 32k on Win95 and earlier,
>> and 64K starting with win98. When using one of the wxTE_RICH flags then on
>> Windows it will be either 2 billion or 4 billion, I've forgotten which it
>> is. For the other platforms I'm not sure if there are hard limits or not,
>> but you can probably depend on it being "a large amount."
>>

> Sorry, if I misunderstood something, does the MaxLength mean, that it


> isn't possible to display longer text in plain TextCtrl than, say, 64
> kB (as I would primarily interpret it)? Or does the limit get
> automatically higher somehow, if none is set explicitly?

The widgets may have a built-in maximum that is all that can be
supported based on the design and implementation of the widget itself,
(such as how they allocate memory, etc.) SetMaxLength can be used to
set a more practical limit, so you don't end up with things like a
person's last name being a string that is 64K long because your cat fell
asleep on your keyboard. ;-)

Dev Player

unread,
Sep 27, 2011, 2:17:55 AM9/27/11
to wxpytho...@googlegroups.com
What of those weird issues my little script found?
 

Tobias Weber

unread,
Sep 27, 2011, 7:47:01 AM9/27/11
to wxpytho...@googlegroups.com

Attached you see screenshots of the widget inspection tool climbing down
my notebook panel w/ sizers on it .
The problem:
I cannot figure out why the 2nd StaticBoxsizer's BoxSizer containing a
wx.ListCtrl just like all the others is not expanding properly, i.e. is
overlapping with the next static box sizer. (see WidgetInsepctor's
highlight in screen-capture-8)
The 4 StaticBoxSizers are exact copies and the 2nd one is the only one
behaving like this ....

You can see from the ObjectInfo that they are not formatted differently ....
Any suggestions where I am missing sthg are VERY welcome :-)

Cheers,

S

screen-capture-8.png
screen-capture-9.png
screen-capture-7.png
screen-capture-6.png

werner

unread,
Sep 27, 2011, 8:08:43 AM9/27/11
to wxpytho...@googlegroups.com
Proportion settings?

I think a small runnable sample app would be better and these images.

http://wiki.wxpython.org/MakingSampleApps

While I often forget to this too, when I do it I often found my error
while doing it and should I not be able to find my error it will make it
easier for others to help.

Werner

Rufus

unread,
Oct 11, 2012, 2:01:12 PM10/11/12
to wxpytho...@googlegroups.com

I have seen the end lines of an appended text dropped as well. You have some very interesting numbers there.  As you say, it doesn't
always happen.  You've inspired me to dig more deeply into it in my situation as well.  The problem is, it's a running log, and I don't always
see the problem, because it is in the middle of the data somewhere.

(Of course, the lines sent to the log file are fine...)

I wonder if you pre-fill it with 65537 characters, then erase the contained text, it sets it to "big" mode, assuming there
may be "transitions" at approximately the levels you're seeing.

Rufus

Rufus

unread,
Oct 11, 2012, 3:47:00 PM10/11/12
to wxpytho...@googlegroups.com

I played with your (nicely done) test program using different fill sizes.  From my experimentation,
I find if I do the following when I first create a textctrl, everything works fine:

self.textctrl.AppendText("x"*65537)    # of course, the character doesn't matter
self.textctrl.Clear()

Then use as normally, it doesn't have those "hitches".

BTW, I  in your test program I added:

before = len(self.tc.GetValue())

before the AppendText call, and

after = len(self.tc.GetValue())

to see how many characters were dropped at each iteration and report if any.

Rufus
Reply all
Reply to author
Forward
0 new messages