Issue
I have developed an asynchronous console chat program. Then I decided to develop an asynchronous GUI chat program.
The server side is running on console. The server is managing the communication process between clients.
I have two client programs. One of them is a console, the other one is a GUI program. When the console program sends messages, they are printed on the Text widget of the GUI program.
However when I sent messages on the GUI program, the messages are displayed on the console window of the other client program only after the client which runs on console writes messages to the other client.
The write
function of the console program is as follows:
async def write(self, writer):
t = threading.Thread(
target=lambda: writer.write(
f"{self.nick}: {sys.stdin.readline()}".encode()
)
)
t.daemon = True
t.start()
t.join(0.1)
await writer.drain()
This function accomplishes the task as I want.
The write
function of the GUI program is as follows:
async def write(self, writer):
if self.data:
data = self.data
self.data = ""
t = threading.Thread(
target=lambda: writer.write(
f"{self.nick}: {data}\n".encode()
)
)
t.daemon = True
t.start()
t.join(0.1)
await writer.drain()
else:
await asyncio.sleep(0.1)
And this function is not working as I want.
self.data
is a variable that gets the text in the tk.Entry
field. It was defined in the __init__
function of the class.
self.entry = tk.Entry(
master=self.bottom_frame,
width=50
)
self.entry.pack()
self.entry.bind("<Return>", lambda event: self.callback())
self.data = ""
The self.callback()
function is as follows:
def callback(self):
self.data = self.entry.get()
self.entry.delete("0", "end")
self.update()
self.update_idletasks()
So, what I was trying to do here was, when I press the <Return>
, the content of the self.entry
is passed to self.data
variable. According to the self.write
function, there's a condition like if self.data
which is used for sending messages when self.data
is not an empty value. If the condition is not met, I decided to wait the function with await asyncio.sleep(0.1)
.
As I said, the gui program reads the messages without any problem, however it can't send messages asynchronously to the console client program. The console client program needs to send a new message to see the messages come from the GUI client.
What should I do to send messages asynchronously on GUI application?
Below are the whole codes:
Server: https://www.dropbox.com/s/q04w3et3huegrao/server.py
Client1: https://www.dropbox.com/s/h7seeuoylvnpezq/client1.py
Client2: https://www.dropbox.com/s/uz4zn3vjfcc3mrj/client2.py
Solution
The probem is solved. The asynchronous write
function is changed as below:
async def write(self, writer):
def inner():
data = self.entry.get()
self.entry.delete("0", "end")
self.entry.unbind_all("<Return>")
t = threading.Thread(
target=lambda: writer.write(
f"{self.nick}: {data}\n".encode()
)
)
t.daemon = True
t.start()
t.join(0.1)
self.entry.bind("<Return>", lambda event: inner())
await writer.drain()
Answered By - dildeolupbiten
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.