【问题标题】:tkinter locking up with sys.exittkinter 与 sys.exit 锁定
【发布时间】:2015-01-13 18:36:23
【问题描述】:

我在 youtube 教程中关注: https://www.youtube.com/watch?v=Zf-b2JVZs7g

当我们到达sys.exit(0)

Python shell 似乎正在响应,但我创建的窗口锁定而不是关闭。另一个奇怪的事情是,当我运行调试器时,程序按预期运行。

#Python 2.7.8
#Idle 2.7.8
#Tkinter 8.5.15

import sys
import Tkinter
import turtle
from Tkinter import *


def main():
    root = Tk()

    root.title("Draw!")
    root.geometry("800x800")

    cv = Canvas(root, width=600, height=600)
    cv.pack(side=LEFT)

    t = turtle.RawTurtle(cv)
    screen = t.getscreen()
    screen.setworldcoordinates(0,0,600,600)

    frame = Frame(root)
    frame.pack(side = RIGHT, fill = BOTH)
    screen.tracer(0)


    def quitHandler():
        print ("Goodbye")
        sys.exit(0)
        ##raise SystemExit
        ##exit()


    quitButton = Button(frame, text="Quit", command = quitHandler)
    quitButton.pack(side=BOTTOM)

    def clickHandler(x,y):
        t.goto(x,y)
        screen.update()

    screen.onclick(clickHandler)

    def dragHandler(x,y):
        t.goto(x,y)
        screen.update()

    t.ondrag(dragHandler)


    root.mainloop()

if __name__ == "__main__":
    main()

在视频的 cmets 中有两件事让我印象深刻,但我不明白为什么 sys.exit(0) 对我没有像对他一样有用:

  1. 他正在使用 Python 3
  2. 其他人也有同样的问题,但我看不到任何答案。

我的猜测是版本问题,但是(作为 n00b)我不知道问题是什么。

【问题讨论】:

  • Python 关闭的细节已经随着版本的变化而变化,即使在 3.x 中也是如此。我个人会将 root.destroy() 而不是 sys.exit() 放在退出处理程序中,并在 mainloop() 和 main() 调用返回后让 Python 正常退出。由于打印 'goodbye' 不会打印到 gui,并且可能会失败(如果您在 windows 上使用 pythonw 运行应用程序),我会将 print 放在 main() 调用之后。
  • 谢谢特里!我将此信息添加到下面的答案中。

标签: python python-2.7 python-3.x tkinter


【解决方案1】:

root.destroy() 行添加到您的quitHandler 函数中。它将清理否则留下的 Tkinter 进程。我对其进行了测试,它为我解决了这个问题。

(代码已删除)

更新

来自 Terry Jan Reedy 的评论:

Python 关闭的细节随着版本的变化而变化, 即使在 3.x 以内。我个人会放 root.destroy() 但不是 sys.exit() 在退出处理程序中,并在之后让 Python 正常退出 mainloop() 和 main() 调用返回。由于打印“再见”不 打印到 gui,并且可能会失败(如果您使用 pythonw 运行应用程序 windows),我会在 main() 调用之后打印。

原来如此

def quitHandler():
    root.destroy()

print 在代码的最后。

【讨论】:

  • 只是为了清楚起见,这是版本问题吗?或者为什么他的工作和我的没有。还有其他一些对我没用的东西对他有用。
  • 他在 Mac 上,所以 Tkinter 的实现与在 Windows 上完全不同。不包括 root.destroy 会导致不可预测的行为,因此不同的实现会给出不同的结果。有时程序会在你自动清理之后。但他应该把它包括在内。
  • 我想我忘了问你用的是什么操作系统。
  • 嗯,好的。我使用的是 Windows 7。所以我假设对于任何循环,您应该始终明确终止它是否正确?
  • 你的意思是每当使用mainloop?是的。
【解决方案2】:
def quitHandler():
    print ("Goodbye")
    root.destroy()
    sys.exit(0)


quitButton = Button(frame, text="Quit", command = quitHandler)
quitButton.pack(side=BOTTOM)

这会很好用。

【讨论】:

    【解决方案3】:

    你可以像这样很容易地做到这一点:

    def quit():
           import sys;sys.exit()
    
    widget = Button(root,text="Quit",width=1,fg="red",command=quit).grid(row=1,column=1)
    

    如果您使用此代码,您可以自定义更多的底部。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-01
      • 2014-06-08
      • 2016-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-13
      • 1970-01-01
      相关资源
      最近更新 更多