Reputation: 63
I am creating a chat server/client using PodSixNet and tkinter and my problem is when I press 'send' to send a message to the other users in the chat room it does not display in the the Text widget.
If I use the commented out code:print(data['who'] + ": " + data['message'])
the message will print just fine on the console but I just cannot get it to appear on the GUI. I don't really know how to go about solving this issue. Below is the code of my client, it is python 3.6.
Chat Client
import sys
from time import sleep
from sys import stdin, exit
from tkinter import *
from PodSixNet.Connection import connection, ConnectionListener
from _thread import *
root = Tk()
root.title("Chat")
line1 = 1.0
class Client(ConnectionListener):
def __init__(self, host, port):
self.Connect((host, port))
print("Chat client started")
print("Ctrl-C to exit")
# get a nickname from the user before starting
print("Enter your nickname: ")
connection.Send({"action": "nickname", "nickname": stdin.readline().rstrip("\n")})
messages = Text(root)
messages.pack()
userInput = StringVar()
textField = Entry(root, text = userInput)
textField.pack(side = BOTTOM, fill = X)
self.message = messages
self.inputField = textField
sendButton = Button(root, text = "Send", command = lambda: self.InputLoop())
sendButton.pack(side = LEFT)
root.mainloop()
def Loop(self):
connection.Pump()
self.Pump()
def InputLoop(self):
connection.Send({"action": "message", "message": self.inputField.get()})
#######################################
### Network event/message callbacks ###
#######################################
def Network_players(self, data):
print("*** players: " + ", ".join([p for p in data['players']]))
def Network_message(self, data):
global line1
# print(data['who'] + ": " + data['message'])
msgGet = data['who'] + ": " + data['message']
self.message.insert(END, msgGet)
line1 += 1.0
# built in stuff
def Network_connected(self, data):
print("You are now connected to the server")
def Network_error(self, data):
print('error:', data['error'][1])
connection.Close()
def Network_disconnected(self, data):
print('Server disconnected')
exit()
if len(sys.argv) != 2:
print("Usage:", sys.argv[0], "host:port")
print("e.g.", sys.argv[0], "localhost:31425")
else:
host, port = sys.argv[1].split(":")
c = Client(host, int(port))
while 1:
c.Loop()
sleep(0.001)
EDIT: Here is the code of the server, in case it is needed.
Chat Server
import sys
from time import sleep, localtime
from weakref import WeakKeyDictionary
from PodSixNet.Server import Server
from PodSixNet.Channel import Channel
class ClientChannel(Channel):
"""
This is the server representation of a single connected client.
"""
def __init__(self, *args, **kwargs):
self.nickname = "anonymous"
Channel.__init__(self, *args, **kwargs)
def Close(self):
self._server.DelPlayer(self)
##################################
### Network specific callbacks ###
##################################
def Network_message(self, data):
self._server.SendToAll({"action": "message", "message": data['message'], "who": self.nickname})
def Network_nickname(self, data):
self.nickname = data['nickname']
self._server.SendPlayers()
class ChatServer(Server):
channelClass = ClientChannel
def __init__(self, *args, **kwargs):
Server.__init__(self, *args, **kwargs)
self.players = WeakKeyDictionary()
print('Server launched')
def Connected(self, channel, addr):
self.AddPlayer(channel)
def AddPlayer(self, player):
print("New Player" + str(player.addr))
self.players[player] = True
self.SendPlayers()
print("players", [p for p in self.players])
def DelPlayer(self, player):
print("Deleting Player" + str(player.addr))
del self.players[player]
self.SendPlayers()
def SendPlayers(self):
self.SendToAll({"action": "players", "players": [p.nickname for p in self.players]})
def SendToAll(self, data):
[p.Send(data) for p in self.players]
def Launch(self):
while True:
self.Pump()
sleep(0.0001)
# get command line argument of server, port
if len(sys.argv) != 2:
print("Usage:", sys.argv[0], "host:port")
print("e.g.", sys.argv[0], "localhost:31425")
else:
host, port = sys.argv[1].split(":")
s = ChatServer(localaddr=(host, int(port)))
s.Launch()
Upvotes: 0
Views: 170
Reputation: 2973
EDIT The following doesn't seem to fix the problem.
You probably need to tell the tkinter.Text
widget to use all the available space by calling pack
as follows:
messages.pack(fill=BOTH, expand=1)
Here's a stripped-down version of the client without the network part. I used it to test the above solution to find that it doesn't make a difference.
from tkinter import *
root = Tk()
messages = Text(root)
messages.pack() # (fill=BOTH, expand=1)
userInput = StringVar()
textField = Entry(root, text = userInput)
textField.pack(side = BOTTOM, fill = X)
def on_send():
msgGet = textField.get()
messages.insert(END, msgGet)
sendButton = Button(root, text = "Send", command = on_send)
sendButton.pack(side = LEFT)
root.mainloop()
Upvotes: 1