【问题标题】:wxPython - lines drawn with Device Context disappear when focus changeswxPython - 当焦点改变时,用设备上下文绘制的线消失
【发布时间】:2011-01-19 04:47:55
【问题描述】:

我编写了这个小应用程序,它可以在用户选择的两点之间画线并且它可以工作,但是当窗口最小化或被另一个打开的窗口覆盖时,我如何防止我画的线消失?

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

【问题讨论】:

    标签: python wxpython


    【解决方案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()
    

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • “使窗口无效”是什么意思?
      • 在窗口 GUI 中,窗口系统会跟踪窗口的哪些部分正确绘制,哪些未正确绘制。当您的基础模型发生更改时,您不会直接在窗口中进行绘制。相反,您告诉窗口系统您不再正确绘制。这称为“使窗口无效”。然后它会向您发送绘制事件以重新绘制它。
      猜你喜欢
      • 2011-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-04
      • 2020-11-29
      • 1970-01-01
      • 1970-01-01
      • 2023-04-05
      相关资源
      最近更新 更多