当调整父 wx.Frame 的大小时(例如 wxPython for image and buttons (resizable) ),我需要能够在 wx.Panel 中重新缩放图像(实时)。
此代码现在可以运行,其行为就像在标准照片查看器中一样:图像完全适合父窗口,并且重新缩放遵循宽高比。
import wx
class MainPanel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent, -1, style=wx.FULL_REPAINT_ON_RESIZE)
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.img = wx.Image('background.png', wx.BITMAP_TYPE_PNG)
self.imgx, self.imgy = self.img.GetSize()
def OnPaint(self, event):
dc = wx.PaintDC(self)
dc.Clear()
x,y = self.GetSize()
posx,posy = 0, 0
newy = int(float(x)/self.imgx*self.imgy)
if newy < y:
posy = int((y - newy) / 2)
y = newy
else:
newx = int(float(y)/self.imgy*self.imgx)
posx = int((x - newx) / 2)
x = newx
img = self.img.Scale(x,y, wx.IMAGE_QUALITY_HIGH)
self.bmp = wx.BitmapFromImage(img)
dc.DrawBitmap(self.bmp,posx,posy)
class MainFrame(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent, -1, title='Test', size=(600,400))
self.panel = MainPanel(self)
self.Show()
app = wx.App(0)
frame = MainFrame(None)
app.MainLoop()
在继续实现某些事情之前,我想知道:
- 这是做到这一点的“好方法”吗?
FULL_REPAINT_ON_RESIZE
可能有点太多了(效率低下),但没有这个我就无法完成,您有改进的想法吗?- 如何跟踪鼠标点击? 示例:我想跟踪原始图像的原始坐标中 (10,20) 到 (50,50) 的矩形中的点击。我应该将其转换为新坐标(因为图像已重新缩放!)?这意味着我现在应该在非常低的级别上完成所有事情......
最佳答案
这不是一个坏方法,但有一些事情您可以轻松优化:
- 不要每次在
OnPaint()
中调用wxImage::Scale()
。这是一个缓慢的操作,您应该只在wxEVT_SIZE
处理程序中执行一次,而不是每次重新绘制窗口时都执行该操作。 - 调用
SetBackgroundStyle(wxBG_STYLE_PAINT)
来指示您的wxEVT_PAINT
处理程序已经完全删除背景,这将减少某些平台上的闪烁(在无论如何,其他总是使用双缓冲,但即使在那里,它仍然会使重画速度稍微快一些)。
至于鼠标点击,我想你别无选择,只能自己翻译坐标。
关于python - 在 wxPython 中调整父级大小时重新缩放图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21369877/