[Tutor] tkinter events: <B1-Motion>
Zsiros Levente
zslevi at sch.bme.hu
Tue Aug 22 12:16:22 CEST 2006
Zsiros Levente wrote:
>Luke Paireepinart wrote:
>
>
>
>>Zsiros Levente wrote:
>>
>>
>>
>>>[snip code]
>>>*def* handler(event):
>>> *if* buttonpressed == 1 :
>>> /#if the mousebutton is pressed and moved, circles should
>>>appear, but they do not/
>>> can.create_oval(event.x-r, event.y-r, event.x+r, event.y+r,
>>>fill="orange")
>>> lab.config(text='buttonpressed=' + str(buttonpressed) )
>>>
>>>*def* press(event):
>>> buttonpressed=1
>>> lab2.config(text=buttonpressed)
>>>
>>>*def* release(event):
>>> buttonpressed=0
>>> lab2.config(text=buttonpressed)
>>>[snip code]
>>>/#global buttonpressed/
>>>buttonpressed=0
>>>
>>>
>>I think you're misunderstanding what global variables are.
>>
>>
>>
>Yes, others already mentioned that.
>
>
You didn't notice that, because first I accidentally sent the code to
other thread (self-modification; of which I have three already :-X )
>
>
>>Take the following example:
>>
>>#--- code
>>a = 0
>>def b():
>> print a
>>b()
>>
>>#--- output
>>0
>>#---
>>the function 'b' can see the variable 'a'. ok so far.
>>
>>now take this example.
>>
>>#--- code
>>a = 0
>>def b():
>> a = 1
>> print a
>>b()
>>print a
>>
>>#--- output
>>1
>>0
>>#---
>>in this case, 'a' is assigned to, but it's a local variable called 'a'
>>and not the one I think you expect it to assign to.
>>so after 'b' is done the value of the 'a' outside of the scope of the
>>function is still 0.
>>in your press and release events you assign values to 'buttonpressed'
>>before you use them,
>>and because of this, the same thing happens as in our second example:
>>a local variable named
>>'buttonpressed' is created with the value 0 or 1 assigned to it
>>(depending on the function you're in.)
>>that works fine, and it sets the label's text value accordingly. But,
>>since it's a local variable and the
>>functions aren't actually modifying the global 'buttonpressed', the
>>'buttonpressed' that you're checking for
>>in your 'handler' function is always going to be 0. That's why your
>>oval code is never drawn.
>>
>>Rather than messing with global variables, which are for the most part
>>evil creatures,
>>as we've witnessed so far here, I'd recommend using a class.
>>I wrote the class I would use for you so you can see it.
>>It's commented, but if you need any more help than the comments feel
>>free to write me back.
>>Just be sure to use the reply-all button so the whole list can see the
>>response.
>>-Luke
>>(note: code attached)
>>
>>------------------------------------------------------------------------
>>
>>#!/usr/bin/python
>>
>># This program implements <B1-motion>. it was originally written by
>>#Zsiros Levente. all rights of this modified version go to him :)
>>
>>
>>
>>from Tkinter import *
>
>
>>class ButtonHandler(object):
>> def __init__(self):
>> #our self.mousedown variable is what we'll use to check the state
>> #of the button, since we're going to be passing a copy of 'self'
>> #around, we don't have to deal with scoping of the variables.
>> #I.E. self.mousedown is global to functions in the class
>> #that accept a 'self' argument.
>> self.mousedown = 0
>>
>> #we make the window normally. note all these are 'self' variables
>> #so we can change them easily elsewhere in the class.
>> self.root = Tk()
>> self.root.geometry('600x500+200+200')
>> self.label = Label(self.root, text=str(self.mousedown))
>> self.can = Canvas(self.root, width='500', height='400', bg='white')
>> #lambda is a way we can add extra arguments to a function.
>> #since the callback of bound events is only a single argument,
>> #we use 'lambda x' to get the 'event' instance, and pass it
>> #along with another string identifying which event it came from.
>> #this may or may not be necessary, but it's cool and it
>> #makes the handler function make more sense.
>> #also, we only need one handler function this way.
>> self.can.bind("<Motion>",lambda x:self.handler(x,'motion'))
>> self.can.bind("<Button-1>",lambda x:self.handler(x,'press'))
>> self.can.bind("<ButtonRelease-1>",lambda x:self.handler(x,'release'))
>> self.label.pack()
>> self.can.pack()
>> self.root.mainloop()
>>
>> def handler(self,event,x):
>> #the first two clauses of the if-elif branch implement your
>> #'press' and 'release' functions.
>> if x == 'press':
>> self.mousedown = 1
>> elif x == 'release':
>> self.mousedown = 0
>> elif x == 'motion':
>> if self.mousedown:
>> #you could do something really cool here, like store the time
>> #that the button was last pressed, and increase the radius of the circle
>> #depending on how long it's been since then.
>> r = 5
>> self.can.create_oval(event.x-r, event.y-r, event.x+r, event.y+r, fill="orange")
>> self.label.config(text=str(self.mousedown))
>>
>>
>>#we create an instance of the class which automatically
>>#calls the '__init__' method.
>>x = ButtonHandler()
>>
>>
>>
>>
>
>_______________________________________________
>Tutor maillist - Tutor at python.org
>http://mail.python.org/mailman/listinfo/tutor
>
>
More information about the Tutor
mailing list