AutoWrapStaticText and resizing

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

AutoWrapStaticText and resizing

Donn Ingle
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. :)

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 = 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()

--
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 [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: AutoWrapStaticText and resizing

Andrea Gavana
Hi,


On Tue, 28 Nov 2017 at 08.24, Donn Ingle <[hidden email]> wrote:
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. :)

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 = 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()




Andrea.


--
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 [hidden email].
For more options, visit https://groups.google.com/d/optout.

--
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 [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: AutoWrapStaticText and resizing

Donn Ingle
In reply to this post by Donn Ingle
I will reply to myself. I got it going. Trial and error. Working demo attached.
(Apologies for pasting initially.)

/d

--
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 [hidden email].
For more options, visit https://groups.google.com/d/optout.

wraphack.py (7K) Download Attachment