聊天客户端:按下发送

时间:2017-04-21 02:09:34

标签: python-3.x tkinter server client

我正在使用PodSixNet和tkinter创建一个聊天服务器/客户端,我的问题是当我按下发送'向聊天室中的其他用户发送消息,它不会显示在“文本”小部件中。

如果我使用注释掉的代码: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()

1 个答案:

答案 0 :(得分:1)

编辑以下似乎无法解决问题。

您可能需要通过调用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()
相关问题