wxpython 中wxOGL的使用 第二篇
2013-04-11 17:44
369 查看
# -*- coding: iso-8859-1 -*- # 11/20/2003 - Jeff Grimmett (grimmtooth@softhome.net) # # o Updated for wx namespace # # 20040508 - Pierre Hjälm # # o Changed to use the python version of OGL # o Added TextShape, CompositeShape and CompositeShape with divisions # # 20040830 - Pierre Hjälm # # o Added DrawnShape # import wx import wx.lib.ogl as ogl import images #前面的以***Shape为类名的类,均为自定义图形,可以先不具体了解。 #---------------------------------------------------------------------- class DrawnShape(ogl.DrawnShape): def __init__(self): ogl.DrawnShape.__init__(self) self.SetDrawnBrush(wx.WHITE_BRUSH) self.SetDrawnPen(wx.BLACK_PEN) self.DrawArc((0, -10), (30, 0), (-30, 0)) self.SetDrawnPen(wx.Pen("#ff8030")) self.DrawLine((-30, 5), (30, 5)) self.SetDrawnPen(wx.Pen("#00ee10")) self.DrawRoundedRectangle((-20, 10, 40, 10), 5) self.SetDrawnPen(wx.Pen("#9090f0")) self.DrawEllipse((-30, 25, 60, 20)) self.SetDrawnTextColour(wx.BLACK) self.SetDrawnFont(wx.Font(8, wx.SWISS, wx.NORMAL, wx.NORMAL)) self.DrawText("DrawText", (-26, 28)) self.SetDrawnBrush(wx.GREEN_BRUSH) self.DrawPolygon([(-100, 5), (-45, 30), (-35, 20), (-30, 5)]) self.SetDrawnPen(wx.BLACK_PEN) self.DrawLines([(30, -45), (40, -45), (40 ,45), (30, 45)]) # Make sure to call CalculateSize when all drawing is done self.CalculateSize() #---------------------------------------------------------------------- class DiamondShape(ogl.PolygonShape): def __init__(self, w=0.0, h=0.0): ogl.PolygonShape.__init__(self) if w == 0.0: w = 60.0 if h == 0.0: h = 60.0 points = [ (0.0, -h/2.0), (w/2.0, 0.0), (0.0, h/2.0), (-w/2.0, 0.0), ] self.Create(points) #---------------------------------------------------------------------- class RoundedRectangleShape(ogl.RectangleShape): def __init__(self, w=0.0, h=0.0): ogl.RectangleShape.__init__(self, w, h) self.SetCornerRadius(-0.3) #---------------------------------------------------------------------- class CompositeDivisionShape(ogl.CompositeShape): def __init__(self, canvas): ogl.CompositeShape.__init__(self) self.SetCanvas(canvas) # create a division in the composite self.MakeContainer() # add a shape to the original division shape2 = ogl.RectangleShape(40, 60) self.GetDivisions()[0].AddChild(shape2) # now divide the division so we get 2 self.GetDivisions()[0].Divide(wx.HORIZONTAL) # and add a shape to the second division (and move it to the # centre of the division) shape3 = ogl.CircleShape(40) shape3.SetBrush(wx.CYAN_BRUSH) self.GetDivisions()[1].AddChild(shape3) shape3.SetX(self.GetDivisions()[1].GetX()) for division in self.GetDivisions(): division.SetSensitivityFilter(0) #---------------------------------------------------------------------- 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 DividedShape(ogl.DividedShape): def __init__(self, width, height, canvas): ogl.DividedShape.__init__(self, width, height) region1 = ogl.ShapeRegion() region1.SetText('DividedShape') region1.SetProportions(0.0, 0.2) region1.SetFormatMode(ogl.FORMAT_CENTRE_HORIZ) self.AddRegion(region1) region2 = ogl.ShapeRegion() region2.SetText('This is Region number two.') region2.SetProportions(0.0, 0.3) region2.SetFormatMode(ogl.FORMAT_CENTRE_HORIZ|ogl.FORMAT_CENTRE_VERT) self.AddRegion(region2) region3 = ogl.ShapeRegion() region3.SetText('Region 3\nwith embedded\nline breaks') region3.SetProportions(0.0, 0.5) region3.SetFormatMode(ogl.FORMAT_NONE) self.AddRegion(region3) self.SetRegionSizes() self.ReformatRegions(canvas) def ReformatRegions(self, canvas=None): rnum = 0 if canvas is None: canvas = self.GetCanvas() dc = wx.ClientDC(canvas) # used for measuring for region in self.GetRegions(): text = region.GetText() self.FormatText(dc, text, rnum) rnum += 1 def OnSizingEndDragLeft(self, pt, x, y, keys, attch): print "***", self ogl.DividedShape.OnSizingEndDragLeft(self, pt, x, y, keys, attch) self.SetRegionSizes() self.ReformatRegions() self.GetCanvas().Refresh() #---------------------------------------------------------------------- #此处为继承自shapeevthandler的处理器 class MyEvtHandler(ogl.ShapeEvtHandler): def __init__(self, log, frame): ogl.ShapeEvtHandler.__init__(self) self.log = log self.statbarFrame = frame #这里是给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)) #这里是给frame的状态栏添加东东,可以忽略不计 def OnLeftClick(self, x, y, keys=0, attachment=0): shape = self.GetShape() canvas = shape.GetCanvas() dc = wx.ClientDC(canvas) canvas.PrepareDC(dc) #以上是准备时间处理需要的对象,shape是绑定到的对象。canvas是shape所在的画布对象。DC是一个画刷。 if shape.Selected(): shape.Select(False, dc) #canvas.Redraw(dc) canvas.Refresh(True)#这里的语义是,如果当前shape已经被选中的话,就把选中的标记取消,并重新刷新页面。 else: redraw = False shapeList = canvas.GetDiagram().GetShapeList() toUnselect = [] #未选中的时候,将先前选中的Shape定义为未选中状态,并将当前shape选中。 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) canvas.Refresh(True) #刷界面。 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): shape = self.GetShape() ogl.ShapeEvtHandler.OnMovePost(self, dc, x, y, oldX, oldY, display) self.UpdateStatusBar(shape) if "wxMac" in wx.PlatformInfo: shape.GetCanvas().Refresh(False) def OnRightClick(self, *dontcare): self.log.WriteText("%s\n" % self.GetShape()) #---------------------------------------------------------------------- class TestWindow(ogl.ShapeCanvas): def __init__(self, parent, log, frame): ogl.ShapeCanvas.__init__(self, parent) maxWidth = 1000 maxHeight = 1000 self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) self.log = log self.frame = frame self.SetBackgroundColour("LIGHT BLUE") #wx.WHITE) self.diagram = ogl.Diagram() self.SetDiagram(self.diagram) self.diagram.SetCanvas(self) self.shapes = [] self.save_gdi = [] rRectBrush = wx.Brush("MEDIUM TURQUOISE", wx.SOLID) dsBrush = wx.Brush("WHEAT", wx.SOLID) self.MyAddShape( CompositeDivisionShape(self), 270, 310, wx.BLACK_PEN, wx.BLUE_BRUSH, "Division" ) self.MyAddShape( CompositeShape(self), 100, 260, wx.BLACK_PEN, wx.RED_BRUSH, "Composite" ) self.MyAddShape( ogl.CircleShape(80), 75, 110, wx.Pen(wx.BLUE, 3), wx.GREEN_BRUSH, "Circle" ) self.MyAddShape( ogl.TextShape(120, 45), 160, 35, wx.GREEN_PEN, wx.LIGHT_GREY_BRUSH, "OGL is now a\npure Python lib!" ) self.MyAddShape( ogl.RectangleShape(85, 50), 305, 60, wx.BLACK_PEN, wx.LIGHT_GREY_BRUSH, "Rectangle" ) self.MyAddShape( DrawnShape(), 500, 80, wx.BLACK_PEN, wx.BLACK_BRUSH, "DrawnShape" ) ds = self.MyAddShape( DividedShape(140, 150, self), 520, 265, wx.BLACK_PEN, dsBrush, '' ) self.MyAddShape( DiamondShape(90, 90), 355, 260, wx.Pen(wx.BLUE, 3, wx.DOT), wx.RED_BRUSH, "Polygon" ) self.MyAddShape( RoundedRectangleShape(95, 70), 345, 145, wx.Pen(wx.RED, 2), rRectBrush, "Rounded Rect" ) bmp = images.getTest2Bitmap() mask = wx.Mask(bmp, wx.BLUE) bmp.SetMask(mask) s = ogl.BitmapShape() s.SetBitmap(bmp) self.MyAddShape(s, 225, 130, None, None, "Bitmap") #dc = wx.ClientDC(self) #self.PrepareDC(dc) for x in range(len(self.shapes)): fromShape = self.shapes[x] if x+1 == len(self.shapes): toShape = self.shapes[0] else: toShape = self.shapes[x+1] line = ogl.LineShape() line.SetCanvas(self) line.SetPen(wx.BLACK_PEN) line.SetBrush(wx.BLACK_BRUSH) line.AddArrow(ogl.ARROW_ARROW) line.MakeLineControlPoints(2) fromShape.AddLine(line, toShape) self.diagram.AddShape(line) line.Show(True) 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.log, self.frame) evthandler.SetShape(shape) evthandler.SetPreviousHandler(shape.GetEventHandler()) shape.SetEventHandler(evthandler) self.shapes.append(shape) return shape def OnBeginDragLeft(self, x, y, keys): self.log.write("OnBeginDragLeft: %s, %s, %s\n" % (x, y, keys)) def OnEndDragLeft(self, x, y, keys): self.log.write("OnEndDragLeft: %s, %s, %s\n" % (x, y, keys)) #---------------------------------------------------------------------- def runTest(frame, nb, log): # This creates some pens and brushes that the OGL library uses. # It should be called after the app object has been created, but # before OGL is used. ogl.OGLInitialize() win = TestWindow(nb, log, frame) return win #---------------------------------------------------------------------- if __name__ == '__main__': import sys, os import run run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
这是我总结OGL库使用方法的第二篇,主要来写一下如何实现一些普通的事件响应函数。
在OGL中,可以为每个Shape绑定一个事件的相应对象,默认的相应方式为,拖动shape。
http://biolpc22.york.ac.uk/wx/contrib/docs/html/ogl/ogl23.htm#wxshapeevthandler
此传送门中记录了所有handler的函数,单击之后就将会显示此函数的主要作用是什么。当然,也可以为整个面板绑定一些普通的事件响应函数,比如EVT_MOVE等等。
如果想要两种响应方式均对界面有所影响的话,使用event.skip()函数吧,很有用处。
值得说明的是,当shape之间需要绘制箭头,或者连线的时候,为整个面板或者画布制定响应函数就显得很重要了。
shape.SetEventHandler(somehandler)函数为绑定函数,为此shape绑定继承于ogl.shapeEvtHandler的函数。
接下来介绍实例中的相应过程。(标记于注释)
相关文章推荐
- wxpython 中wxOGL的使用 第三篇
- wxpython 中wxOGL的使用 第一篇
- 数字证书KeyTool使用(第二篇)
- android rxjava入门第二篇操作符的使用
- 第二篇: 在虚拟主机上使用ASP.NET Ajax
- wxPython中使用剪贴板存取文本数据
- Linux下Tomcat的使用与常见配置(CentOS7)-----Linux第二篇
- Python使用wxPython、py2exe编写桌面程序
- Python使用wxPython、py2exe编写桌面程序
- C++异常第二篇---C++标准库异常类exception的使用
- memcached 第二篇----安装使用
- 提高第二篇之SurfaceView的基本使用
- beta 的第二篇心得:在 case 语句中使用字符串
- git config命令使用第二篇——section操作,多个key值操作,使用正则
- wxPython:面板Panel的使用
- Windows中使用wxPython和py2exe开发Python的GUI程序的实例教程
- Android提高第二篇之SurfaceView的基本使用
- 第二篇:Retrofit调用流程图和使用到的设计模式
- wxPython学习]使用PubSub机制来更新视图
- Maven第二篇【Idea下使用Maven】