tkinter工作在主线程,而gevent是单线程工作,如何整合在一起?
瞅到一段代码,迅速收藏
1 import gevent
2 from gevent import socket
3 import Tkinter as tk
4
5 class SockLoop(object):
6 def __init__(self, callback):
7 self.callback = callback
8
9 def __call__(self, sock, client):
10 while 1:
11 mes = sock.recv(256)
12 ret = self.callback(client, mes)
13 if ret is not None:
14 sock.send(ret)
15
16 def socket_server(port, callback):
17 ssock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP)
18 ssock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
19 ssock.bind(('', port))
20 ssock.listen(5)
21
22 while 1:
23 sock, client = ssock.accept()
24 gevent.spawn(callback, sock, client)
25
26 class App(object):
27 def __init__(self, root):
28 self.greenlet = None
29 self.root = root
30 self._build_window(root)
31 self.root.after(100, self._connect)
32
33 def add_text(self, text):
34 cleaned_string = text.replace('\r', '')
35 self.text.insert(tk.END, cleaned_string)
36
37 def quit(self):
38 self.root.quit()
39
40 def _build_window(self, root):
41 self.frame = tk.Frame(root)
42 self.text = tk.Text(self.frame)
43 self.quit_button = tk.Button(self.frame, text="Quit", command=self.quit)
44 self.text.pack()
45 self.quit_button.pack()
46 self.frame.pack()
47
48 def _connect(self):
49 self.greenlet = gevent.spawn(
50 socket_server,
51 8080,
52 SockLoop(lambda cl, txt: self.add_text("%s: %s" % (cl, txt))))
53 self.gevent_loop_step()
54
55 def gevent_loop_step(self):
56 gevent.sleep()
57 self.root.after_idle(self.gevent_loop_step)
58
59
60 if __name__ == '__main__':
61 root = tk.Tk()
62 app = App(root)
63 root.mainloop()