Hi,
I am getting a crash (IndexError) with wxPython 2.5.4.1 on MSW, Python 2.3, if I use a wxLine with an associated label and I click on it, invoking OnLeftClick. See attached sample, which is basically a stripped down version of the OGL demo, but with a clickable ogl.LineShape _with a label_. The traceback is:
Traceback (most recent call last):
File "C:\Python23\Lib\site-packages\wx-2.5.4-msw-unicode\wx\lib\ogl\_canvas.py", line 219, in OnMouseEvent
nearest_object.GetEventHandler().OnLeftClick(x, y, keys, attachment)
File "C:\Documents and Settings\davides\My Documents\Software\Packages\eclipse-SDK-3.0.1-win32\eclipse\workspace\wxPython Stuff\broken_line.py", line 24, in OnLeftClick
shape.Select(True, dc)
File "C:\Python23\lib\site-packages\wx-2.5.4-msw-unicode\wx\lib\ogl\_lines.py", line 1114, in Select
if self._regions[i]:
IndexError: list index out of range
If you comment out the line
line.AddText("Line Label")
from the sample below, or if you don't click on the label, no crash. I had a quick look at the OGL source, and it seems to me that the IndexError is generated because OnLabelMovePre() (file _lines.py) removes one of the LineShape regions. (I don't follow the logic being used there)
I tried to run the same code on a system with wxPython 2.4.2.4 and the old C++ OGL, and I am getting a crash there as well (wxPyDeadObjectError: The C++ part of the wxPyRectangleShapePtr object has been deleted, attribute access no longer allowed), although to make it crash there you first need to click on the line, and then on one of the nodes.
Regards,
Davide
···
====
import wx
import wx.lib.ogl as ogl
class MyEvtHandler(ogl.ShapeEvtHandler):
def __init__(self, frame):
ogl.ShapeEvtHandler.__init__(self)
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:
shapeList = canvas.GetDiagram().GetShapeList()
toUnselect = []
for s in shapeList:
if s.Selected():
toUnselect.append(s)
shape.Select(True, dc)
if toUnselect:
for s in toUnselect:
s.Select(False, dc)
canvas.Redraw(dc)
class TestWindow(ogl.ShapeCanvas):
def __init__(self, parent, frame):
ogl.ShapeCanvas.__init__(self, parent)
self.frame = frame
self.diagram = ogl.Diagram()
self.SetDiagram(self.diagram)
self.diagram.SetCanvas(self)
self.shapes = []
# a couple of shapes
node1 = self.MyAddShape(ogl.CircleShape(80),
75, 110, wx.Pen(wx.BLUE, 3), wx.GREEN_BRUSH, "Node 1")
node2 = self.MyAddShape(ogl.CircleShape(80),
350, 110, wx.Pen(wx.BLUE, 3), wx.GREEN_BRUSH, "Node 2")
dc = wx.ClientDC(self)
self.PrepareDC(dc)
# now link them with a LineShape
line = ogl.LineShape()
line.SetCanvas(self)
line.MakeLineControlPoints(2)
node1.AddLine(line, node2)
if 1:
# add a label: this crashes with IndexError
line.AddText("Line Label")
self.diagram.AddShape(line)
node1.Move(dc, 75, 110) # it seems required w/ wx 2.4 at least to display the line
line.Show(True)
eh = MyEvtHandler(self.frame)
eh.SetShape(line)
eh.SetPreviousHandler(line.GetEventHandler())
line.SetEventHandler(eh)
def MyAddShape(self, shape, x, y, pen, brush, text):
shape.SetCanvas(self)
if x: shape.SetX(x)
if y: shape.SetY(y)
if pen: shape.SetPen(pen)
if brush: shape.SetBrush(brush)
if text: shape.AddText(text)
self.diagram.AddShape(shape)
shape.Show(True)
eh = MyEvtHandler(self.frame)
eh.SetShape(shape)
eh.SetPreviousHandler(shape.GetEventHandler())
shape.SetEventHandler(eh)
self.shapes.append(shape)
return shape
class CrashDemo(wx.App):
def __init__(self):
wx.App.__init__(self, redirect=False)
def OnInit(self):
frame = wx.Frame(None, -1, "wx Test", pos=(50,50), size=(200,100),
style=wx.DEFAULT_FRAME_STYLE)
frame.Show(True)
ogl.OGLInitialize()
win = TestWindow(frame, frame)
frame.SetSize((640,480))
win.SetFocus()
self.frame = frame
return True
def OnExitApp(self, evt):
self.frame.Close(True)
if __name__ == "__main__":
app = CrashDemo()
app.MainLoop()