Tkinter。后方法冻结窗? [英] Tkinter .after method freezing window?
问题描述
我有一个简单的聊天客户端,我试图使用 Tkinter
作为界面。我的问题是,当为聊天输入/输出运行 mainloop
与 .after
时,窗口冻结并阻止,直到收到另一封邮件。
I have a simple chat client that I was attempting to get working with Tkinter
as the interface. My problem is that when running the mainloop
with .after
for the chat input/output, the window freezes and blocks until another message is received.
class Client(Frame):
def __init__(self, **kwargs):
Frame.__init__(self, Tk())
self.pack()
self.lb = Listbox(self, width=100, height=30)
self.lb.pack()
self.show_data = self.lb.after(1000, self.chat_handle)
self.entry = Entry(self)
self.entry.bind('<Return>', self.input_handle)
self.entry.pack(side=BOTTOM, fill=X)
def input_handle(self, event):
msg = self.entry.get()
self.entry.delete(0, 'end')
new_msg = 'privmsg %s :' % self.channel + msg + '\r\n'
self.client.sendall(new_msg)
self.lb.insert(END, self.nick + ' | ' + msg)
def chat_handle(self):
try:
self.data = self.client.recvfrom(1024)
except socket.error:
self.lb.insert(END, "Bad Connection!")
return
if self.data and len(self.data[0]) > 0:
self.lb.insert(END, self.data[0])
elif self.data and len(self.data[0]) == 0:
self.lb.insert(END, "Connection Dropped!")
return
self.show_data = self.lb.after(1000, self.chat_handle)
该代码块被缩短,但显示了相关的部件。 条目
小部件将在长时间内变得无响应,而 .after
被调用,并且在收到消息之前不会响应。
This block of code is shortened but, shows the relavent parts involved. The Entry
widget will become unresponsive for extended periods while .after
is called and won't respond until a message is received.
当条目
小部件再次响应时,输入字段包含所有输入的数据,但是在冻结时间内不会看到变化。 Listbox
小部件也是如此。
When the Entry
widget becomes responsive again, the entry field has all the data that was typed in but, I won't see the changes during the "frozen" time. The same goes for the Listbox
widget.
如果有人可以清楚地说明为什么这是准确的或指出的如果我错过在这里使用一种方法,将不胜感激。
If anyone could shed some light on why this is exactly or point out if I'm miss using a method here, it would be greatly appreciated.
编辑:经过一些更多的研究,它看起来像 socket
数据在此时被调用和窗口冻结时阻塞。
after some more research, its looking like the socket
data is blocking whenever its called and window is getting frozen during this time.
推荐答案
我了解到使用选择
进行系统调用以检查套接字文件是否准备好读取。
I learned about using select
to make system calls to check if a socket file is ready to be read.
class Client(Frame):
def __init__(self, **kwargs):
self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.client.connect(("host", port))
self.client.setblocking(0)
Frame.__init__(self, Tk())
self.pack()
self.lb = Listbox(self, width=100, height=30)
self.lb.pack()
self.show_data = self.lb.after(1000, self.chat_handle)
self.entry = Entry(self)
self.entry.bind('<Return>', self.input_handle)
self.entry.pack(side=BOTTOM, fill=X)
def input_handle(self, event):
msg = self.entry.get()
self.entry.delete(0, 'end')
new_msg = 'privmsg %s :' % self.channel + msg + '\r\n'
self.client.sendall(new_msg)
self.lb.insert(END, self.nick + ' | ' + msg)
def chat_handle(self):
socket_data = select.select([self.client], [], [], 0.3) # set timeout on last arg
if socket_data[0]:
try:
self.data = self.client.recvfrom(1024)
except socket.error:
self.lb.insert(END, "Bad Connection!")
return
if self.data and len(self.data[0]) > 0:
self.lb.insert(END, self.data[0])
elif self.data and len(self.data[0]) == 0:
self.lb.insert(END, "Connection Dropped!")
return
self.show_data = self.lb.after(1000, self.chat_hand
这篇关于Tkinter。后方法冻结窗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!