如何使用线程正确关闭Tkinter应用程序

时间:2014-07-25 13:43:25

标签: python

我正在尝试构建一个显示基本GUI并在后台运行简单Web服务器的简单应用程序。我目前运行的代码运行得很好:

import Tkinter
import SimpleHTTPServer
import SocketServer
import threading
import time
import webbrowser
import json

# Load configuration
json_data=open('config.json')
configuration = json.load(json_data)
json_data.close()


# -----------------------------------------
#           configuration
# -----------------------------------------
host = configuration["host"]
port = configuration["port"]
folder = configuration["folder"]
url = host + ":" + str(port) + "/" + folder


# -----------------------------------------
#           Web Server
# -----------------------------------------
class WebserverThread (threading.Thread):
    def __init__(self, threadID, name):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name

    def run(self):
        self.PORT = port
        self.Handler = SimpleHTTPServer.SimpleHTTPRequestHandler
        self.httpd = SocketServer.TCPServer(("", self.PORT), self.Handler)

        print "--- serving at port", self.PORT
        self.httpd.serve_forever()

    def close(self):
        self.httpd.shutdown()
        print "Exiting web server Thread"

# create & start webserver thread, launch browser
thread1 = WebserverThread(1, "Thread-1")
thread1.start()
webbrowser.open_new( url )



# -----------------------------------------
#           Graphic User Interface
# -----------------------------------------
# Create window
top = Tkinter.Tk()
top.geometry('200x200')
top.resizable(width=0, height=0)

# start GUI
top.mainloop()

# Handle exit
print "Exiting Main Thread"
thread1.close()

如果我使用窗口关闭按钮(OSX中的红色圆圈)关闭GUI窗口,则应用程序需要几秒钟并正常退出。当我尝试使用Cmd + Q关闭应用程序时出现问题,在这种情况下,应用程序被冻结并且不会被关闭(我需要强制它关闭,因为它不会响应)。

我尝试删除网络服务器代码(线程),问题不再发生,所以它看起来像是在那里继续运行,但我不知道如何处理它。

因此,从本质上讲,当用户尝试通过Cmd + Q关闭应用程序时,如何处理并正确关闭应用程序?

非常感谢。

1 个答案:

答案 0 :(得分:0)

我会用Tk的“绑定”命令

绑定Cmd + Q事件
def callback(event):
    print("Cmd-Q recieved, shutting down thread");
    thread1.close()        # stop the webServer thread
    # call any additional exit handler you want
    root.destroy()         # destroy root window, my syntax may be wrong here

top.bind("<Cmd-Q>", callback)

您可以决定如何向webServerThread发送消息。