2012-08-02 52 views
0

我正在使用下面的類來添加橡皮筋。但是,每次我創建橡皮筋(左鍵單擊)時,都會出現閃爍/閃爍。我不知道爲什麼會發生這種情況。另外,我將橡皮筋放在ScrolledWindow中。DC閃爍,wxPython

import wx 
class wxPyRubberBander: 
    """ A class to manage mouse events/ rubberbanding of a wx.Python 
     canvas object """ 

    def __init__(self, canvas): 

     # canvas object 
     self._canvas = canvas 
     # mouse selection start point 
     self.m_stpoint=wx.Point(0,0) 
     # mouse selection end point 
     self.m_endpoint=wx.Point(0,0) 
     # mouse selection cache point 
     self.m_savepoint=wx.Point(0,0) 

     # flags for left click/ selection 
     self._leftclicked=False 
     self._selected=False 

     # Register event handlers for mouse 
     self.RegisterEventHandlers() 

    def RegisterEventHandlers(self): 
     """ Register event handlers for this object """ 

     wx.EVT_LEFT_DOWN(self._canvas, self.OnMouseEvent) 
     wx.EVT_LEFT_UP(self._canvas, self.OnMouseEvent) 
     wx.EVT_MOTION(self._canvas, self.OnMouseEvent) 


    def OnMouseEvent(self, event): 
     """ This function manages mouse events """ 


     if event: 

      # set mouse cursor 
      # get device context of canvas 
      dc= wx.ClientDC(self._canvas) 
      # Set logical function to XOR for rubberbanding 
      dc.SetLogicalFunction(wx.XOR) 

      # Set dc brush and pen 
      # Here I set brush and pen to white and grey respectively 
      # You can set it to your own choices 

      # The brush setting is not really needed since we 
      # dont do any filling of the dc. It is set just for 
      # the sake of completion. 

      wbrush = wx.Brush(wx.Colour(255,255,255), wx.TRANSPARENT) 
      wpen = wx.Pen(wx.Colour(200, 200, 200), 1, wx.SOLID) 
      dc.SetBrush(wbrush) 
      dc.SetPen(wpen) 


     if event.LeftDown(): 

      # Left mouse button down, change cursor to 
      # something else to denote event capture 
      self.m_stpoint = event.GetPosition() 

      # invalidate current canvas 
      self._canvas.Refresh() 
      # cache current position 
      self.m_savepoint = self.m_stpoint 
      self._selected = False 
      self._leftclicked = True 

     elif event.Dragging(): 

      # User is dragging the mouse, check if 
      # left button is down 

      if self._leftclicked: 

       # reset dc bounding box 
       dc.ResetBoundingBox() 
       dc.BeginDrawing() 
       w = (self.m_savepoint.x - self.m_stpoint.x) 
       h = (self.m_savepoint.y - self.m_stpoint.y) 

       # To erase previous rectangle 
       dc.DrawRectangle(self.m_stpoint.x, self.m_stpoint.y, w, h) 

       # Draw new rectangle 
       self.m_endpoint = event.GetPosition() 

       w = (self.m_endpoint.x - self.m_stpoint.x) 
       h = (self.m_endpoint.y - self.m_stpoint.y) 

       # Set clipping region to rectangle corners 
       dc.SetClippingRegion(self.m_stpoint.x, self.m_stpoint.y, w,h) 
       dc.DrawRectangle(self.m_stpoint.x, self.m_stpoint.y, w, h) 
       dc.EndDrawing() 

       self.m_savepoint = self.m_endpoint # cache current endpoint 

     elif event.LeftUp(): 

      # User released left button, change cursor back 
      self._selected = True #selection is done 
      self._leftclicked = False # end of clicking 


    def GetCurrentSelection(self): 
     """ Return the current selected rectangle """ 

     # if there is no selection, selection defaults to 
     # current viewport 

     left = wx.Point(0,0) 
     right = wx.Point(0,0) 

     # user dragged mouse to right 
     if self.m_endpoint.y > self.m_stpoint.y: 
      right = self.m_endpoint 
      left = self.m_stpoint 
     # user dragged mouse to left 
     elif self.m_endpoint.y < self.m_stpoint.y: 
      right = self.m_stpoint 
      left = self.m_endpoint 

     return (left.x, left.y, right.x, right.y) 


    def ClearCurrentSelection(self): 
     """ Clear the current selected rectangle """ 

     box = self.GetCurrentSelection() 

     dc=wx.ClientDC(self._canvas) 

     w = box[2] - box[0] 
     h = box[3] - box[1] 
     dc.SetClippingRegion(box[0], box[1], w, h) 
     dc.SetLogicalFunction(wx.XOR) 

     # The brush is not really needed since we 
     # dont do any filling of the dc. It is set for 
     # sake of completion. 

     wbrush = wx.Brush(wx.Colour(255,255,255), wx.TRANSPARENT) 
     wpen = wx.Pen(wx.Colour(200, 200, 200), 1, wx.SOLID) 
     dc.SetBrush(wbrush) 
     dc.SetPen(wpen) 
     dc.DrawRectangle(box[0], box[1], w,h) 
     self._selected = False 

     # reset selection to canvas size 
     self.ResetSelection()  

    def ResetSelection(self): 
     """ Resets the mouse selection to entire canvas """ 

     self.m_stpoint = wx.Point(0,0) 
     sz=self._canvas.GetSize() 
     w,h=sz.GetWidth(), sz.GetHeight() 
     self.m_endpoint = wx.Point(w,h) 
+0

試圖尋找到doublebuffering – 2012-08-02 14:49:50

+0

是的,我試過,但我遇到的問題使用DB,可以提供我怎麼能解決這個問題的例子嗎?它在創建時只會閃爍。 – user1513192 2012-08-02 15:40:29

+1

可能更容易(和可能的工作),以冷藏起來... – 2012-08-02 15:46:58

回答

1

也許凍結它的工作

def OnMouseEvent(self, event): 
    """ This function manages mouse events """ 
    if not self._canvas.IsFrozen(): #prevent multiple freezes 
     self._canvas.Freeze() #freeze it from updates 
    if event: 

     # set mouse cursor 
     # get device context of canvas 
     dc= wx.ClientDC(self._canvas) 
     # Set logical function to XOR for rubberbanding 
     dc.SetLogicalFunction(wx.XOR) 

     # Set dc brush and pen 
     # Here I set brush and pen to white and grey respectively 
     # You can set it to your own choices 

     # The brush setting is not really needed since we 
     # dont do any filling of the dc. It is set just for 
     # the sake of completion. 

     wbrush = wx.Brush(wx.Colour(255,255,255), wx.TRANSPARENT) 
     wpen = wx.Pen(wx.Colour(200, 200, 200), 1, wx.SOLID) 
     dc.SetBrush(wbrush) 
     dc.SetPen(wpen) 


    if event.LeftDown(): 

     # Left mouse button down, change cursor to 
     # something else to denote event capture 
     self.m_stpoint = event.GetPosition() 

     # invalidate current canvas 
     self._canvas.Refresh() 
     # cache current position 
     self.m_savepoint = self.m_stpoint 
     self._selected = False 
     self._leftclicked = True 

    elif event.Dragging(): 

     # User is dragging the mouse, check if 
     # left button is down 

     if self._leftclicked: 

      # reset dc bounding box 
      dc.ResetBoundingBox() 
      dc.BeginDrawing() 
      w = (self.m_savepoint.x - self.m_stpoint.x) 
      h = (self.m_savepoint.y - self.m_stpoint.y) 

      # To erase previous rectangle 
      dc.DrawRectangle(self.m_stpoint.x, self.m_stpoint.y, w, h) 

      # Draw new rectangle 
      self.m_endpoint = event.GetPosition() 

      w = (self.m_endpoint.x - self.m_stpoint.x) 
      h = (self.m_endpoint.y - self.m_stpoint.y) 

      # Set clipping region to rectangle corners 
      dc.SetClippingRegion(self.m_stpoint.x, self.m_stpoint.y, w,h) 
      dc.DrawRectangle(self.m_stpoint.x, self.m_stpoint.y, w, h) 
      dc.EndDrawing() 

      self.m_savepoint = self.m_endpoint # cache current endpoint 

    elif event.LeftUp(): 

     # User released left button, change cursor back 
     self._selected = True #selection is done 
     self._leftclicked = False # end of clicking 
    if self._canvas.IsFrozen(): #prevent multiple thaws 
     self._canvas.Thaw() #thaw it so it updates 
+0

感謝您的答覆,但現在它甚至更糟,它閃爍每次我把鼠標移動(wx.EVT_MOTION) – user1513192 2012-08-02 15:50:53

+0

我不知道我只是測試你的代碼,我得到閃爍的全部時間,我拖......但不能點擊... – 2012-08-02 16:10:05

+1

好NVM,我只是找到了一個很好的例子,http://www.ida.liu.se/~ETE257/timetable/LectureWxPython.html,工像一個魅力!,雙緩衝是解決方案。現在,即使我刷新,也不會閃爍! – user1513192 2012-08-02 16:42:39