Toolbar Button size is not driven by the image on Windows?

Hello all. The Toolbar documentation contains this statement:

the tools will always be made big enough to fit the size of the bitmaps used in them.

However in Windows that does not seem to be true. I have this test code:

import  wx

class TestToolBar(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent, -1, 'Test ToolBar', size=(600, 400))

        client = wx.Panel(self)

        tb = self.CreateToolBar( )

        print("Default toolbar tool size: %s\n" % tb.GetToolBitmapSize())

        new_bmp =  wx.ArtProvider.GetBitmap(wx.ART_NEW, wx.ART_TOOLBAR, (24,24))
        open_bmp = wx.ArtProvider.GetBitmap(wx.ART_FILE_OPEN, wx.ART_TOOLBAR, (110,24))

        tb.AddTool(10, "New", new_bmp, wx.NullBitmap, wx.ITEM_NORMAL, "New", "Long help for 'New'", None)
        self.Bind(wx.EVT_TOOL, self.OnToolClick, id=10)

        tb.AddTool(20, "Open", open_bmp, wx.NullBitmap, wx.ITEM_NORMAL, "Open", "Long help for 'Open'", None)
        self.Bind(wx.EVT_TOOL, self.OnToolClick, id=20)

    def OnToolClick(self, event):
        print("tool %s clicked\n" % event.GetId())

app = wx.App(False)
frm = TestToolBar(None)

In Linux I get the expected behavior, but in Windows the image is the default button size:


Any thoughts about how I can use different sized images for different buttons on Windows? Thanks.

Python 3.10, wxpython 4.2.0

Hi folks,

I tested wx.ArtProvider and wx.Toolbar and found that the actions are different between 4.1.1 and 4.2.0. This seems like a bug in 4.2.0 to me.


Code Example (click to expand)
import wx

print("wxPython {}".format(wx.version()))

class Panel(wx.Panel):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        def _test(size):
            bmp = wx.ArtProvider.GetBitmap(wx.ART_FILE_OPEN, wx.ART_OTHER, size)
            return wx.StaticBitmap(self, -1, bmp, style=wx.BORDER)

            _test((24,24)), _test((48,24)), _test((24,48)),

class Frame(wx.Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        def _test(size):
            bmp = wx.ArtProvider.GetBitmap(wx.ART_FILE_OPEN, wx.ART_OTHER, size)
            return tb.AddTool(-1, "test", bmp)

        tb = self.CreateToolBar()
        if 1:
            _test((24,24)), _test((48,24)), _test((24,48)),

        panel = Panel(self, style=wx.BORDER)

if __name__ == "__main__":
    app = wx.App()
    frm = Frame(None, size=(320,160))

wxPython 4.1.1 msw (phoenix) wxWidgets 3.1.5

wxPython 4.2.0 msw (phoenix) wxWidgets 3.2.0

Tested with Python 3.8 on Windows 10

@SeaLion what are you trying to achieve :upside_down_face:


I don’t think at all that is a bug, rather it’s an overdue streamlining to avoid these arbitrary GUI designs (should one thank MS for that :hugs:)

Thank you for your valuable opinion.

Yeah, it’s normal design to use icons of the same size, but I’m not sure that MS intended that…
:worried: What I’m worried about is:

  1. I don’t see any documentation that the wx.ArtProvider was changed to serve 1:1 aspect ratio images with transparent padding instead of arbitrary aspect ratio images.
  2. wx.ToolBar seems to fit the button size depending on the size of the last image, forcing the previous image to expand to that size. In 4.1.1, the size of the button will be the largest size that all images will fit.

To be fixed, or not to be fixed, that is the question… :thinking:

@da-dada My goal is to use images of different shapes in the toolbar. I would like a couple sqaure ones and a couple rectangular ones. This works flawlessly in Linux … Just Windows seems to insist on square images.

I was stretching the builtin images just for an example, in reality I would provide 1:1 (square) and 1:5 (rectangular) images.

well @SeaLion, I’m fully aware of your ‘liking’, but my question was more contentual (at least I thought): what sense does it make, are some of the tools more precious, are they faster, more dangerous, more complicated, only for advanced use, only run in daylight :face_with_raised_eyebrow:

As a workaround, could you create wx.BitmapButtons of the required sizes and pass them to the toolbar’s AddControl() method, instead of using the toolbar’s AddTool() method?

@RichardT Thank you very much, this is working very well.