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()