当前位置: 首页 > 知识库问答 >
问题:

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

麻桐
2023-03-14

我正在使用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个答案

戚衡
2023-03-14

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

你可能需要告诉tkinter。文本小部件通过调用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()
 类似资料:
  • 如何在聊天客户端发送媒体消息?我使用的是JS SDK,基于教程https://www.twilio.com/docs/api/chat/guides/media-support,但是出现了错误。我使用的方法如下所示: 错误消息:

  • 我对python有点陌生,这是我第一次使用套接字,我试图制作一个具有客户端和服务器的应用程序,用户可以在客户端中输入,它将被发送到服务器,然后将其发送给所有其他客户端。我已经将其设置为工作状态,但每当我尝试发送第二条消息时,我总是收到一个错误错误:[Errno 10058]发送或接收数据的请求被禁止,因为套接字已经在之前的关闭调用中关闭了该方向。我如何才能做到这一点? 尝试在启动新套接字或发送新消

  • 我的问题是,我仍然可以在客户端之间发送消息(客户端到客户端),但发送两三次后,消息不再显示给收件人。 因此,基本上每当客户机希望向另一个客户机发送消息时,该消息首先被发送到服务器。但正如您从我的编码中注意到的,我是以对象的形式发送服务器数据的。例如: 当您发送消息时,类型是“message”。当服务器接收对象时,它检查接收数据及其类型。例如: 如果类型是“message”,那么它会向特定的客户端发

  • 我需要在netty中有一个客户机/服务器通信,用于我的项目目的之一。所以我刚开始用一个handsOn来改进,我正在学习netty,我是一个初学者。 我尝试了一个简单的客户端服务器与Netty聊天。 客户端和服务器正在初始化,我可以看到服务器能够获得用于建立连接的客户端管道,但是当客户端发送消息时,它没有进入ServerAdapterHandler的messageReceived部分。下面是我的源代

  • Twilio布道者们好, 我们使用Twilio模块,可编程聊天,并使用Javascript客户端和Twilio.api,C#服务器API。 我们希望用户看到特定信道的信道和消息,但需要有条件地阻止他们发送消息。 我们可以禁用UI元素,但智能用户仍然能够访问Twilio客户端,并发送消息。

  • 问题内容: 您好,我一直在尝试将文件从node.js发送到客户端。 我的代码有效,但是当客户端转到指定的url()时,它将流式传输文件。 从Google Chrome浏览器访问该文件可使文件(.mp3)在播放器中播放。 我的目标是让客户的浏览器下载文件,然后问客户他想在哪里存储文件,而不是在网站上流式传输。 问题答案: 您需要设置一些标题标志。 用下载代替流媒体;