wxPython - 将按钮固定到图像中的给定位置
wxPython - Fixing buttons to a given position in a image
我正在构建一个软件,我需要在其中显示图像上的按钮,并在图像所在的 sizer 调整大小时使其保持在相同的位置(尽可能最好)。
图像上的按钮显示已经完成。我现在只需要让数学工作。我已经尝试了一堆没有运气的东西。我想魔法需要在 updateButtons 函数中发生。
谢谢!
import wx
import wx.lib.platebtn as pb
class MainFrame(wx.Frame):
def __init__(self, parent):
super().__init__(parent)
self.bInfoSizerVisibility = False
self.images = []
self.initUI()
self.CenterOnScreen()
self.Bind(wx.EVT_SIZE, self.OnResizing)
def initUI(self):
self.imageSizer = wx.BoxSizer(wx.VERTICAL)
self.imageSizer.SetMinSize((800, 600))
self.bitmap = None
self.image = None
self.aspect = None
self.bmpImage = wx.StaticBitmap(self, wx.ID_ANY)
self.imageSizer.Add(self.bmpImage, 1, wx.EXPAND)
self.btn = pb.PlateButton(self.bmpImage, -1, 'Click Me!', style=pb.PB_STYLE_NOBG)
self.btn.Bind(wx.EVT_BUTTON, self.test)
self.btn.Position = 250, 250
self.SetSizerAndFit(self.imageSizer)
self.frameImage()
def test(self, event):
print('Button Pressed!')
def updateButtons(self):
w, h = self.bmpImage.GetSize()
u, v = 0.3, 0.7
self.btn.Position = int(u * w), int(v * h)
def frameImage(self, isJustResize=False):
if not isJustResize:
self.bitmap = wx.Bitmap('image.jpg', wx.BITMAP_TYPE_ANY)
self.image = wx.Bitmap.ConvertToImage(self.bitmap)
self.aspect = self.image.GetSize()[1] / self.image.GetSize()[0]
self.Layout()
sW, sH = self.imageSizer.GetSize()
newW = sW
newH = int(newW * self.aspect)
if newH > sH:
newH = sH
newW = int(newH / self.aspect)
image = self.image.Scale(newW, newH)
self.bmpImage.SetBitmap(image.ConvertToBitmap())
self.Layout()
self.Refresh()
self.updateButtons()
# print(f"Image New Size: ({newW}, {newH})")
# print(f"App Size: {self.GetSize()}")
# print(f"imageSizer Size: {self.imageSizer.GetSize()}\n")
def OnResizing(self, event):
self.frameImage(True)
event.Skip()
app = wx.App()
frame = MainFrame(None)
frame.Show()
app.MainLoop()
您需要考虑到这样一个事实,即在调整图像大小时,白色 space 会出现在左侧和右侧,或者出现在顶部和底部。请记住,按钮位置是相对于框架而不是图像。
我已经重写了你的 updateButtons 方法来实现这个。
我假设你的按钮的位置是 0.3 * 图像从左边的宽度和 0.7 * 图像从顶部的高度
import wx
import wx.lib.platebtn as pb
IMAGE_MINIMUM_SIZE = (800, 600)
BUTTON_POSITION_RATIO = (0.3, 0.7)
class MainFrame(wx.Frame):
def __init__(self, parent):
super().__init__(parent)
self.bInfoSizerVisibility = False
self.images = []
self.initUI()
self.CenterOnScreen()
self.Bind(wx.EVT_SIZE, self.OnResizing)
def initUI(self):
self.imageSizer = wx.BoxSizer(wx.VERTICAL)
self.imageSizer.SetMinSize(IMAGE_MINIMUM_SIZE)
self.bitmap = None
self.image = None
self.image_aspect = None
self.bmpImage = wx.StaticBitmap(self, wx.ID_ANY)
self.imageSizer.Add(self.bmpImage, 1, wx.EXPAND)
self.btn = pb.PlateButton(self, -1, 'Click Me!', style=pb.PB_STYLE_NOBG)
self.btn.Bind(wx.EVT_BUTTON, self.test)
self.SetSizerAndFit(self.imageSizer)
self.frameImage()
def test(self, event):
print('Button Pressed!')
def updateButtons(self):
frame_aspect = self.Size[0] / self.Size[1]
button_horizontal = int(self.Size[0] * BUTTON_POSITION_RATIO[0])
button_vertical = int(self.Size[1] * BUTTON_POSITION_RATIO[1])
if self.image_aspect <= frame_aspect:
# Frame is wider than image so find the horizontal white space size to add
image_width = self.Size[1] * self.image_aspect
horizontal_offset = (self.Size[0] - image_width)/2
button_horizontal = int(horizontal_offset + image_width * BUTTON_POSITION_RATIO[0])
elif self.image_aspect > frame_aspect:
# Frame is higher than image so find the vertical white space size to add
image_height = self.Size[0] / self.image_aspect
vertical_offset = (self.Size[1] - image_height)/2
button_vertical = int(vertical_offset + image_height * BUTTON_POSITION_RATIO[1])
self.btn.Position = (button_horizontal, button_vertical)
def frameImage(self, isJustResize=False):
if not isJustResize:
self.bitmap = wx.Bitmap('image.jpg', wx.BITMAP_TYPE_ANY)
self.image = wx.Bitmap.ConvertToImage(self.bitmap)
self.image_aspect = self.image.GetSize()[0] / self.image.GetSize()[1]
image_width, image_height = self.imageSizer.GetSize()
new_image_width = image_width
new_image_height = int(new_image_width / self.image_aspect)
if new_image_height > image_height:
new_image_height = image_height
new_image_width = int(new_image_height * self.image_aspect)
image = self.image.Scale(new_image_width, new_image_height)
self.bmpImage.SetBitmap(image.ConvertToBitmap())
self.Layout()
self.Refresh()
self.updateButtons()
def OnResizing(self, event):
self.frameImage(True)
event.Skip()
app = wx.App()
frame = MainFrame(None)
frame.Show()
app.MainLoop()
我正在构建一个软件,我需要在其中显示图像上的按钮,并在图像所在的 sizer 调整大小时使其保持在相同的位置(尽可能最好)。
图像上的按钮显示已经完成。我现在只需要让数学工作。我已经尝试了一堆没有运气的东西。我想魔法需要在 updateButtons 函数中发生。
谢谢!
import wx
import wx.lib.platebtn as pb
class MainFrame(wx.Frame):
def __init__(self, parent):
super().__init__(parent)
self.bInfoSizerVisibility = False
self.images = []
self.initUI()
self.CenterOnScreen()
self.Bind(wx.EVT_SIZE, self.OnResizing)
def initUI(self):
self.imageSizer = wx.BoxSizer(wx.VERTICAL)
self.imageSizer.SetMinSize((800, 600))
self.bitmap = None
self.image = None
self.aspect = None
self.bmpImage = wx.StaticBitmap(self, wx.ID_ANY)
self.imageSizer.Add(self.bmpImage, 1, wx.EXPAND)
self.btn = pb.PlateButton(self.bmpImage, -1, 'Click Me!', style=pb.PB_STYLE_NOBG)
self.btn.Bind(wx.EVT_BUTTON, self.test)
self.btn.Position = 250, 250
self.SetSizerAndFit(self.imageSizer)
self.frameImage()
def test(self, event):
print('Button Pressed!')
def updateButtons(self):
w, h = self.bmpImage.GetSize()
u, v = 0.3, 0.7
self.btn.Position = int(u * w), int(v * h)
def frameImage(self, isJustResize=False):
if not isJustResize:
self.bitmap = wx.Bitmap('image.jpg', wx.BITMAP_TYPE_ANY)
self.image = wx.Bitmap.ConvertToImage(self.bitmap)
self.aspect = self.image.GetSize()[1] / self.image.GetSize()[0]
self.Layout()
sW, sH = self.imageSizer.GetSize()
newW = sW
newH = int(newW * self.aspect)
if newH > sH:
newH = sH
newW = int(newH / self.aspect)
image = self.image.Scale(newW, newH)
self.bmpImage.SetBitmap(image.ConvertToBitmap())
self.Layout()
self.Refresh()
self.updateButtons()
# print(f"Image New Size: ({newW}, {newH})")
# print(f"App Size: {self.GetSize()}")
# print(f"imageSizer Size: {self.imageSizer.GetSize()}\n")
def OnResizing(self, event):
self.frameImage(True)
event.Skip()
app = wx.App()
frame = MainFrame(None)
frame.Show()
app.MainLoop()
您需要考虑到这样一个事实,即在调整图像大小时,白色 space 会出现在左侧和右侧,或者出现在顶部和底部。请记住,按钮位置是相对于框架而不是图像。
我已经重写了你的 updateButtons 方法来实现这个。
我假设你的按钮的位置是 0.3 * 图像从左边的宽度和 0.7 * 图像从顶部的高度
import wx
import wx.lib.platebtn as pb
IMAGE_MINIMUM_SIZE = (800, 600)
BUTTON_POSITION_RATIO = (0.3, 0.7)
class MainFrame(wx.Frame):
def __init__(self, parent):
super().__init__(parent)
self.bInfoSizerVisibility = False
self.images = []
self.initUI()
self.CenterOnScreen()
self.Bind(wx.EVT_SIZE, self.OnResizing)
def initUI(self):
self.imageSizer = wx.BoxSizer(wx.VERTICAL)
self.imageSizer.SetMinSize(IMAGE_MINIMUM_SIZE)
self.bitmap = None
self.image = None
self.image_aspect = None
self.bmpImage = wx.StaticBitmap(self, wx.ID_ANY)
self.imageSizer.Add(self.bmpImage, 1, wx.EXPAND)
self.btn = pb.PlateButton(self, -1, 'Click Me!', style=pb.PB_STYLE_NOBG)
self.btn.Bind(wx.EVT_BUTTON, self.test)
self.SetSizerAndFit(self.imageSizer)
self.frameImage()
def test(self, event):
print('Button Pressed!')
def updateButtons(self):
frame_aspect = self.Size[0] / self.Size[1]
button_horizontal = int(self.Size[0] * BUTTON_POSITION_RATIO[0])
button_vertical = int(self.Size[1] * BUTTON_POSITION_RATIO[1])
if self.image_aspect <= frame_aspect:
# Frame is wider than image so find the horizontal white space size to add
image_width = self.Size[1] * self.image_aspect
horizontal_offset = (self.Size[0] - image_width)/2
button_horizontal = int(horizontal_offset + image_width * BUTTON_POSITION_RATIO[0])
elif self.image_aspect > frame_aspect:
# Frame is higher than image so find the vertical white space size to add
image_height = self.Size[0] / self.image_aspect
vertical_offset = (self.Size[1] - image_height)/2
button_vertical = int(vertical_offset + image_height * BUTTON_POSITION_RATIO[1])
self.btn.Position = (button_horizontal, button_vertical)
def frameImage(self, isJustResize=False):
if not isJustResize:
self.bitmap = wx.Bitmap('image.jpg', wx.BITMAP_TYPE_ANY)
self.image = wx.Bitmap.ConvertToImage(self.bitmap)
self.image_aspect = self.image.GetSize()[0] / self.image.GetSize()[1]
image_width, image_height = self.imageSizer.GetSize()
new_image_width = image_width
new_image_height = int(new_image_width / self.image_aspect)
if new_image_height > image_height:
new_image_height = image_height
new_image_width = int(new_image_height * self.image_aspect)
image = self.image.Scale(new_image_width, new_image_height)
self.bmpImage.SetBitmap(image.ConvertToBitmap())
self.Layout()
self.Refresh()
self.updateButtons()
def OnResizing(self, event):
self.frameImage(True)
event.Skip()
app = wx.App()
frame = MainFrame(None)
frame.Show()
app.MainLoop()