Phoenix
Phoenix copied to clipboard
BitmapButton.SetBitmap() changes button size on first call
Operating system: macOS 12.2.1 arm64
wxPython version & source: wx version: 4.1.1 osx-cocoa (phoenix) wxWidgets 3.1.5 (MacPorts)
Python version & source: python version: 3.9.10 (main, Jan 15 2022, 18:27:37) (MacPorts) [Clang 13.0.0 (clang-1300.0.29.3)]
Description of the problem: With a wx.BitmapButton first call to SetBitmap() method increases the size of the button. Doesn't matter if BitmapButton is constructed with default or specified size. I didn't expect this, especially when the button was constructed with a specific size and the image passed in SetBitmap() had the same size as original bitmap.
This is a minor problem but, without additional code, causes sizer items to overlap or look distorted. Button parameters other than size may also be affected. I tried setting button size and position after SetBitmap() which improved the appearance but layout was still messed up.
Code Example (click to expand)
import sys, platform
import wx
from wx.lib.embeddedimage import PyEmbeddedImage
Triangle_Blue = PyEmbeddedImage(
b'iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAIAAAC0tAIdAAAAA3NCSVQICAjb4U/gAAAAfElE'
b'QVQokYXSMQ7EIAxE0e+cOEV6c4At9pDcY1Ks2BAYkimQbKwnJBOSmBIRtr/NrVLK/xyjKQAc'
b'/mqoMxOACmTmy3SDq+VvdQdXy9+mO7ha/iom2PCsYcPzCI88j/DIb93adrO81v/NhKSIgGM9'
b'DXzhI4n24vdkpv9rq5ymkRKYv3vJYwAAAABJRU5ErkJggg==')
Triangle_Red = PyEmbeddedImage(
b'iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAIAAAC0tAIdAAAAA3NCSVQICAjb4U/gAAAAaUlE'
b'QVQokY3SSwrAMAgE0LEXy9EmN+vR7EKwxF87hIBGHi4iqooUESn7V27tvf2O0RQA91r1U6hJ'
b'ArAlSH5MG6wNf9QOa8Mf0w7byfxbBLjk0cEljwHOPAY485jhwGOGAw+D/4Rk/de6PGrHNH8d'
b'JjRKAAAAAElFTkSuQmCC')
class MyFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, wx.ID_ANY, "BitmapButton Bug")
self.bitmaps = [ Triangle_Blue.GetBitmap(), Triangle_Red.GetBitmap() ]
print('bitmap sizes', [b.GetSize() for b in self.bitmaps])
self.active_symbol = 0
self.bitmapButton = wx.BitmapButton(self, id=wx.ID_ANY,
bitmap=self.bitmaps[self.active_symbol], # size=wx.Size(20,20),
name='bitmap')
self.changeButton = wx.Button(self, id=wx.ID_ANY, label='Change')
sizer = wx.BoxSizer(wx.HORIZONTAL)
sizer.Add(self.bitmapButton)
sizer.Add(self.changeButton)
self.SetSizer(sizer)
self.Bind(wx.EVT_BUTTON, self.OnBitmapButton, self.bitmapButton)
self.Bind(wx.EVT_BUTTON, self.OnBitmapButton, self.changeButton)
def OnBitmapButton(self, event):
print('OnBitmapButton')
print('size before set bitmap', self.bitmapButton.GetSize())
self.active_symbol = (self.active_symbol + 1) % 2
self.bitmapButton.SetBitmap(self.bitmaps[self.active_symbol])
print('size after set bitmap', self.bitmapButton.GetSize())
if __name__ == "__main__":
app = wx.App()
print('os version:', platform.platform())
print('python version:', sys.version)
print('wx version:', wx.version())
frame = MyFrame().Show()
app.MainLoop()
Sample Code Output:
$ python wx_bitmapbutton_bug.py
os version: macOS-12.2.1-arm64-arm-64bit
python version: 3.9.10 (main, Jan 15 2022, 18:27:37)
[Clang 13.0.0 (clang-1300.0.29.3)]
wx version: 4.1.1 osx-cocoa (phoenix) wxWidgets 3.1.5
bitmap sizes [wx.Size(15, 15), wx.Size(15, 15)]
OnBitmapButton
size before set bitmap (27, 23)
size after set bitmap (39, 34)
OnBitmapButton
size before set bitmap (39, 34)
size after set bitmap (39, 34)
I can't confirm this on Windows. I get a size of (23,23) which is probably due to borders. But this size does not change afterwards.
Does Layout
make a difference?
self.Bind(wx.EVT_BUTTON, self.OnBitmapButton, self.changeButton)
print('size before layout', self.bitmapButton.GetSize())
self.Layout()
print('size after layout', self.bitmapButton.GetSize())
Does the look of the button change, except for the color?