2010-01-31 1 views
1

У меня проблема с DC. Я пытаюсь сделать приложение, которое будет рисовать много строк на экранах и должно обновляться очень быстро, и, поскольку я не хочу мерцать, я решил дать буферизованный dcs выстрел. Но когда я запускаю этот код, он ничего не рисует. Что я делаю не так?Не могу получить wx.BufferedDC нарисовать что-нибудь

import wx 

class MainFrame(wx.Frame): 
    def __init__(self): 
     screensize = wx.GetDisplaySize() 
     self.framesize = (screensize[0]/4*3, screensize[1]/4*3) 
     wx.Frame.__init__(self, None, -1, "CursorTracker", size=self.framesize, 
          style=wx.SYSTEM_MENU| 
          wx.CAPTION| 
          wx.CLOSE_BOX| 
          wx.MINIMIZE_BOX) 
     self.dc = wx.ClientDC(self) 
     self.bdc = wx.BufferedDC(self.dc) 
     self.SetBackgroundColour(wx.WHITE) 
     self.Timer = wx.Timer(self) 
     self.Bind(wx.EVT_TIMER, self.OnTimer) 
     self.Timer.Start(100) 

    def OnTimer(self, event): 

     self.bdc.DrawLine(1,1,100,100) 


class App(wx.App): 
    def OnInit(self): 
     frame = MainFrame() 
     frame.Show() 
     return True 

app = App(redirect=False) 
app.MainLoop() 

ответ

3

I «ве использовали AutoBufferedPaintDC, но я нашел делает свою собственную двойную буферизацию с MemoryDC быть более гибким Вот шаблон для вас

import wx 

class Frame(wx.Frame): 
    def __init__(self): 
     super(Frame, self).__init__(None, -1, 'CursorTracker') 
     self.mdc = None # memory dc to draw off-screen 
     self.Bind(wx.EVT_SIZE, self.on_size) 
     self.Bind(wx.EVT_ERASE_BACKGROUND, self.on_erase) 
     self.Bind(wx.EVT_PAINT, self.on_paint) 
     w, h = wx.GetDisplaySize() 
     w, h = w * 3/4, h * 3/4 
     self.SetSize((w, h)) 
     self.Center() 
     self.on_timer() 
    def on_size(self, event): 
     # re-create memory dc to fill window 
     w, h = self.GetClientSize() 
     self.mdc = wx.MemoryDC(wx.EmptyBitmap(w, h)) 
     self.redraw() 
    def on_erase(self, event): 
     pass # don't do any erasing to avoid flicker 
    def on_paint(self, event): 
     # just blit the memory dc 
     dc = wx.PaintDC(self) 
     if not self.mdc: 
      return 
     w, h = self.mdc.GetSize() 
     dc.Blit(0, 0, w, h, self.mdc, 0, 0) 
    def on_timer(self): 
     # refresh every N milliseconds 
     self.redraw() 
     wx.CallLater(100, self.on_timer) 
    def redraw(self): 
     # do the actual drawing on the memory dc here 
     dc = self.mdc 
     w, h = dc.GetSize() 
     dc.Clear() 
     dc.DrawLine(0, 0, w, h) 
     self.Refresh() 

if __name__ == '__main__': 
    app = wx.PySimpleApp() 
    frame = Frame() 
    frame.Show() 
    app.MainLoop() 

основной подход:..

  • создать memory dc для занавесного чертежа
  • , если при изменении размера окна, изменить размер постоянного тока памяти и перерисовывать
  • , когда происходит событие краски, просто блитирования на постоянном токе памяти на краску постоянного
  • ничего не делать на Стирание фоне события, чтобы избежать мерцания экрана
  • вызова перерисовки тогда и только тогда, когда вы на самом деле нужно изменить то, что на экране

Если вы сохраните ссылку на эту EmptyBitmap, который создан в on_size, вы даже можете сохранить содержимое окна в файл изображения с wxBitmap.SaveFile()

1

BufferedDC копируется на экран только тогда, когда объект уничтожается. Так как вы никогда не уничтожаете self.bdc, его содержимое никогда не будет скопировано на экран. Итак, вам нужно уйти от self.bdc (возможно, просто замените его новым экземпляром BufferedDc: т. Е. Повторите задание self.bdc = wc.BufferedDc(self.dc) в «стратегические» моменты времени, когда вы хотите визуализировать чертеж.