如何使用 tkinter 创建打字指示器?
How to create typing indicator with tkinter?
我在 Python 和 tkinter
创建了一个真实的实时聊天室。
我想知道如何在不使用 firebase 的情况下创建输入指示器。我的意思是说,其中一个用户的名字是 bob
,如果鲍勃正在输入一条消息,我希望它对其他用户说 bob is typing...
并且我想要它,如果可能,出现在类型消息框上。
编辑:
我在以下位置添加了这个:
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
import socket, threading
host = socket.gethostname()
port = 4000
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host,port))
s.listen()
clients = {}
addresses = {}
print(host)
print("Server is ready...")
serverRunning = True
def handle_client(conn):
try:
data = conn.recv(1024).decode('utf8')
welcome = 'Welcome %s! If you ever want to quit, type {quit} to exit.' % data
conn.send(bytes(welcome, "utf8"))
msg = "%s has joined the chat" % data
broadcast(bytes(msg, "utf8"))
clients[conn] = data
while True:
found = False
response = 'Number of People Online\n'
msg1 = conn.recv(1024)
if msg1 != bytes("{quit}", "utf8"):
broadcast(msg1, data+": ")
else:
conn.send(bytes("{quit}", "utf8"))
conn.close()
del clients[conn]
broadcast(bytes("%s has left the chat." % data, "utf8"))
break
except:
print("%s has left the chat." % data)
def broadcast(msg, prefix=""):
for sock in clients:
sock.send(bytes(prefix, "utf8")+msg)
while True:
conn,addr = s.accept()
conn.send("Enter username: ".encode("utf8"))
print("%s:%s has connected." % addr)
addresses[conn] = addr
threading.Thread(target = handle_client, args = (conn,)).start()
Client.py
import socket,threading,tkinter
host = input("Enter server name: ")
port = 4000
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
address = (host,port)
def echo_data(sock):
while True:
try:
msg = sock.recv(1024).decode('utf8')
msg_list.insert(tkinter.END, msg)
except OSError:
break
def send(event=None):
msg = my_msg.get()
my_msg.set("")
s.send(bytes(msg, "utf8"))
if msg == "{quit}":
s.close()
top.quit()
def on_closing(event=None):
my_msg.set("{quit}")
send()
top = tkinter.Tk()
top.title("Chat Room")
messages_frame = tkinter.Frame(top)
my_msg = tkinter.StringVar()
my_msg.set("Type your messages here.")
scrollbar = tkinter.Scrollbar(messages_frame)
msg_list = tkinter.Listbox(messages_frame, height=15, width=100, yscrollcommand=scrollbar.set)
scrollbar.pack(side=tkinter.RIGHT, fill=tkinter.Y)
msg_list.pack(side=tkinter.LEFT, fill=tkinter.BOTH)
msg_list.pack()
messages_frame.pack()
entry_field = tkinter.Entry(top, textvariable=my_msg)
entry_field.bind("<Return>", send)
entry_field.pack()
send_button = tkinter.Button(top, text="Send", command=send)
send_button.pack()
top.protocol("WM_DELETE_WINDOW", on_closing)
address = (host,port)
s.connect(address)
threading.Thread(target=echo_data, args = (s,)).start()
tkinter.mainloop()
Question: create typing indicator for tkinter.Entry
widget
定义从 tk.Tk
继承的应用程序 class,仅供演示。
import tkinter as tk
class App(tk.Tk):
def __init__(self):
super().__init__()
初始化一个标志.is_typing
,知道检测到输入
self.is_typing = False
创建一个Entry
作为普通
self.my_msg = tk.StringVar()
entry_field = tk.Entry(self, textvariable=self.my_msg)
entry_field.grid(row=0, column=0)
绑定一个 '<KeyRelease>'
事件到 Entry
实例,每个按键释放事件调用函数 self.typing(...
entry_field.bind('<KeyRelease>', self.typing)
创建 Label
和 Button
仅用于演示目的
self.label = tk.Label(self)
self.label.grid(row=1, column=0)
btn = tk.Button(self, text='Send', command=self.send_msg)
btn.grid(row=2, column=0)
重置标志 .is_typing
并清除发送消息时的 Label
文本,仅供演示。
def send_msg(self):
self.is_typing = False
self.label.config(text="")
函数 def typing(...
在每次按键释放事件时调用。
Return 如果设置了标志 .is_typing
,则无需进一步操作。
如果标志未设置,这是第一次调用:
- 设置标志
做动作,她只把Label
文字设置为"is typing"
。
def typing(self, *args):
if self.is_typing:
return
self.is_typing = True
self.label.config(text="is typing")
运行 演示应用程序
if __name__ == "__main__":
App().mainloop()
测试 Python:3.5
我在 Python 和 tkinter
创建了一个真实的实时聊天室。
我想知道如何在不使用 firebase 的情况下创建输入指示器。我的意思是说,其中一个用户的名字是 bob
,如果鲍勃正在输入一条消息,我希望它对其他用户说 bob is typing...
并且我想要它,如果可能,出现在类型消息框上。
编辑:
我在以下位置添加了这个:
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
import socket, threading
host = socket.gethostname()
port = 4000
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host,port))
s.listen()
clients = {}
addresses = {}
print(host)
print("Server is ready...")
serverRunning = True
def handle_client(conn):
try:
data = conn.recv(1024).decode('utf8')
welcome = 'Welcome %s! If you ever want to quit, type {quit} to exit.' % data
conn.send(bytes(welcome, "utf8"))
msg = "%s has joined the chat" % data
broadcast(bytes(msg, "utf8"))
clients[conn] = data
while True:
found = False
response = 'Number of People Online\n'
msg1 = conn.recv(1024)
if msg1 != bytes("{quit}", "utf8"):
broadcast(msg1, data+": ")
else:
conn.send(bytes("{quit}", "utf8"))
conn.close()
del clients[conn]
broadcast(bytes("%s has left the chat." % data, "utf8"))
break
except:
print("%s has left the chat." % data)
def broadcast(msg, prefix=""):
for sock in clients:
sock.send(bytes(prefix, "utf8")+msg)
while True:
conn,addr = s.accept()
conn.send("Enter username: ".encode("utf8"))
print("%s:%s has connected." % addr)
addresses[conn] = addr
threading.Thread(target = handle_client, args = (conn,)).start()
Client.py
import socket,threading,tkinter
host = input("Enter server name: ")
port = 4000
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
address = (host,port)
def echo_data(sock):
while True:
try:
msg = sock.recv(1024).decode('utf8')
msg_list.insert(tkinter.END, msg)
except OSError:
break
def send(event=None):
msg = my_msg.get()
my_msg.set("")
s.send(bytes(msg, "utf8"))
if msg == "{quit}":
s.close()
top.quit()
def on_closing(event=None):
my_msg.set("{quit}")
send()
top = tkinter.Tk()
top.title("Chat Room")
messages_frame = tkinter.Frame(top)
my_msg = tkinter.StringVar()
my_msg.set("Type your messages here.")
scrollbar = tkinter.Scrollbar(messages_frame)
msg_list = tkinter.Listbox(messages_frame, height=15, width=100, yscrollcommand=scrollbar.set)
scrollbar.pack(side=tkinter.RIGHT, fill=tkinter.Y)
msg_list.pack(side=tkinter.LEFT, fill=tkinter.BOTH)
msg_list.pack()
messages_frame.pack()
entry_field = tkinter.Entry(top, textvariable=my_msg)
entry_field.bind("<Return>", send)
entry_field.pack()
send_button = tkinter.Button(top, text="Send", command=send)
send_button.pack()
top.protocol("WM_DELETE_WINDOW", on_closing)
address = (host,port)
s.connect(address)
threading.Thread(target=echo_data, args = (s,)).start()
tkinter.mainloop()
Question: create typing indicator for
tkinter.Entry
widget
定义从
tk.Tk
继承的应用程序 class,仅供演示。import tkinter as tk class App(tk.Tk): def __init__(self): super().__init__()
初始化一个标志
.is_typing
,知道检测到输入self.is_typing = False
创建一个
Entry
作为普通self.my_msg = tk.StringVar() entry_field = tk.Entry(self, textvariable=self.my_msg) entry_field.grid(row=0, column=0)
绑定一个
'<KeyRelease>'
事件到Entry
实例,每个按键释放事件调用函数self.typing(...
entry_field.bind('<KeyRelease>', self.typing)
创建
Label
和Button
仅用于演示目的self.label = tk.Label(self) self.label.grid(row=1, column=0) btn = tk.Button(self, text='Send', command=self.send_msg) btn.grid(row=2, column=0)
重置标志
.is_typing
并清除发送消息时的Label
文本,仅供演示。def send_msg(self): self.is_typing = False self.label.config(text="")
函数
def typing(...
在每次按键释放事件时调用。
Return 如果设置了标志.is_typing
,则无需进一步操作。
如果标志未设置,这是第一次调用:- 设置标志
做动作,她只把
Label
文字设置为"is typing"
。def typing(self, *args): if self.is_typing: return self.is_typing = True self.label.config(text="is typing")
运行 演示应用程序
if __name__ == "__main__": App().mainloop()
测试 Python:3.5