I'm new to wxPython and GUI in general. Right now the application just displays a toolbar, statusbar, and the following panel. The panel contains a boxSizer with a staticBitmap in it. I'm trying to have an image resize itself to fit its container whenever the window is resized, but I'm running into a lot of flickering.
Summary
resizeImage() is called when the window is resized (EVT_SIZE fires) resizeImage() resizes the panel to fit the new dimensions and then scales the image with scaleImage() and it is placed into the staticBitmapresizeImage() basically grabs the image object, resizes it, sets it to a bitmap, and then sets it to the staticbitmap to be displayed.
Code
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])
Try drawing on a double buffered DC instead of using a StaticBitmap.
In your resizeImage method, it might help to add a Freeze and a Thaw, like this:
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()
精彩评论