wxpython - 如何无闪烁地调整图像大小?

1 投票
2 回答
2042 浏览
提问于 2025-04-16 16:44

我刚接触wxPython和图形用户界面(GUI)。现在我的应用程序只显示了一个工具栏、状态栏和一个面板。这个面板里有一个盒子布局,里面放着一个静态图片。我想让这个图片在窗口大小改变时自动调整大小,以适应它的容器,但我遇到了很多闪烁的问题。

总结
当窗口大小改变时,会调用resizeImage()(EVT_SIZE事件触发)
resizeImage()会调整面板的大小以适应新的尺寸,然后通过scaleImage()来缩放图片,并把它放到静态图片中。

resizeImage()的基本功能是获取图片对象,调整它的大小,把它设置为位图,然后将其设置为静态图片以供显示。

代码

class Canvas(wx.Panel):
"""Panel used to display selected images"""

#---------------------------------------------------------------------------
def __init__(self, parent):
    """Constructor"""
    wx.Panel.__init__(self, parent)

    # Globals
    self.image        = wx.EmptyImage(1,1)
    self.control    = wx.StaticBitmap(self, wx.ID_ANY, 
                                     wx.BitmapFromImage(self.image))    
    self.background    = wx.BLACK
    self.padding    = 5
    self.imageList    = []
    self.current    = 0
    self.total        = 0

    # Register Events
    Publisher().subscribe(self.onLoadDirectory, ("load directory"))
    Publisher().subscribe(self.resizeImage, ("resize window"))

    # Set Layout
    self.mainSizer = wx.BoxSizer(wx.VERTICAL)
    self.mainSizer.Add(self.control, 1, wx.ALL|wx.CENTER|wx.EXPAND,
            self.padding)
    self.SetSizer(self.mainSizer)
    self.SetBackgroundColour(self.background)

#---------------------------------------------------------------------------
def scaleImage(self, image, maxWidth, maxHeight):
    """asd"""
    width    = image.GetWidth()
    height    = image.GetHeight()
    ratio    = min( maxWidth / width, maxHeight/ height );
    image    = image.Scale(ratio*width, ratio*height, wx.IMAGE_QUALITY_HIGH)
    result    = wx.BitmapFromImage(image)

    return result

#---------------------------------------------------------------------------
def loadImage(self, image):
    """Load image"""
    self.image = wx.Image(image, wx.BITMAP_TYPE_ANY)
    bmp = wx.BitmapFromImage(self.image)
    w, h = self.mainSizer.GetSize()
    w = w - self.padding*2
    h = h - self.padding*2
    bmp = self.scaleImage(self.image, w, h)        
    self.control.SetBitmap(bmp)

#---------------------------------------------------------------------------
def getImageIndex(self, path):
    """Retrieve index of image from imagePaths"""
    i = 0
    for image in self.imagePaths:
        if image == path:
            return i
        i += 1
    return -1

#---------------------------------------------------------------------------
def resizeImage(self, event):
    self.SetSize(event.data)
    if self.total:
        w = event.data[0] - self.padding*2
        h = event.data[1] - self.padding*2
        bmp = self.scaleImage(self.image, w, h)
        self.control.SetBitmap(bmp)

#---------------------------------------------------------------------------
def onLoadDirectory(self, event):
    """Load the image and compile a list of image files from directory"""
    self.folderPath        = os.path.dirname(event.data)
    self.imagePaths        = glob.glob(self.folderPath + "\\*.jpg")
    self.total            = len(self.imagePaths)
    self.current        = self.getImageIndex(event.data)
    self.SetSize(self.GetSize())
    self.loadImage(self.imagePaths[self.current])

2 个回答

1

在你的resizeImage方法中,添加一个“冻结”和一个“解冻”可能会有帮助,像这样:

def resizeImage(self, event):
    self.SetSize(event.data)
    if self.total:
        w = event.data[0] - self.padding*2
        h = event.data[1] - self.padding*2
        self.Freeze()
        bmp = self.scaleImage(self.image, w, h)
        self.control.SetBitmap(bmp)
        self.Thaw()
1

试着在一个绘图上下文上进行双缓冲绘图,而不是使用静态位图。

撰写回答