简体   繁体   中英

wxpython - Draw a line with a dragging mouse

As the title already says I try to draw a line which is defined by 2 mouse events. The start point of the line should be onClick() so when the left mouse button gets clicked and the end point of the line should be onRelease(). My basic idea was that I will call two events: One for when the left mouse button is clicked and the second for when the left mouse button is released. This should simulate the "dragging" of the mouse. I save the coordinates for each event and after the 2 events happened I want to draw a line between the saved coordinates. Thats a least my basic idea... PLEASE NOTE: I'm new to wxpython and have a lack of object orientated knowledge which I'm trying to fix right now.

I get the following error for my code below:

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'

Code:

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

Why does it say that the function has not the attribute? I just don't get it.

(Can someone say if my basic blueprint will work out or is it already a wrong approach?)

Best regards

You haven't defined posx1 when you call paint() in the init call!!

First up you want to call it like this:

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

To get the variables that you are setting in the mouse events. Secondly those variables are not set anywhere before the call to paint() and the end of the init. So set them to something before you call paint().

posx1 = None
posy1 = None
posx2 = None
posy2 = None

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

Then in paint make sure you're not using the None values..

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)

Thirdly, you don't need to pass member variables around like that.. Do it like this:

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)

Finally, it's not a great idea to force the paint() call yourself. wx has a "paint" call already OnPaint(). The way this is usually done is: wxpython will call you when it's ready to draw to the screen using OnPaint() and you overload OnPaint() to do what you want.

See this example: http://wiki.wxpython.org/VerySimpleDrawing

good luck

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM