2010-01-20 29 views
1

我已經寫了這個小應用程序,吸引用戶選擇的兩點之間的線,它的工作原理,但我怎麼養我繪製線條從每當窗口最小化後消失或被另一個打開的窗口覆蓋?wxPython的 - 與設備上下文繪製線條消失在焦點更改

class SimpleDraw(wx.Frame): 
    def __init__(self, parent, id, title, size=(640, 480)): 
    self.points = [] 
    wx.Frame.__init__(self, parent, id, title, size) 

    self.Bind(wx.EVT_LEFT_DOWN, self.DrawDot) 

    self.SetBackgroundColour("WHITE") 
    self.Centre() 
    self.Show(True) 

    def DrawDot(self, event): 
    self.points.append(event.GetPosition()) 
    if len(self.points) == 2: 
     dc = wx.ClientDC(self) 
     dc.SetPen(wx.Pen("#000000", 10, wx.SOLID)) 
     x1, y1 = self.points[0] 
     x2, y2 = self.points[1] 
     dc.DrawLine(x1, y1, x2, y2) 
     # reset the list to empty 
     self.points = [] 

if __name__ == "__main__": 
    app = wx.App() 
    SimpleDraw(None, -1, "Title Here!") 
    app.MainLoop() 

回答

0

你必須在GUI環境中不同的構建程序。通常,您維護一個稱爲模型的數據結構。在你的情況下,你已經有一個開始,self.points。然後,您只需在窗口上繪製以響應繪畫事件。窗口系統將發送你畫的事件,當窗口需要繪製,當它第一次顯示,當包括最大化,並且當它從另一個窗口下方顯示。

在你的程序中,你會將LeftDown事件綁定到修改self.points並使窗口無效的函數,這通常會導致窗口系統向你發送繪畫事件。您將Paint事件綁定到在窗口上繪製的函數。

+0

你是什麼意思「使窗口無效」? – cornjuliox 2010-01-20 08:19:32

+1

在窗口化的GUI中,窗口系統會跟蹤窗口的哪些部分被正確繪製,哪些不是。當底層模型發生變化時,您不會直接在窗口中繪製。相反,您告訴窗口系統您不再正確繪製。這被稱爲「使窗口無效」。然後它會發送給您繪畫事件以重新繪製它。 – 2010-01-20 11:59:56

0

您的問題是,你是只有繪圖時用戶點擊。調整大小/擦除(當另一個窗口覆蓋你的問題時)是因爲你的窗口沒有保存一個可以重繪的「緩衝區」。

在這裏,我已經修改了你的樣品,它似乎是工作好。

import wx 

class SimpleDraw(wx.Frame): 
    def __init__(self, parent, id, title, size=(640, 480)): 
     self.points = [] 
     wx.Frame.__init__(self, parent, id, title, size) 

     self.Bind(wx.EVT_LEFT_DOWN, self.DrawDot) 
     self.Bind(wx.EVT_PAINT, self.Paint) 

     self.SetBackgroundColour("WHITE") 
     self.Centre() 
     self.Show(True) 
     self.buffer = wx.EmptyBitmap(640, 480) # draw to this 
     dc = wx.BufferedDC(wx.ClientDC(self), self.buffer) 
     dc.Clear() # black window otherwise 


    def DrawDot(self, event): 
     self.points.append(event.GetPosition()) 
     if len(self.points) == 2: 
      dc = wx.BufferedDC(wx.ClientDC(self), self.buffer) 
      dc.Clear() 
      dc.SetPen(wx.Pen("#000000", 10, wx.SOLID)) 
      x1, y1 = self.points[0] 
      x2, y2 = self.points[1] 
      dc.DrawLine(x1, y1, x2, y2) 
      # reset the list to empty 
      self.points = [] 


    def Paint(self, event): 
     wx.BufferedPaintDC(self, self.buffer) 


if __name__ == "__main__": 
    app = wx.App(0) 
    SimpleDraw(None, -1, "Title Here!") 
    app.MainLoop()