DC有问题。我试图制作一个可以在屏幕上画很多线并且需要真正快速更新的应用程序,并且由于我不想闪烁,所以我决定尝试一下缓冲的DC。但是,当我运行这段代码时,它什么也没画。我究竟做错了什么?

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()

最佳答案

我使用了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()


基本方法是:


创建用于屏幕外绘图的内存DC
如果调整了窗口的大小,请调整内存dc的大小并重新绘制
当发生绘画事件时,只需将内存dc涂抹到绘画dc上
对擦除背景事件不执行任何操作以避免闪烁
仅当您确实需要更改屏幕上的内容时,才调用重绘


如果存储对在on_size中创建的EmptyBitmap的引用,则甚至可以使用wxBitmap.SaveFile()将窗口内容保存到图像文件中。

关于python - 无法获得wx.BufferedDC绘制任何内容,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2173821/

10-12 16:46
查看更多