AutoWrapStaticText and resizing

Hi,
I’ll post the code below, it’s runnable. It’s python 2.x and wxpython 3.0-gtk.
(I would be trying Python 3 if Phoenix were in the Linux repos.)

The ghost of AutoWrapStaticText rises again. :slight_smile:

The thing:
I want a StaticText label which can:

  1. Have its content changed any time: SetLabel(“some new whatever”)
  2. It should then wrap (or not) and
  3. resize its surrounds (somehow).

The test code has a BoxSizer like so:

label

···


text control

button

The button sets a long/short string on the label. I am hoping to see the sizer change as the the label changes.

I guess it’s something to do with Layout/Fit, but I can’t find the magic. At the moment it only redraws when you manually resize the frame.

If I can’t get past this hurdle, I will use the ellipses thing to indicate to the user that the window must be made wider.

Any clues?
/d

CODE:

When run, drag the frame a bit first.

import wx

class AutoWrapStaticText(wx.PyControl):
def init(self, parent, id=-1, label="",
pos=wx.DefaultPosition, size=wx.DefaultSize,
style=0, name=“wrapStatText”):
wx.PyControl.init(self, parent, id, pos, size, wx.NO_BORDER,
wx.DefaultValidator, name)

    self.p = parent

    [self.st](http://self.st) = wx.StaticText(self, -1, label, style=style)

    self._label = label
    self._rows = 0

    # Measure the string once, to get a lineheight.
    # My thinking is it will be faster to math
    # with that than to render and measure
    # the entire string each time.
    f = self.st.GetFont()
    dc = wx.ScreenDC()
    dc.SetFont(f)
    w,h,lh = dc.GetMultiLineTextExtent(label,f)
    self._lineheight = lh
 
    self._Rewrap()
    self.Bind(wx.EVT_SIZE, self.OnSize)

def _lh(self):
    # return a tup of parent width, text height
    # lineheight * rows should = ~ height
    h = self._rows * self._lineheight
    sz = ( self.p.GetSize()[0], h )
    print sz
    return sz

def SetLabel(self, label):
    # This is the NB one. I need to set different
    # strings - and they can be long or short.
    # I.e. they can wrap or not.
    # The space the string is in should resize,
    # but I can't get it right.
    self._label = label
    self._Rewrap()

def GetLabel(self):
    return self._label

def SetFont(self, font):
    self.st.SetFont(font)
    self._Rewrap()

def GetFont(self):
    return self.st.GetFont()

def OnSize(self, evt):
    self.st.SetSize(self.GetSize())
    self._Rewrap()

def _Rewrap(self):
    self.st.Freeze()
    self.st.SetLabel(self._label)
    self.st.Wrap(self.GetSize().width)
    # here I count the rows:
    self._rows = self.st.GetLabel().count("\n") + 1
    self.st.Thaw()

def DoGetBestSize(self):
    # Trying to use the lineheight etc.
    return self._lh()

longstring = “A certain king had a beautiful garden, and in the garden stood a tree which bore golden apples. These apples were always counted, and about the time when they began.”
shortstring = “I am set to a shortstring.”
txt = “This area should move up/down as the string above changes and/or wraps.”

class TestFrame(wx.Frame):
def init(self, *args, **kw):
wx.Frame.init(self, *args, **kw)

    p = wx.Panel(self)

    bs = wx.BoxSizer(wx.VERTICAL)
   
    # First slot - the wrap text
    self.awst = AutoWrapStaticText(p, label=longstring)
    bs.Add(self.awst, 0, wx.EXPAND)
   
    # Second slot - the text ctrl
    printer = wx.TextCtrl(p, -1, txt,
            style = wx.TE_READONLY | wx.TE_MULTILINE)
    bs.Add(printer, 1, wx.EXPAND)

    # Last slot the button
    b = wx.Button( p, label = "press me" )
    self.tog = True
    self.Bind(wx.EVT_BUTTON, self._press, b)
    bs.Add(b, 0)

    p.SetSizer(bs)
    p.Layout() # guessing.

def _press(self, evt):
    self.awst.SetLabel(shortstring if self.tog else longstring)
    self.tog = not self.tog

app = wx.App(redirect=False)
frm = TestFrame(None, title=“test wrapping static text”)
frm.Show()
#import wx.lib.inspection
#wx.lib.inspection.InspectionTool().Show()
app.MainLoop()

Hi,

Hi,
I’ll post the code below, it’s runnable. It’s python 2.x and wxpython 3.0-gtk.
(I would be trying Python 3 if Phoenix were in the Linux repos.)

The ghost of AutoWrapStaticText rises again. :slight_smile:

The thing:
I want a StaticText label which can:

  1. Have its content changed any time: SetLabel(“some new whatever”)
  2. It should then wrap (or not) and
  3. resize its surrounds (somehow).

The test code has a BoxSizer like so:

label

text control

button

The button sets a long/short string on the label. I am hoping to see the sizer change as the the label changes.

I guess it’s something to do with Layout/Fit, but I can’t find the magic. At the moment it only redraws when you manually resize the frame.

If I can’t get past this hurdle, I will use the ellipses thing to indicate to the user that the window must be made wider.

Any clues?
/d

CODE:

When run, drag the frame a bit first.

import wx

class AutoWrapStaticText(wx.PyControl):
def init(self, parent, id=-1, label=“”,
pos=wx.DefaultPosition, size=wx.DefaultSize,
style=0, name=“wrapStatText”):
wx.PyControl.init(self, parent, id, pos, size, wx.NO_BORDER,
wx.DefaultValidator, name)

    self.p = parent

    [self.st](http://self.st) = wx.StaticText(self, -1, label, style=style)

    self._label = label
    self._rows = 0

    # Measure the string once, to get a lineheight.
    # My thinking is it will be faster to math
    # with that than to render and measure
    # the entire string each time.
    f = self.st.GetFont()
    dc = wx.ScreenDC()
    dc.SetFont(f)
    w,h,lh = dc.GetMultiLineTextExtent(label,f)
    self._lineheight = lh
 
    self._Rewrap()
    self.Bind(wx.EVT_SIZE, self.OnSize)

def _lh(self):
    # return a tup of parent width, text height
    # lineheight * rows should = ~ height
    h = self._rows * self._lineheight
    sz = ( self.p.GetSize()[0], h )
    print sz
    return sz

def SetLabel(self, label):
    # This is the NB one. I need to set different
    # strings - and they can be long or short.
    # I.e. they can wrap or not.
    # The space the string is in should resize,
    # but I can't get it right.
    self._label = label
    self._Rewrap()

def GetLabel(self):
    return self._label

def SetFont(self, font):
    self.st.SetFont(font)
    self._Rewrap()

def GetFont(self):
    return self.st.GetFont()

def OnSize(self, evt):
    self.st.SetSize(self.GetSize())
    self._Rewrap()

def _Rewrap(self):
    self.st.Freeze()
    self.st.SetLabel(self._label)
    self.st.Wrap(self.GetSize().width)
    # here I count the rows:
    self._rows = self.st.GetLabel().count("\n") + 1
    self.st.Thaw()

def DoGetBestSize(self):
    # Trying to use the lineheight etc.
    return self._lh()

longstring = “A certain king had a beautiful garden, and in the garden stood a tree which bore golden apples. These apples were always counted, and about the time when they began.”
shortstring = “I am set to a shortstring.”
txt = “This area should move up/down as the string above changes and/or wraps.”

class TestFrame(wx.Frame):
def init(self, *args, **kw):
wx.Frame.init(self, *args, **kw)

    p = wx.Panel(self)

    bs = wx.BoxSizer(wx.VERTICAL)
   
    # First slot - the wrap text
    self.awst = AutoWrapStaticText(p, label=longstring)
    bs.Add(self.awst, 0, wx.EXPAND)
   
    # Second slot - the text ctrl
    printer = wx.TextCtrl(p, -1, txt,
            style = wx.TE_READONLY | wx.TE_MULTILINE)
    bs.Add(printer, 1, wx.EXPAND)

    # Last slot the button
    b = wx.Button( p, label = "press me" )
    self.tog = True
    self.Bind(wx.EVT_BUTTON, self._press, b)
    bs.Add(b, 0)

    p.SetSizer(bs)
    p.Layout() # guessing.

def _press(self, evt):
    self.awst.SetLabel(shortstring if self.tog else longstring)
    self.tog = not self.tog

app = wx.App(redirect=False)
frm = TestFrame(None, title=“test wrapping static text”)
frm.Show()
#import wx.lib.inspection
#wx.lib.inspection.InspectionTool().Show()
app.MainLoop()

For some ideas:

https://wxpython.org/Phoenix/docs/html/wx.lib.agw.infobar.AutoWrapStaticText.html

Andrea.

···

On Tue, 28 Nov 2017 at 08.24, Donn Ingle donn.ingle@gmail.com wrote:

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-users+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

I will reply to myself. I got it going. Trial and error. Working demo attached.

(Apologies for pasting initially.)

/d

wraphack.py (5.18 KB)