Scalable icons?

I want to add icons to buttons etc. in my applications.
This can easily be done using bitmaps (e.g., PNG images).

However these don’t scale. This is a problem when deploying an application to users who have widely varying screen sizes and DPIs.

I’ve tried using a custom ArtProvider 256x256 PNGs and dynamically scaling to 16, 20, 24, etc., pixels in proportion to the DPI (although wxPython seems to report DPI incorrectly on Linux), but the results are poor.

Ideally I’d like to be able to use SVG images and then dynamically draw them as PNGs of the appropriate size (and cache them once drawn). But I can’t see any SVG rendering class in wxPython, only SVGFileDC which outputs SVG.

Surely other wxPython users have encountered (and solved) this problem?

(By comparison, Qt allows the use of SVG images directly for icons and scales them appropriately for you.)

There still isn’t SVG support in wxWidgets, however it looks like better HiDPI cross-platform support may be coming in 4.1.x. I haven’t investigated fully yet but if I understand correctly it involves selecting differently sized images based on the scaling factor of the display.

There is already some support for this on OSX, although if I remember correctly it requires the images to be in the Resources folder of the application bundle, or something like that, so it’s not very easy to use from a non-bundled python application. The discussions about this on wx-dev have been about making things work better and consistently on all the main platforms.

I’ve been playing around with this for the past few weeks.

All the commonly used SVG features are supported, and for those that aren’t, (like text) loading the file into an editor and changing things to simple paths will probably take care of it. The rendering to a wx.GraphicsContext is not quite perfect on all platforms, but it’s very usable and probably close enough to perfect everywhere except the GDI+ backend. The rasterizing to a wx.Bitmap does work very well everywhere.

Here are some examples:

Snap001

Snap002

Snap003

Snap004

Snap005

That looks wonderful. In terms of API will we see widget.SvgImage alongside widget.Bitmap or what?

It’s possible it could eventually grow into something like that, but for now the focus is just adding the ability to get a bitmap from an SVG, and it’s expected it will be used with the existing widget APIs.