UPDATED: SEE BELOW
I’ve been porting the code for this assignment: http://www.stanford.edu/class/cs221/progAssignments/PA1/search.html (the entire source code is available as zip from there)
from Python 2.x to 3.x. Note, porting is not the assignment, that’s just me trying to keep the code up to date and avoiding installing another version of Python…
After the usual 2.x -> 3.x syntax fixes (printing, exception raising, etc), and realizing that the module Tkinter is now known as tkinter in 3.x (lower-case), I’ve run into stranger problems, with this snippet and several others like it:
def keys_pressed(d_o_e=tkinter.tkinter.dooneevent,d_w=tkinter.tkinter.DONT_WAIT)
The errors are of the type:
AttributeError: 'module' object has no attribute 'tkinter'
Code completion in my IDE and the variable trace indeed seems to indicate that the tkinter module has no attribute or sub-class tkinter under which one might refer to dooneevent or DONT_WAIT. However, there are a few other references on the Internet of people using constructs like
_tkinter.dooneevent(_tkinter.DONT_WAIT)
to move the main loop ahead, but even referencing it like that still yields the same error.
Any ideas greatly appreciated.
UPDATE: Referring to the _root_window via lambda notation seems to work, as in it no longer complains pre-execution time in the majority of cases. To my untrained eye however, this is basically “magic”, and as such I have little idea what this subsequent error is saying or how to work around it. The method now looks like this, with my changes in the first line:
def move_to(object, x, y=None, d_o_e=lambda arg: _root_window(arg), d_w=tkinter._tkinter.DONT_WAIT):
if y is None:
try: x, y = x
except: raise 'incomprehensible coordinates'
horiz = True
newCoords = []
current_x, current_y = _canvas.coords(object)[0:2] # first point
for coord in _canvas.coords(object):
if horiz:
inc = x - current_x
else:
inc = y - current_y
horiz = not horiz
newCoords.append(coord + inc)
_canvas.coords(object, *newCoords)
d_o_e(d_w)
and the error I get is:
TypeError: 'Tk' object is not callable
referencing the line where the method is defined (first line above).
It appears
Tkinter.tkinterwas changed totkinter._tkinterin Python 3. Compare these docs from Python 2 with these from Python 3. Also,dooneeventis no longer intkinter._tkinter, but is still a member of theTk(akaroot) object.So change your code to
This takes advantage of the fact that in your linked code
_root_windowisglobal, so while_root_windowis not available when the class is defined, it will be available when the lambda is run.