How to increase TextCtrl size to fit its message?

1,604 views
Skip to first unread message

Yuming Cao

unread,
Jun 3, 2013, 8:38:00 PM6/3/13
to wxpytho...@googlegroups.com
I'm creating a readonly TextCtrl in order to enabling copy its message. I want it to show the whole information at the very beginning but it doesn't adjust its size. A hard-coded way may not be a good approach since message string length may vary. Attached is the code snippet that doesn't work so well. Thanks!

----------------------------------------------

#!/usr/bin/env python

"""SizerTest - 'cause Sizer's wx.EXPAND does not GROW """

import wx

class SizerTest(wx.Frame):
    
    def __init__(self):
    
        wx.Frame.__init__(self, parent = None, id = wx.ID_ANY)
        frame_box = wx.BoxSizer()

        panel = wx.Panel(self, -1, style=wx.BORDER_SUNKEN)
        self.text = wx.TextCtrl(panel, id=-1,
                value='heiheiheihhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh', style=wx.TE_READONLY|wx.NO_BORDER)
        panel_box = wx.BoxSizer()
        panel_box.Add(self.text, 1, wx.EXPAND | wx.ALL | wx.ALIGN_TOP)
        panel.SetSizer(panel_box)
        frame_box.Add(panel, 1, wx.EXPAND) 
        self.SetSizer(frame_box)
if __name__ == '__main__':
    app = wx.App()
    frame = SizerTest()
    frame.Show(True)
    import wx.lib.inspection
    wx.lib.inspection.InspectionTool().Show()
    app.MainLoop()

C M

unread,
Jun 4, 2013, 12:41:24 AM6/4/13
to wxpytho...@googlegroups.com
On Mon, Jun 3, 2013 at 8:38 PM, Yuming Cao <yumin...@cyaninc.com> wrote:
> I'm creating a readonly TextCtrl in order to enabling copy its message. I
> want it to show the whole information at the very beginning but it doesn't
> adjust its size. A hard-coded way may not be a good approach since message
> string length may vary. Attached is the code snippet that doesn't work so
> well. Thanks!

Does adding the wx.TE_MULTILINE flag to the TextCtrl get you what you want?

Yuming Cao

unread,
Jun 4, 2013, 1:41:55 PM6/4/13
to wxpytho...@googlegroups.com
Not really, since I'm trying display a selectable message dialog, most of the time, the text message is short, the textctrl's behavior is kind of weird. If I set its size too large, the text alignment is strange, if too small, there's scroll bar on the side, which is not ideal for a message box.

C M

unread,
Jun 4, 2013, 1:55:33 PM6/4/13
to wxpytho...@googlegroups.com
On Tue, Jun 4, 2013 at 1:41 PM, Yuming Cao <yumin...@cyaninc.com> wrote:
> Not really, since I'm trying display a selectable message dialog, most of
> the time, the text message is short, the textctrl's behavior is kind of
> weird. If I set its size too large, the text alignment is strange, if too
> small, there's scroll bar on the side, which is not ideal for a message box.

What do you mean by a "selectable" message dialog? What is the
purpose of the thing you are trying to create?

I don't think the TextCtrl's behavior is weird or the alignment is
strange; it strikes me as perfectly reasonable for a text control.
What is probably the issue is that you are using the wrong widget for
your purpose, unless you have a very long (paragraphs long) message to
display to the user, in which case then a TextCtrl might be
appropriate (for something almost like a README.txt file). For
shorter messages to the user, why not use StaticText (or, better yet,
see next point).

Is there a reason why the standard wx.MessageDialog, the
GenericMessageDialog or the ScrolledMessageDialog aren't sufficient
for your purposes?

Also, are you aware of the textwrap module, which can help to make
message widths look nicer by constraining them to something
reasonable, like 70 characters wide:

import sys
import textwrap
message = 'This message is pretty long if it is not wrapped to a ' \
'nicer length, so it is a good idea to
consider using textwrap ' \
'to shorten the length of it so that it looks
a bit better in the ' \
'messageDialog that you are using to display
this message.'

if sys.platform == "win32":
lines = textwrap.wrap(message,70)
message = "\n".join(lines)

dlg = wx.MessageDialog(self, message, 'wrapped msg'', wx.OK | wx.ICON_WARNING)

etc...

Yuming Cao

unread,
Jun 4, 2013, 3:39:36 PM6/4/13
to wxpytho...@googlegroups.com
Previously I'm using createTextSizer to show message, in which the text msg is not able to be copied. Actually, statictext is also not working. So i'm doing wx.TR_READONLY to make textctrl 'looks like' statictext but also make selectable. 

Thanks for the MessageDialog suggestion, but here I'm doing something generic and has my own dialog already. Actually the Messagebox is working perfect for me, so it would be perfect if somebody can help me figure how the text msg is handled in wx.MessageBox. 

C M

unread,
Jun 4, 2013, 3:56:03 PM6/4/13
to wxpytho...@googlegroups.com
On Tue, Jun 4, 2013 at 3:39 PM, Yuming Cao <yumin...@cyaninc.com> wrote:
> Previously I'm using createTextSizer to show message, in which the text msg
> is not able to be copied. Actually, statictext is also not working. So i'm
> doing wx.TR_READONLY to make textctrl 'looks like' statictext but also make
> selectable.
>
> Thanks for the MessageDialog suggestion, but here I'm doing something
> generic and has my own dialog already. Actually the Messagebox is working
> perfect for me, so it would be perfect if somebody can help me figure how
> the text msg is handled in wx.MessageBox.

What do you mean "how the text msg is handled"? You have to be really
explicit and spell out everything when you ask questions on a
forum--we're not mind readers. :D

Yuming Cao

unread,
Jun 4, 2013, 4:37:44 PM6/4/13
to wxpytho...@googlegroups.com
The message inside MessageBox dialog can be selected, the dialog can adjust its size according to text string's length,  I'm wondering what utility it is using to show the message and how sizers are initialized, is there a place to look into the source code?  

Rufus Smith

unread,
Jun 4, 2013, 5:34:38 PM6/4/13
to wxpytho...@googlegroups.com
--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to wxpython-user...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

The key is the GetMultiLineTextExtent function, but you need a device context and font for it.
This worked for me:
(you may need to add to the dimensions a little, depending on borders and stuff....)

class TextDisplayFrame(wx.Frame):
    """TextDisplayFrame  is a simple text display frame class
       which should only be used if the text will fit on the
       screen in a window. 
       Anything needing scrollbars should use something else.
    """
   
    def __init__(self,*args,**kwds):
        if "title" in kwds:
            self.title = kwds["title"]
        else:
            self.title = "Text Frame"
            kwds["title"]=self.title

        if "text" in kwds:
            self.text = kwds["text"]
            del kwds["text"]
        else:
            self.text = "No Text Given"

        kwds["style"] = wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self,*args,**kwds)

        panel = wx.Panel(self,wx.ID_ANY)
        text = wx.StaticText(panel,wx.ID_ANY,self.text)
        font = wx.Font(10, wx.MODERN, wx.NORMAL, wx.NORMAL, False, u'Console')
        text.SetFont(font)
        dc = wx.WindowDC(panel)
        (width,height,other) = dc.GetMultiLineTextExtent(self.text,text.GetFont())
        panel.SetSize((width,height))
        self.Fit()
        self.Show()

Yuming Cao

unread,
Jun 4, 2013, 6:24:25 PM6/4/13
to wxpytho...@googlegroups.com
Thanks Rufus, GetMultiLineText works, but only when I'm not using boxsizer, since i have pic to add to the same dialog, i'm not sure how to SetSize while I'm using sizer.  
Reply all
Reply to author
Forward
0 new messages