Python 如何使用tkinter创建键入指示器?

Python 如何使用tkinter创建键入指示器?,python,python-3.x,sockets,tkinter,python-multithreading,Python,Python 3.x,Sockets,Tkinter,Python Multithreading,我用Python和tkinter创建了一个真正的实时聊天室 我想知道如何在不使用firebase的情况下创建键入指示器。我的意思是说,其中一个用户名是bob,如果bob正在键入消息,我希望它告诉其他用户bob正在键入…,如果可能的话,我希望它出现在键入消息框上 编辑: 我在以下文件中添加了这一点: def var_changed(self): self.label.config(text=msg+"is typing") my_msg = tkinter.StringVar() my_m

我用Python和
tkinter
创建了一个真正的实时聊天室

我想知道如何在不使用firebase的情况下创建键入指示器。我的意思是说,其中一个用户名是
bob
,如果bob正在键入消息,我希望它告诉其他用户
bob正在键入…
,如果可能的话,我希望它出现在键入消息框上

编辑: 我在以下文件中添加了这一点:

def var_changed(self):
   self.label.config(text=msg+"is typing")

my_msg = tkinter.StringVar()
my_msg.trace = ("w", var_changed)
entry_field = tkinter.Entry(top, textvariable=my_msg)
entry_field.pack()
但它所做的只是复制我正在写的东西,而不是说用户在键入消息

Server.py Client.py
导入套接字、线程、tkinter
主机=输入(“输入服务器名称:”)
端口=4000
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
地址=(主机、端口)
def回波_数据(sock):
尽管如此:
尝试:
msg=sock.recv(1024).decode('utf8')
msg_list.insert(tkinter.END,msg)
除操作错误外:
打破
def发送(事件=无):
msg=my_msg.get()
my_msg.set(“”)
s、 发送(字节(msg,“utf8”))
如果msg==“{quit}”:
s、 关闭()
top.quit()
def on_关闭(事件=无):
my_msg.set(“{quit}”)
发送()
top=tkinter.Tk()
顶部标题(“聊天室”)
消息\u frame=tkinter.frame(顶部)
my_msg=tkinter.StringVar()
my_msg.set(“在此处键入您的消息”)
scrollbar=tkinter.scrollbar(消息\u帧)
msg_list=tkinter.Listbox(消息框,高度=15,宽度=100,yscrollcommand=scrollbar.set)
滚动条.pack(side=tkinter.RIGHT,fill=tkinter.Y)
msg_list.pack(side=tkinter.LEFT,fill=tkinter.BOTH)
msg_list.pack()
消息\u frame.pack()
entry\u field=tkinter.entry(顶部,textvariable=my\u msg)
条目\字段。绑定(“,发送)
条目\字段.pack()
发送按钮=tkinter.button(顶部,text=“发送”,command=send)
发送按钮。包()
协议(“WM_删除_窗口”,打开_关闭)
地址=(主机、端口)
s、 连接(地址)
threading.Thread(target=echo_data,args=(s,).start()
tkinter.mainloop()
问题:为
tkinter.Entry
小部件创建键入指示器

  • 定义从
    tk.tk
    继承的应用程序类,仅供演示

    import tkinter as tk
    
    class App(tk.Tk):
    
        def __init__(self):
            super().__init__()
    
        def send_msg(self):
            self.is_typing = False
            self.label.config(text="")
    
  • 初始化一个标志
    。正在键入
    ,以了解是否检测到键入

            self.is_typing = False
    
  • 创建一个
    条目

            self.my_msg = tk.StringVar()
            entry_field = tk.Entry(self, textvariable=self.my_msg)
            entry_field.grid(row=0, column=0)
    
  • ''
    事件绑定到
    条目
    实例,该实例针对每个按键释放事件调用函数
    self.typing(…

            entry_field.bind('<KeyRelease>', self.typing)
    
  • 重置标记
    。正在键入
    ,并在发送消息时清除标签文本,仅供演示

    import tkinter as tk
    
    class App(tk.Tk):
    
        def __init__(self):
            super().__init__()
    
        def send_msg(self):
            self.is_typing = False
            self.label.config(text="")
    
  • 函数
    def typing(…
    ),在每次按键释放事件中调用该函数。
    如果设置了标志
    。正在键入
    ,则返回,无需进一步操作。
    如果标志未设置,则这是第一次调用:

    • 立旗
    • 执行此操作时,她只需将
      标签设置为
      “文本”即可键入“

  • 运行演示应用程序

    if __name__ == "__main__":
        App().mainloop()
    
  • 使用Python:3.5测试

    问题:为
    tkinter.Entry
    小部件创建键入指示器

  • 定义从
    tk.tk
    继承的应用程序类,仅供演示

    import tkinter as tk
    
    class App(tk.Tk):
    
        def __init__(self):
            super().__init__()
    
        def send_msg(self):
            self.is_typing = False
            self.label.config(text="")
    
  • 初始化一个标志
    。正在键入
    ,以了解是否检测到键入

            self.is_typing = False
    
  • 创建一个
    条目

            self.my_msg = tk.StringVar()
            entry_field = tk.Entry(self, textvariable=self.my_msg)
            entry_field.grid(row=0, column=0)
    
  • ''
    事件绑定到
    条目
    实例,该实例针对每个按键释放事件调用函数
    self.typing(…

            entry_field.bind('<KeyRelease>', self.typing)
    
  • 重置标记
    。正在键入
    ,并在发送消息时清除标签
    文本,仅供演示

    import tkinter as tk
    
    class App(tk.Tk):
    
        def __init__(self):
            super().__init__()
    
        def send_msg(self):
            self.is_typing = False
            self.label.config(text="")
    
  • 函数
    def typing(…
    ),在每次按键释放事件中调用该函数。
    如果设置了标志
    。正在键入
    ,则返回,无需进一步操作。
    如果标志未设置,则这是第一次调用:

    • 立旗
    • 执行此操作时,她只需将
      标签设置为
      “文本”即可键入“

  • 运行演示应用程序

    if __name__ == "__main__":
        App().mainloop()
    

  • 用Python:3.5测试的

    tkinter
    不支持多线程,这意味着只有一个线程可以更新GUI。这意味着,例如,
    echo\u data()
    无法直接更新tkinter
    列表框。常见的解决方法通常是使用
    队列
    在线程之间传递数据,并在QUI线程中定期检查数据以查看是否有新数据到达。您可以使用
    tkinter
    的通用小部件方法安排轮询这里有许多答案,说明了如果你在这里搜索它们,该如何做。@martineau我已经研究了
    队列
    之后()
    有点理解,但是如果有人在键入内容,那么检测代码会是什么呢?我认为检测是否有人在键入内容时没有阻塞是特定于操作系统的,并且不认为Python提供了任何通用的方法来专门做这件事。例如,在Windows上,您可以使用
    msvcrt.kbhit()
    。下面是一个问题的答案,答案显示了它的用途。我不知道其他操作系统,但是很可能在这个主题上有一些问题。
    tkinter
    不支持多线程,这意味着只有一个线程可以更新GUI。这意味着,例如,
    echo\u data()
    无法直接更新tkinter
    列表框。常见的解决方法通常是使用
    队列
    在线程之间传递数据,并在QUI线程中定期检查数据以查看是否有新数据到达。您可以使用
    tkinter
    的通用小部件方法安排轮询这里有很多答案,说明了如果你在这里搜索它们,该怎么做。@martineau我已经研究了
    Queue
    after()
    ,有点明白了,但是这些代码是用来做什么的呢