【问题标题】:Rescale image when parent is resized in wxPython在 wxPython 中调整父级大小时重新缩放图像
【发布时间】:2014-01-26 22:04:01
【问题描述】:

当父 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) 在原始图像的原始坐标中的点击。我应该将其转换为新坐标(因为图像已重新缩放!)?这意味着我现在应该在非常低的级别上做所有事情......

【问题讨论】:

    标签: python wxpython wxwidgets


    【解决方案1】:

    这不是一个糟糕的方法,但您可以轻松优化以下几点:

    1. 不要每次都拨打wxImage::Scale()OnPaint()。这是一个缓慢的操作,您应该只在 wxEVT_SIZE 处理程序中执行一次,而不是每次重新绘制窗口时都执行此操作。
    2. 调用SetBackgroundStyle(wxBG_STYLE_PAINT) 表明您的wxEVT_PAINT 处理程序已经完全擦除了背景,这将减少某些平台上的闪烁(无论如何,您不会在其他总是使用双缓冲的平台上看到任何差异,但它仍然会即使在那里,也可以稍微加快重绘速度)。

    至于鼠标点击,我想你别无选择,只能自己翻译坐标。

    【讨论】:

    • 我尝试了1.,但我不能在OnPaint() (wx.EVT_PAINT) 之外的其他地方使用dc = wx.PaintDC(self)。如果您可以修改我在此处提供的代码以显示您的修改(我认为这可能对许多用户有用)?
    • 为什么需要dc 来调整图像大小?它是完全独立的,只需在您的wxEVT_SIZE 处理程序中分配self.bmp。当然,您仍然需要在 wxEVT_PAINT 处理程序中保留 dc.DrawBitmap() 调用自身。
    猜你喜欢
    • 2018-06-15
    • 1970-01-01
    • 2023-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多