Python tkinter在将2.x代码移植到3.x和#x27;特金特';模块属性不为';不存在 更新:见下文

Python tkinter在将2.x代码移植到3.x和#x27;特金特';模块属性不为';不存在 更新:见下文,python,version,tkinter,porting,Python,Version,Tkinter,Porting,我已经为这个任务移植了代码:(整个源代码可以从那里以zip格式获得) 从Python2.x到3.x。注意,移植不是任务,这只是我试图保持代码最新,避免安装另一个版本的Python 在通常的2.x->3.x语法修复(打印、异常引发等)之后,意识到模块Tkinter现在在3.x(小写)中被称为Tkinter,我遇到了一些奇怪的问题,这段代码和其他一些类似的问题: def keys_pressed(d_o_e=tkinter.tkinter.dooneevent,d_w=tkinter.tkinter

我已经为这个任务移植了代码:(整个源代码可以从那里以zip格式获得) 从Python2.x到3.x。注意,移植不是任务,这只是我试图保持代码最新,避免安装另一个版本的Python

在通常的2.x->3.x语法修复(打印、异常引发等)之后,意识到模块
Tkinter
现在在3.x(小写)中被称为
Tkinter
,我遇到了一些奇怪的问题,这段代码和其他一些类似的问题:

def keys_pressed(d_o_e=tkinter.tkinter.dooneevent,d_w=tkinter.tkinter.DONT_WAIT)
错误类型如下:

AttributeError: 'module' object has no attribute 'tkinter'
我的IDE中的代码完成和变量跟踪似乎确实表明tkinter模块没有属性或子类tkinter,在这些属性或子类下可以引用dooneeventDONT\u WAIT。然而,在互联网上还有一些其他的参考文献,人们使用了类似的结构

_tkinter.dooneevent(_tkinter.DONT_WAIT)
将主循环向前移动,但即使这样引用它也会产生相同的错误

非常感谢您的任何想法


更新:通过lambda表示法引用_root_窗口似乎有效,因为在大多数情况下,它不再抱怨预执行时间。然而,在我未经训练的眼中,这基本上是“魔法”,因此我不知道接下来的错误是什么,也不知道如何解决它。该方法现在如下所示,第一行是我的更改:

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)
我得到的错误是:

TypeError: 'Tk' object is not callable              

引用定义方法的行(上面的第一行)。

出现
Tkinter。在Python 3中,Tkinter
已更改为
Tkinter.\u Tkinter
。比较Python2和Python3。另外,
dooneevent
不再位于
tkinter.\u tkinter
,但仍然是
Tk
(又称
root
)对象的成员

所以把你的代码改成

def keys_pressed(d_o_e=lambda arg: _root_window.dooneevent(arg),
        d_w=tkinter._tkinter.DONT_WAIT):

这利用了这样一个事实,即在链接的代码
\u root\u窗口中
全局的
,因此,虽然定义类时
\u root\u窗口
不可用,但在运行lambda时它将可用。

是的,这是我已经尝试过的。(我想你的意思是它从
Tkinter.Tkinter
变为
Tkinter.\u Tkinter
-
Tkinter.\u Tkinter
给出了一个
名称Tkinter未定义
错误)。我在导入这个的过程中可能遗漏了什么吗?我只是在做
import tkinter
,虽然从tkinter import*导入的
似乎也没有什么不同。奇怪。
dir(tkinter)
dir(tkinter.tkinter)
dir(tkinter.\u tkinter)
的结果是什么?dir(tkinter.\u tkinter):['ALL_EVENTS'、'don_WAIT'、'EXCEPTION'、'FILE_EVENTS'、'IDLE_EVENTS'、'READABLE'、'TCL_VERSION'、'TIMER_EVENTS'、'TCL_VERSION'、'TcError'、'TcKappType'、'tKTTTType'、'WINDOW_EVENTS'、'WRITABLE'、'doc'、'FILE'、'name'、'package'、'、'u展平'、'create'、'getbusywaitinterval'、'setbusywaitinterval'给出前面提到的
AttributeError:'module'对象没有属性'tkinter'
dir(tkinter)很长,如果您想让我发布它,请告诉我(假设我在注释中有足够的字符).THXY您的
\u root\u window
对象应该有一个
dooneevent
方法。不幸的是,在创建函数时这不可用。由于
\u root\u window
是一个
全局
窗口,您可以改为执行此操作:
按键(d\o\u e=lambda arg:\u root\u window(arg),d\u w=tkinter.\u tkinter.不要等待)
。这样,调用lambda时,而不是创建函数时,将查找
\u root\u window
。oops.应该编写
\u root\u window.dooneevent(arg)
,而不是
\u root\u window(arg)
。斯坦福链接已失效,从那里链接的代码无法访问。因此,我不知道答案中使用的名称“\u root\u window”实际上指的是什么。链接失效的可能性就是为什么要求问题具有完整的可运行代码,并要求答案至少用答案总结链接。我想我找到了answer.
tkinter.Tk().Tk
\u tkinter.tkapp
类的一个实例,该类似乎是隐藏的。(我猜它是Tk应用程序的代理,只能通过实例化
tkinter.Tk
进行实例化。tkapp实例具有
.doonevent
函数(方法)以及以前在2.x中可用的其他文件,如
Tkinter.Tkinter.xyz
(其中
Tkinter.Tkinter
实际上是
\u Tkinter
)。