image - wxPython - 将按钮固定到图像中的给定位置
问题描述
我正在构建一个软件,我需要在图像上显示按钮,并在调整图像大小时使其保持在同一位置(尽可能最佳)。
图像上的按钮显示已经完成。我现在只需要让数学工作。我已经尝试了一堆没有运气的东西。我想魔法需要在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()
解决方案
您需要考虑这样一个事实,即当您调整图像大小时,会在左侧和右侧或顶部和底部出现空白。请记住,按钮位置是相对于框架而不是图像。
我已经重写了您的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()
推荐阅读
- r - R不会在数据框中读取CSV的数值
- amazon-web-services - api 网关找不到 lambda 别名
- postgresql - PostgreSQL 更新触发器:关系“新”不存在
- git - 如何将 gpg 密钥传输到另一台计算机?
- formatting - 仅突出显示已“拖”过来的文本/代码?
- react-native - 无法创建自定义 StackNavigator - “无法注册导航器”?
- r - 试图获取从列值派生的 checkboxGroupInput 以过滤条形图,但不断收到各种错误?
- javascript - 如何添加文档并将其 ID 立即存储在 Firebase 的其他地方?使用本机反应
- javascript - 运行 react-app-rewired build 时忽略文件
- c++ - 为什么我只输出一半大小的堆栈?C++