Hi people,
I write a simple example for the problem. Put the code into a .py file and run it. Open the file menu and click to shape label (the MDIChild frame appear). Now, open the task manager (my OS is windows xp) and in a "Proccess" tab, add a "GDI Object" column. You will see the number of gdi objects create for the test application. When you close the MDIChild frame, this number not decreasing and in a successive open of MDIChildFrame, the application saturates the memory.
best regards,
Stefano Casagrande.
#!/usr/bin/env python
#Boa:App:BoaApp
import wx
import wx.lib.ogl as ogl
import random
[wxID_MDICHILDFRAME1] = [wx.NewId() for _init_ctrls in range(1)]
class MDIChildGDIFrame(wx.MDIChildFrame):
def _init_ctrls(self, prnt):
wx.MDIChildFrame.__init__(self, style=wx.DEFAULT_FRAME_STYLE, name='', parent=prnt, title='MDIChildFrame1', pos=wx.Point(-1, -1), id=wxID_MDICHILDFRAME1, size=wx.Size(-1, -1))
ogl.OGLInitialize()
self.Object_panel = ObjectArea(self, self.GetSize())
self.CreateStatusBar()
def __init__(self, parent):
self._init_ctrls(parent)
class ObjectArea(ogl.ShapeCanvas):
def __init__(self, parent, size=wx.DefaultSize):
ogl.ShapeCanvas.__init__(self, parent=parent, id=wx.NewId(), size=size, style=wx.SUNKEN_BORDER)
maxWidth = 2000
maxHeight = 2000
self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20)
self.SetBackgroundColour(wx.WHITE)
self.diagram = ogl.Diagram()
self.SetDiagram(self.diagram)
self.diagram.SetCanvas(self)
self.diagram.SetSnapToGrid(False)
for i in range(500):
x, y = random.randint(0, 2000), random.randint(0, 2000)
self.MyAddShape(
CompositeShape(self),
x, y, wx.BLACK_PEN, wx.RED_BRUSH, "Composite"
)
def MyAddShape(self, shape, x, y, pen, brush, text):
# Composites have to be moved for all children to get in place
if isinstance(shape, ogl.CompositeShape):
dc = wx.ClientDC(self)
self.PrepareDC(dc)
shape.Move(dc, x, y)
else:
shape.SetDraggable(True, True)
shape.SetCanvas(self)
shape.SetX(x)
shape.SetY(y)
if pen: shape.SetPen(pen)
if brush: shape.SetBrush(brush)
if text:
for line in text.split('\n'):
shape.AddText(line)
#shape.SetShadowMode(ogl.SHADOW_RIGHT)
self.diagram.AddShape(shape)
shape.Show(True)
evthandler = MyEvtHandler(self.GetParent())
evthandler.SetShape(shape)
evthandler.SetPreviousHandler(shape.GetEventHandler())
shape.SetEventHandler(evthandler)
return shape
class CompositeShape(ogl.CompositeShape):
def __init__(self, canvas):
ogl.CompositeShape.__init__(self)
self.SetCanvas(canvas)
constraining_shape = ogl.RectangleShape(120, 100)
constrained_shape1 = ogl.CircleShape(50)
constrained_shape2 = ogl.RectangleShape(80, 20)
constraining_shape.SetBrush(wx.BLUE_BRUSH)
constrained_shape2.SetBrush(wx.RED_BRUSH)
self.AddChild(constraining_shape)
self.AddChild(constrained_shape1)
self.AddChild(constrained_shape2)
constraint = ogl.Constraint(ogl.CONSTRAINT_MIDALIGNED_BOTTOM, constraining_shape, [constrained_shape1, constrained_shape2])
self.AddConstraint(constraint)
self.Recompute()
# If we don't do this, the shapes will be able to move on their
# own, instead of moving the composite
constraining_shape.SetDraggable(False)
constrained_shape1.SetDraggable(False)
constrained_shape2.SetDraggable(False)
# If we don't do this the shape will take all left-clicks for itself
constraining_shape.SetSensitivityFilter(0)
class MyEvtHandler(ogl.ShapeEvtHandler):
def __init__(self, frame):
ogl.ShapeEvtHandler.__init__(self)
self.statbarFrame = frame
def UpdateStatusBar(self, shape):
x, y = shape.GetX(), shape.GetY()
width, height = shape.GetBoundingBoxMax()
self.statbarFrame.SetStatusText("Pos: (%d, %d) Size: (%d, %d)" %
(x, y, width, height))
def OnLeftClick(self, x, y, keys=0, attachment=0):
shape = self.GetShape()
canvas = shape.GetCanvas()
dc = wx.ClientDC(canvas)
canvas.PrepareDC(dc)
if shape.Selected():
shape.Select(False, dc)
canvas.Redraw(dc)
else:
redraw = False
shapeList = canvas.GetDiagram().GetShapeList()
toUnselect =
for s in shapeList:
if s.Selected():
# If we unselect it now then some of the objects in
# shapeList will become invalid (the control points are
# shapes too!) and bad things will happen...
toUnselect.append(s)
shape.Select(True, dc)
if toUnselect:
for s in toUnselect:
s.Select(False, dc)
canvas.Redraw(dc)
self.UpdateStatusBar(shape)
def OnEndDragLeft(self, x, y, keys=0, attachment=0):
shape = self.GetShape()
ogl.ShapeEvtHandler.OnEndDragLeft(self, x, y, keys, attachment)
if not shape.Selected():
self.OnLeftClick(x, y, keys, attachment)
self.UpdateStatusBar(shape)
def OnSizingEndDragLeft(self, pt, x, y, keys, attch):
ogl.ShapeEvtHandler.OnSizingEndDragLeft(self, pt, x, y, keys, attch)
self.UpdateStatusBar(self.GetShape())
def OnMovePost(self, dc, x, y, oldX, oldY, display):
ogl.ShapeEvtHandler.OnMovePost(self, dc, x, y, oldX, oldY, display)
self.UpdateStatusBar(self.GetShape())
def OnRightClick(self, *dontcare):
pass
[wxID_FRAME1] = [wx.NewId() for _init_ctrls in range(1)]
class Frame1(wx.MDIParentFrame):
def _init_ctrls(self, prnt):
wx.MDIParentFrame.__init__(self, style=wx.DEFAULT_FRAME_STYLE | wx.VSCROLL | wx.HSCROLL | wx.MAXIMIZE, name='', parent=prnt, title='Frame1', pos=wx.Point(-1, -1), id=wxID_FRAME1, size=wx.Size(-1, -1))
def __init__(self, parent):
self._init_ctrls(parent)
#crea Menu Function
self.SentryMenuFunction = wx.Menu()
self.ID_Menu_Events = wx.NewId()
self.SentryMenuFunction.Append(self.ID_Menu_Events, "Shape")
#crea Menu bar
self.SentryMenuBar = wx.MenuBar()
self.SentryMenuBar.Append(self.SentryMenuFunction, "&Function")
self.SetMenuBar(self.SentryMenuBar)
self.Bind(wx.EVT_MENU, self.OnShape, id=self.ID_Menu_Events)
self.Maximize()
def OnShape(self, event):
cf = MDIChildGDIFrame(self)
cf.Show(True)
event.Skip()
class BoaApp(wx.App):
def OnInit(self):
wx.InitAllImageHandlers()
self.main = Frame1(None)
self.main.Show()
self.SetTopWindow(self.main)
return True
def main():
application = BoaApp(0)
application.MainLoop()
if __name__ == '__main__':
main()
···
stefcasa@inwind.it wrote:
> I have a problem with lib.ogl classes: in my project there are many ogl objects instance
> (ogl.BitmapShape and ogl.EllipseShape) inside a ogl.ShapeCanvas and the ogl.ShapeCanvas is
> inside MDIChildFrame. The number of ogl objects depend from many factors and this number
> change during time. When I close the MDIChildFrame, the gdi objects is not released from memory
> (I see that in task manager) and in a successive MDIChildFrame open the application creates new gdi objects.
> In a successive open, the application saturates the memory and I must Kill it.
> How I can make in order to resolve the problem of the memory release of the gdi objects?Are you able to narrow it down any further? Perhaps to figure out what
it is that is not being released?--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!