Tkinter。后方法冻结窗? [英] Tkinter .after method freezing window?

查看:165
本文介绍了Tkinter。后方法冻结窗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的聊天客户端,我试图使用 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.

如何在python的套接字recv方法上设置超时?

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆