聊天客户端:tkinter文本窗口小部件在按发送后不更新



我正在使用podsixnet和tkinter创建聊天服务器/客户端,而我的问题是,当我按'send'将消息发送给聊天室中的其他用户时,文字小部件。

如果我使用注释的代码: print(data['who'] + ": " + data['message']),该消息将在控制台上正常打印,但我无法将其显示在GUI上。我真的不知道该如何解决这个问题。以下是我客户的代码,它是Python 3.6。

聊天客户端

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)

编辑:这是服务器的代码,以防万一。

聊天服务器

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()

edit 以下似乎无法解决问题。

您可能需要告诉tkinter.Text小部件通过调用pack的所有可用空间,如下所示:

messages.pack(fill=BOTH, expand=1)

这是没有网络部分的客户端的剥离版本。我用它来测试上述解决方案,以发现它没有区别。

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()

最新更新