【问题标题】:wxpython - Draw a line with a dragging mousewxpython - 用鼠标拖动画一条线
【发布时间】:2014-03-08 02:48:28
【问题描述】:

正如标题所说,我尝试绘制一条由 2 个鼠标事件定义的线。线的起点应该是 onClick(),所以当鼠标左键被点击时,线的终点应该是 onRelease()。 我的基本想法是我将调用两个事件:一个用于单击鼠标左键时,第二个用于释放鼠标左键时。这应该模拟鼠标的“拖动”。我保存每个事件的坐标,在两个事件发生后,我想在保存的坐标之间画一条线。 这至少是我的基本想法...请注意:我是 wxpython 的新手,缺乏面向对象的知识,我现在正在尝试解决。

下面的代码出现以下错误:

Traceback (most recent call last):
  File "wxPaintingTest.py", line 49, in <module>
    frame = MyFrame()
  File "wxPaintingTest.py", line 20, in __init__
    self.paint(self.onClick.posx1, self.posy1, self.posx2, self.posy2)
AttributeError: 'function' object has no attribute 'posx1'

代码:

import wx

class MyFrame(wx.Frame):

    def __init__(self):
        wx.Frame.__init__(self, None, -1, 'draw line', (500, 500))
        panel = wx.Panel(self, -1)
        panel.Bind(wx.EVT_LEFT_DOWN, self.onClick)
        panel.Bind(wx.EVT_LEFT_UP, self.onRelease)
        wx.StaticText(panel, -1, "Pos:", pos=(10, 12))
        self.posClick = wx.TextCtrl(panel, -1, "", pos=(40, 10))
        self.posRelease = wx.TextCtrl(panel, -1, "", pos=(40, 10))
        self.paint(self.onClick.posx1, self.onClick.posy1,
                   self.onRelease.posx2, self.onRelease.posy2)

    def onClick(self, event):
        pos = event.GetPosition()
        self.posx1 = pos.x
        self.posy1 = pos.y
        self.posClick.SetValue("%s, %s" % (pos.x, pos.y))

    def onRelease(self, event):
        pos = event.GetPosition()
        self.posx2 = pos.x
        self.posy2 = pos.y
        self.posRelease.SetValue("%s, %s" % (pos.x, pos.y))

    def paint(self, pos1, pos2, pos3, pos4):
        dc = wx.PaintDC(self.panel)
        dc.SetPen(wx.Pen('blue', 4))
        dc.DrawLine(pos1, pos2, pos3, pos4)

if __name__ == '__main__':
    app = wx.App()
    frame = MyFrame()
    frame.Show(True)
    app.MainLoop()

为什么说函数没有属性?我就是不明白。

(有人可以说我的基本蓝图是否可行,还是它已经是错误的方法?)

最好的问候

【问题讨论】:

    标签: python events wxpython line draw


    【解决方案1】:

    在 init 调用中调用 paint() 时,您还没有定义 posx1!

    首先你想这样称呼它:

    self.paint(self.posx1, self.posy1, self.posx2, self.posy2)
    

    获取您在鼠标事件中设置的变量。其次,这些变量在调用paint() 和init 结束之前没有设置。因此,在调用paint() 之前将它们设置为某个值。

    posx1 = None
    posy1 = None
    posx2 = None
    posy2 = None
    
    self.paint(self.posx1, self.posy1, self.posx2, self.posy2)
    

    然后在绘画中确保你没有使用 None 值..

    def paint(self, pos1, pos2, pos3, pos4):
       if (pos1 is not None and pos2 is not None and 
           pos3 is not None and pos4 is not None):
            dc = wx.PaintDC(self.panel)
            dc.SetPen(wx.Pen('blue', 4))
            dc.DrawLine(pos1, pos2, pos3, pos4)
    

    第三,你不需要像那样传递成员变量。这样做:

    def paint(self):
       if (self.posx1 is not None and self.posy1 is not None and 
           self.posx2 is not None and self.posy2 is not None):
            dc = wx.PaintDC(self.panel)
            dc.SetPen(wx.Pen('blue', 4))
            dc.DrawLine(self.posx1, self.posy1, self.posx2, self.posy2)
    

    最后,强制paint() 调用自己并不是一个好主意。 wx 已经有一个“绘画”调用 OnPaint()。通常这样做的方式是:当 wxpython 准备好使用 OnPaint() 绘制到屏幕上并且你重载 OnPaint() 来做你想做的事情时,它会调用你。

    请参阅此示例:http://wiki.wxpython.org/VerySimpleDrawing

    祝你好运

    【讨论】:

      猜你喜欢
      • 2019-04-06
      • 2014-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-22
      • 1970-01-01
      • 2015-09-25
      • 1970-01-01
      相关资源
      最近更新 更多