Whenever I handle EVT_PAINT event by binding it to a function some problem occures the frame/window opens up but it cannot be closed when I click on the close option on the top-right corner of the frame. Can any one tell me what can be the reason for this ??? Apart form that there is a lot of flicker that occures.
The purpose of the code is somewhat like this. I have a Main Frame class which holds a panel. In that panel I have a wxPython Notebook. There are two pages in the notebook. Each page has same structure having two panels, image panel and control panel. Image panel displays image and control panel has a file open button that opens the file to be displayed in the image panel. By default image panel shows a image called "default.png".
Just create some png image in the same folder as that of the program and name it as default.png so that the program works.
Here is the sample code.
import os
import wx
#===========================================================================
# This is how you pre-establish a file filter so that the dialog
# only shows the extension(s) you want it to.
wildcard = "Python source (*.py)|*.py|" \
"Compiled Python (*.pyc)|*.pyc|" \
"SPAM files (*.spam)|*.spam|" \
"Egg file (*.egg)|*.egg|" \
"All files (*.*)|*.*"
#===========================================================================
#========================================================================
# Set to 1 when new image is uploaded.
imageChangeFlag = [0];
#========================================================================
#========================================================================
# Set to 1 when new image is uploaded.
pageChangeFlag = [0];
#========================================================================
# Some classes to use for the notebook pages. Obviously you would
# want to use something more meaningful for your application, these
# are just for illustration.
class ImagePanel(wx.Panel):
'''
Create an image panel.
Sets all the controls of image panel
'''
def __init__(self,parent):
wx.Panel.__init__(self,parent,id=-1,
name="Image Panel",
style=wx.BORDER_THEME)
self.SetBackgroundColour(wx.WHITE)
class ControlPanel(wx.Panel):
'''
Create a control panel.
Sets all the controls of the control panel
'''
def __init__(self,parent):
wx.Panel.__init__(self,parent,id=-1,
name="Control Panel",
style=wx.BORDER_THEME)
self.SetBackgroundColour(wx.Colour(235,234,211))
class PageOne(wx.Panel):
'''
This panel is the first page of the notebook and sets all the widgets in the first page.
'''
def __init__(self, parent, id):
'''
Constructor for page 1 initializes the first page of the notebook
'''
wx.Panel.__init__(self, parent, id, name="Network Visualization")
#t = wx.StaticText(self, -1, "This is a PageOne object", (20,20))
self.path = "default.png"
#====================================================================
# Set the Network Visualization Page.
#====================================================================
self.imagePanel = ImagePanel(self)
self.controlPanel = ControlPanel(self)
fileOpenButton = wx.Button(self.controlPanel, -1, "Browse", (30,30))
self.Bind(wx.EVT_BUTTON, self.onFileOpen, fileOpenButton)
controlSizer = wx.BoxSizer()
controlSizer.Add(fileOpenButton,1)
self.controlPanel.SetSizer(controlSizer)
box = wx.BoxSizer()
box.Add(self.imagePanel,3,wx.EXPAND)
box.Add(self.controlPanel,1,wx.EXPAND)
self.SetSizer(box)
self.loadImage(self.path)
def onFileOpen(self,event):
fileOpenDlg = wx.FileDialog(self.controlPanel,
message="Select a file",
defaultDir=os.getcwd(),
defaultFile="",
wildcard=wildcard,
style=wx.OPEN |wx.CHANGE_DIR)
# Show the dialog and retrieve the user response. If it is the OK response,
# process the data.
if fileOpenDlg.ShowModal() == wx.ID_OK:
image = fileOpenDlg.GetPath()
# Load the new image and set the imageChangeFlag to 1.
self.loadImage(image)
imageChangeFlag[0] = 1;
# Destroy the dialog. Don't do this until you are done with it!
# BAD things can happen otherwise!
fileOpenDlg.Destroy()
def loadImage(self,image):
'''
Initializes the image.
Finds the properties of the image like the aspect ratio and bitmap.
'''
self.png = wx.Image(image, wx.BITMAP_TYPE_ANY)
imageHeight = self.png.GetHeight()
imageWidth = self.png.GetWidth()
self.aspectRatio = imageWidth/imageHeight
self.bitmap = wx.BitmapFromImage(self.png)
def getImagePanel(self):
return self.imagePanel
def getControlPanel(self):
return self.controlPanel
def getImage(self):
return self.png
def getImageBitmap(self):
return self.bitmap
def getImageAspectRatio(self):
return self.aspectRatio
class PageTwo(wx.Panel):
def __init__(self, parent, id):
'''
Constructor for page 1 initializes the first page of the notebook
'''
wx.Panel.__init__(self, parent, id, name="Graph Visualization")
#t = wx.StaticText(self, -1, "This is a PageTwo object", (40,40))
self.path = "default.png"
#====================================================================
# Set the Network Visualization Page.
#====================================================================
self.imagePanel = ImagePanel(self)
self.controlPanel = ControlPanel(self)
fileOpenButton = wx.Button(self.controlPanel, -1, "Browse", (30,30))
self.Bind(wx.EVT_BUTTON, self.onFileOpen, fileOpenButton)
controlSizer = wx.BoxSizer()
controlSizer.Add(fileOpenButton,1)
self.controlPanel.SetSizer(controlSizer)
box = wx.BoxSizer()
box.Add(self.imagePanel,3,wx.EXPAND)
box.Add(self.controlPanel,1,wx.EXPAND)
self.SetSizer(box)
self.loadImage(self.path)
def onFileOpen(self,event):
fileOpenDlg = wx.FileDialog(self.controlPanel,
message="Select a file",
defaultDir=os.getcwd(),
defaultFile="",
wildcard=wildcard,
style=wx.OPEN |wx.CHANGE_DIR)
# Show the dialog and retrieve the user response. If it is the OK response,
# process the data.
if fileOpenDlg.ShowModal() == wx.ID_OK:
image = fileOpenDlg.GetPath()
# Load the new image and set the imageChangeFlag to 1.
self.loadImage(image)
imageChangeFlag[0] = 1;
# Destroy the dialog. Don't do this until you are done with it!
# BAD things can happen otherwise!
fileOpenDlg.Destroy()
def loadImage(self,image):
'''
Initializes the image.
Finds the properties of the image like the aspect ratio and bitmap.
'''
self.png = wx.Image(image, wx.BITMAP_TYPE_ANY)
imageHeight = self.png.GetHeight()
imageWidth = self.png.GetWidth()
self.aspectRatio = imageWidth/imageHeight
self.bitmap = wx.BitmapFromImage(self.png)
def getImagePanel(self):
return self.imagePanel
def getControlPanel(self):
return self.controlPanel
def getImage(self):
return self.png
def getImageBitmap(self):
return self.bitmap
def getImageAspectRatio(self):
return self.aspectRatio
class Notebook(wx.Notebook):
'''
Creates a Notebook.
'''
def __init__(self,parent):
wx.Notebook.__init__(self,parent,size=parent.GetSizeTuple())
class MainFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None,
title="Social Network Analysis",
size=(900,700))
#======================================================================
# Create a panel and a notebook on the panel
#======================================================================
self.p = wx.Panel(self,size=self.GetSizeTuple())
self.nb = Notebook(self.p)
#====================================================================
# Create the page windows as children of the notebook
#====================================================================
self.networkVisualizationPage = PageOne(self.nb,id=1)
self.graphVisualizationPage = PageTwo(self.nb,id=2)
#=======================================================================================
# Initialize the page id to 1.
# By default Network Visualization Page will be selected first.
# Get the image panel from networkVisualization page.
# Then get the image to be displayed on the image panel of networkVisualization page.
#=======================================================================================
self.pageId = 1
self.pageSelect()
self.imageRefresh()
#======================================================================
# Add the pages to the notebook with the label to show on the tab
#======================================================================
self.nb.AddPage(self.networkVisualizationPage, "Network Visualization")
self.nb.AddPage(self.graphVisualizationPage, "Graph Visualization")
#======================================================================
# Finally, put the notebook in a sizer for the panel to manage the layout
#======================================================================
sizer = wx.BoxSizer()
sizer.Add(self.nb, 1, wx.EXPAND)
self.p.SetSizer(sizer)
self.Bind(wx.EVT_PAINT, self.onPaint)
self.Bind(wx.EVT_SIZE, self.onResize)
self.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.onPageChange)
self.Bind(wx.EVT_ERASE_BACKGROUND , self.erase)
def erase(self,event):
pass
def onPageChange(self,event):
'''
Handles the EVT_NOTEBOOK_PAGE_CHANGED event
'''
pageChangeFlag[0] = 1
self.pageId = self.nb.GetCurrentPage().GetId()
self.pageSelect()
self.imageRefresh()
#print "Page Change"
#print self.pageId
def onPaint(self,event):
'''
Handles EVT_PAINT event.
'''
if(imageChangeFlag[0] == 1 or pageChangeFlag[0] == 1):
imageChangeFlag[0] = 0
pageChangeFlag[0] = 0
self.imageRefresh()
(w, h) = self.getBestSize()
self.scaledPNG = self.png.Scale(w,h,quality=wx.IMAGE_QUALITY_HIGH)
self.bitmap = wx.BitmapFromImage(self.scaledPNG)
self.Refresh()
imagePanelDC = wx.PaintDC(self.imagePanel)
imagePanelDC.DrawBitmap(self.bitmap, 0, 0, useMask=False)
#controlPanelDC = wx.PaintDC(self.controlPanel)
imagePanelDC.Destroy()
def onResize(self,event):
'''
Handles EVT_SIZE event.
'''
self.p.SetSize(self.GetSizeTuple())
(w, h) = self.getBestSize()
self.imageRefresh()
self.scaledPNG = self.png.Scale(w,h,quality=wx.IMAGE_QUALITY_HIGH)
self.bitmap = wx.BitmapFromImage(self.scaledPNG)
self.Refresh()
def imageRefresh(self):
#======================================================================
# Initialize the image parameters
#======================================================================
if(self.pageId == 1):
self.png = self.networkVisualizationPage.getImage()
self.bitmap = self.networkVisualizationPage.getImageBitmap()
self.aspectRatio = self.networkVisualizationPage.getImageAspectRatio()
elif(self.pageId == 2):
self.png = self.graphVisualizationPage.getImage()
self.bitmap = self.graphVisualizationPage.getImageBitmap()
self.aspectRatio = self.graphVisualizationPage.getImageAspectRatio()
def pageSelect(self):
#========================================================================
# Selects the image panel and control panel of appropriate page
#========================================================================
if(self.pageId == 1):
self.imagePanel = self.networkVisualizationPage.getImagePanel()
self.controlPanel = self.networkVisualizationPage.getControlPanel()
elif(self.pageId == 2):
self.imagePanel = self.graphVisualizationPage.getImagePanel()
self.controlPanel = self.graphVisualizationPage.getControlPanel()
def getBestSize(self):
'''
Returns the best size the image can have based on the aspect ratio of the image.
'''
(w,h) = self.imagePanel.GetSizeTuple()
#print "Image Panel Size = "
#print (w,h)
reductionFactor = 0.1
# Reduce the height by 20 units and change width of the image according to aspect ratio
newHeight = int(h - (h * reductionFactor))
newWidth = int (self.aspectRatio * newHeight)
newSize = (newWidth,newHeight)
#print "Image Size = "
#print newSize
return newSize
if __name__ == "__main__":
app = wx.App()
MainFrame().Show()
app.MainLoop()