The right way to find the size of text in wxPython

2019-06-28 03:25发布

问题:

I have an application I am developing in wxPython. Part of the application creates a large number of TextCtrls in a grid in order to enter four-letter codes for each day of the week for an arbitrarily large list of people.

I've managed to make it work, but I'm having to do something kludgy. Specifically, I haven't found a good way to figure out how big (in pixels) a bit of text is, so I have to guess at sizing the TextCtrls in order to just fit the biggest (4 letter) code. My concern is that if the size of the text was to change, or the application was ported to something other than MSW, that my layout might break.

The solution I found was to create a StaticText object, fill it with 4 large letters, get its size, and then .Destroy() it. This works, but it really seems like a klunky solution. Does anyone have a more direct method for figuring out just how big an arbitrary text string will be in a TextCtrl? I've looked in the docs and haven't been able to find anything, and I haven't seen any examples that do precisely what I'm trying to do.

A little code sample (showing the test method) follows:

    # This creates and then immediately destroys a static text control
    # in order to learn how big four characters are in the current font.
    testst = wx.StaticText(self, id = wx.ID_ANY, label = "XXXX")
    self.fourlettertextsize = testst.GetClientSize() + (4,4)
    testst.Destroy()

(The + (4,4) part is to add a little more space in the control to accommodate the cursor and a little border in the client area of the TextCtrl; this is another thing I'd rather not be doing directly.)

回答1:

Create a wx.Font instance with the face, size, etc.; create a wx.DC; then call dc.GetTextExtent("a text string") on that to get the width and height needed to display that string. Set your row height and column width in the grid accordingly.

Something like:

font = wx.Font(...)
dc = wx.DC()
dc.SetFont(font)
w,h = dc.GetTextExtent("test string")


回答2:

Not to take away from Paul McNett's answer, but for those not-so-familiar with wxPython here's a simple complete example:

import wx

app = wx.PySimpleApp()

font = wx.Font(pointSize = 10, family = wx.DEFAULT,
               style = wx.NORMAL, weight = wx.NORMAL,
               faceName = 'Consolas')

dc = wx.ScreenDC()
dc.SetFont(font)

text = 'text to test'

# (width, height) in pixels
print '%r: %s' % (text, dc.GetTextExtent(text))

Outputs: 'text to test': (84, 15)