在wxPython中调整父级大小时重新缩放图像

时间:2014-01-26 22:04:01

标签: python wxpython wxwidgets

当调整父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)中的单击。我应该在新坐标中转换它(因为图像已经重新调整!)?这意味着我现在应该在非常低的水平上做所有事情......

1 个答案:

答案 0 :(得分:1)

这不是一个糟糕的方法,但有一些事情可以轻松优化:

  1. 每次wxImage::Scale()都不要致电OnPaint()。这是一个很慢的操作,你应该只在你的wxEVT_SIZE处理程序中执行一次,而不是每次重新绘制窗口时都这样做。
  2. 调用SetBackgroundStyle(wxBG_STYLE_PAINT)表示你的wxEVT_PAINT处理程序已经完全删除了后台,这将减少某些平台上的闪烁(你不会看到其他总是使用双缓冲的差异,无论如何,但即使在那里,它仍然会使重新绘制的速度略快。
  3. 至于鼠标点击,我认为你没有别的选择,只能自己翻译坐标。