I’m just getting started with wxPython, and I’m working with the “Hello, World Part 2” example at https://wxpython.org/pages/overview/#hello-world-part-2 . The wx.StaticText widget seems to be getting created correctly, but when the font is changed, the widget is not resized. It appears that the overview’s author intended for the widget to be resized when the font size is changed, and the screenshots back this up.
I’m not really even sure what the right way to resize it would be. I ended up calling st.SetSize(st.GetTextExtent(st.Label)), which seems like an odd way to do that.
I’m using the python3-wxgtk4.0 package on Ubuntu 19.04. A screenshot of the broken version (without the SetSize call) is attached, as well as source code for my fixed version with the “SetSize” call.
Am I doing something wrong? Is this just a behavior that changed in Phoenix, and the example is meant to be pre-Phoenix? This feels like I’m doing things the wrong way, but I’m new here and don’t know what the right way is.
A related doc note: in the wxPython wx.Window docs at https://wxpython.org/Phoenix/docs/html/wx.Window.html , the docs don’t describe GetTextExtent, but they do refer to it in the SetFont description. The GetFullTextExtent method description doesn’t describe how it differs from GetTextExtent. (I suspect the difference is that GetTextExtent only returns the x and y values from C++'s wxWindow::GetTextExtent, while Python’s GetFullTextExtent also returns the descent and externalLeading parameters. But this did take some digging to figure out.)
The control should automatically resize itself when you call SetLabel. Try setting the label after you set the font.
···
On May 17, 2019, at 7:38 PM, Joel Holveck <piquan@gmail.com> wrote:
I'm not really even sure what the right way to resize it would be. I ended up calling st.SetSize(st.GetTextExtent(st.Label)), which seems like an odd way to do that.
—
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.
I'm not really even sure what the right way to resize it would be. I ended up calling st.SetSize(st.GetTextExtent(st.Label)), which seems like an odd way to do that.
The control should automatically resize itself when you call SetLabel. Try setting the label after you set the font.
Thanks for the suggestion. I did try that. I also tried calling Fit, and SetSize(-1, -1). None of these seemed to have a useful effect.
wx.StaticText autosizing does not work when changing font under Phoenix
(which is usually built with GTK3, so the latter may have something to
do with it), it stays at the size of the initial label font until
manually updating the size. The only reliable work-around I found was to
use GetTextExtent() to figure out the correct size, like you did. I've
reported the issue[1]. Possibly related: [2] (I also don't think the
"fix" for [2] is a good one because it is non-obvious and
platform-specific. StaticText should automatically do the right thing
when a label/font is changed).
I'm not really even sure what the right way to resize it would be. I ended up calling st.SetSize(st.GetTextExtent(st.Label)), which seems like an odd way to do that.
The control should automatically resize itself when you call SetLabel. Try setting the label after you set the font.
Thanks for the suggestion. I did try that. I also tried calling Fit, and SetSize(-1, -1). None of these seemed to have a useful effect.
If the best size has already been calculated then it could be returning a cached value. I find it’s best to call InvalidateBestSize so that cached value will be wiped out. Then the next time there’s a sizer layout a new best size will be calculated (and cached.) In this example, since there is no sizer used, then the new size can be calculated and the widget resized, like this:
st.InvalidateBestSize()
st.SetSize(st.BestSize)
···
On Saturday, May 18, 2019 at 9:56:27 PM UTC-7, Tim Roberts wrote:
On May 17, 2019, at 7:38 PM, Joel Holveck piquan@gmail.com wrote:
I’m not really even sure what the right way to resize it would be. I ended up calling st.SetSize(st.GetTextExtent(st.Label)), which seems like an odd way to do that.
The control should automatically resize itself when you call SetLabel.
Hi all - is this really the outcome of the question? I am also having this problem in wxStaticText on Mac OSX and find it ridiculous that people should have to go through such an ordeal to update a text label.
Please create a small sample that shows the problem you are having on OSX, as the problems discussed here were mostly due to problems in the wx GTK3 port.
Same problem. Testing is Ubuntu 16.04, wxPython-4.0.7.post2
SetSize(st.GetTextExtent(st.GetLabel())) remedies the problem however not in Choicebook panel inside a sizer. Works fine in Simplebook and Notebook panels. Very strange.
import wx
class PageNoSizer(wx.Panel):
def __init__(self, parent):
super().__init__(parent)
self.SetBackgroundColour(wx.BLACK)
st = wx.StaticText(self, label="HELLO WORLD", pos=(60, 55), style=wx.TE_CENTER | wx.EXPAND | wx.ALL)
st.SetForegroundColour(wx.Colour(0x00FF44))
stylish_font = wx.Font(wx.FontInfo(20).FaceName("liberation").Bold())
st.SetFont(stylish_font)
st.SetSize(st.GetTextExtent(st.GetLabel()))
btn = wx.Button(self, label="Next Page")
self.Bind(wx.EVT_BUTTON, parent.OnNextPage, btn)
class PageWithSizer(wx.Panel):
def __init__(self, parent):
super().__init__(parent)
self.SetBackgroundColour(wx.BLACK)
vbox = wx.BoxSizer(wx.VERTICAL)
st = wx.StaticText(self, label="HELLO WORLD", style=wx.TE_CENTER | wx.EXPAND | wx.ALL)
st.SetForegroundColour(wx.Colour(0x00FF44))
stylish_font = wx.Font(wx.FontInfo(20).FaceName("liberation").Bold())
st.SetFont(stylish_font)
st.SetSize(st.GetTextExtent(st.GetLabel()))
vbox.Add(st)
btn = wx.Button(self, label="Next Page")
vbox.Add(btn, 0, wx.ALIGN_RIGHT)
self.Bind(wx.EVT_BUTTON, parent.OnNextPage, btn)
self.SetSizer(vbox)
# class TestingBook(wx.Simplebook):
class TestingBook(wx.Choicebook):
# class TestingBook(wx.Notebook):
def __init__(self, parent):
super().__init__(parent)
noSizer = PageNoSizer(self)
withSizer = PageWithSizer(self)
self.AddPage(noSizer, "PageNoSizer")
self.AddPage(withSizer, "PageWithSizer")
def OnNextPage(self, evt):
current = self.GetSelection()
current += 1
if current >= self.GetPageCount():
current = 0
self.ChangeSelection(current)
class MainFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, size=wx.Size(800, 600))
TestingBook(self)
self.Show()
if __name__ == '__main__':
app = wx.App(redirect=False)
frame = MainFrame()
app.MainLoop()
On the other hand, creating a StaticText and then immediately changing the font is quite unusual. Certainly it’s too unusual for a Hello World example.
I would rather suggest to remove the font change and put a second element into the the sizer. E.g. a button with an event handler. Or maybe a button and a text control, where the button event handler reads the text, modifies it, puts it back into the text control and reports the result in a MessageDialog.
This way the reader has the basic building blocks for a simple application.
The font example is something one might need in the second year of using wx…