wxPython Font by Pixel Height

I’ve been looking to find a way to resize a font when the window’s size changes. Here is code that will create a font that is close as possible to a given height in pixels without specifying anything about the font width. Osku Salerma posted some code in GitHub that did the trick.

I changed it a bit to make it self-contained. Here’s my modified version of his code to create a wxPython font given a height in pixels:

    def createFontFromHeightInPixels(self, heightInPixels, family, style, weight):
        # return a font that's as close to 'heightInPixels' as possible without being larger
        # modified from code at http://github.com/oskusalerma/blyte/blob/master/util.py  
        fontSizeToTest = 6
        bestFontSoFar = wx.Font(fontSizeToTest, family, style, weight, encoding = wx.FONTENCODING_ISO8859_1)
        closestDiffInPixelsSoFar = 1000
        testDc = wx.MemoryDC()
        testDc.SelectObject(wx.EmptyBitmap(512, 32)) 
        while 1:
            testedFont = wx.Font(fontSizeToTest, family, style, weight, encoding = wx.FONTENCODING_ISO8859_1)
            heightOfTestedFont = testDc.GetTextExtent("_\xC5")[1]
            diff = heightInPixels-heightOfTestedFont
            if diff >= 0:
                if diff < closestDiffInPixelsSoFar:
                    closestDiffInPixelsSoFar = diff
                    bestFontSoFar = testedFont
            fontSizeToTest += 2
        return bestFontSoFar 

It would be used like this assuming the above function is in the window class or one of its superclasses:

def __init__(self, *args, **kwds):
    self.Bind(wx.EVT_SIZE, self.OnSize)     

def OnSize(self, event):
        size = event.GetSize()
        currentFont = self.GetFont()
        newFont = self.createFontFromHeightInPixels( (size.height*0.8), 
            currentFont.GetFamily(), currentFont.GetStyle(), currentFont.GetWeight())

This entry was posted in Python, wxPython. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *