问题描述
正如标题已经说过的,我尝试绘制一条由 2 个鼠标事件定义的线。 线的起点应该是 onClick(),所以当鼠标左键被点击时,线的终点应该是 onRelease()。 我的基本想法是我将调用两个事件:一个用于单击鼠标左键时,第二个用于释放鼠标左键时。 这应该模拟鼠标的“拖动”。 我保存了每个事件的坐标,在 2 个事件发生后,我想在保存的坐标之间画一条线。 这至少是我的基本想法......请注意:我是 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()
为什么说函数没有属性? 我只是不明白。
(有人可以说我的基本蓝图是否可行,还是已经是错误的方法?)
此致
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 已经有一个“paint”调用了 OnPaint()。 通常这样做的方法是:当 wxpython 准备好使用 OnPaint() 绘制到屏幕并且您重载 OnPaint() 以执行您想要的操作时,它会调用您。
请参阅此示例: :
祝你好运