wxPython - 焦点更改时,使用设备上下文绘制的线条消失

时间:2010-01-20 01:32:51

标签: python 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()

2 个答案:

答案 0 :(得分:1)

您的问题是,当用户点击时,您绘图。调整大小/擦除(当另一个窗口覆盖你的时候)问题是因为你的窗口没有维护一个可以重绘的“缓冲区”。

在这里,我修改了你的样本,似乎工作正常。

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

答案 1 :(得分:0)

您必须在GUI环境中以不同方式构建程序。通常,您维护一个称为模型的数据结构。在您的情况下,您已经有一个self.points的开头。然后你只在窗口上绘制以响应绘画事件。当窗口需要绘画时,窗口系统会向您发送绘画事件,包括首次显示时,最大化时以及从另一个窗口下方显示时。

在你的程序中,你将LeftDown事件绑定到一个修改self.points并使窗口无效的函数,这通常会导致窗口系统向你发送绘制事件。您将Paint事件绑定到绘制窗口的函数。