使用Tkinter GUI的客户端代码,无法发送多条数据

0 投票
1 回答
1173 浏览
提问于 2025-04-18 00:24

这是一个聊天服务器中客户端的代码,使用的是Python的Tkinter库来制作图形界面(GUI)。

问题是,当我发送一次消息后,就会出现一个无限循环,这个循环一直在运行,导致我无法发送其他消息。请告诉我这里有什么问题。

from Tkinter import *
import socket#for sockets
import sys  #for exit
import tkMessageBox
blue ="#000fff000"

root = Tk()
frame = Frame(root)
frame.pack()
root.geometry("500x500")
e=NONE

# create dgram udp socket
try:
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
except socket.error:
    print 'Failed to create socket'
    sys.exit()

host = 'localhost';
port = 40019;

def sendmsg():
 global e
 e = Entry(frame ,width=50 )
 e.pack(side=RIGHT)
 e.focus_set()
 b = Button(frame, text="send", width=10, command=callback ,bg =blue)
 b.pack(side=LEFT)
 mainloop()
 text = e.get()

 def callback():
     print  e.get()
     msg=str(e.get())
     e.delete(0, END)
     while(1):          

      text_area.insert(END,msg)

      try:
        #Set the whole string
       while(1):
        s.sendto(msg, (host, port))             

        # receive data from client (data, addr)
        d = s.recvfrom(1024)
        reply = d[0]
        addr = d[1]

        print 'Server reply : ' + reply
        text_area.insert(END,reply)

      except socket.error, msg:
        print 'Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
        sys.exit()            

menubar = Menu(root)
filemenu = Menu(menubar, tearoff=0)
filemenu.add_command(label="SEND A MESSAGE", command=sendmsg)
filemenu.add_separator()

filemenu.add_command(label="Exit", command=sys.exit)
menubar.add_cascade(label="SEND", menu=filemenu)
root.config(menu=menubar)

frame=Frame(root)
frame.pack()
text_area = Text(frame)
text_area.pack(side=BOTTOM)

B1 = Button(root, text = "CLOSE", command = sys.exit)
B1.pack(side =TOP)        

root.mainloop()

1 个回答

0

在任何窗口系统中,你需要定期处理窗口系统的事件。这意味着你需要使用非阻塞的输入输出,或者在工作线程上进行网络输入输出。你还可能需要注意从工作线程更新用户界面窗口,因此像twisted这样的框架可以将各种事件源整合到一个事件处理循环中,这样可以让事情变得更简单。

一个很好的例子是一个基于线程的方案,它将网络和Tkinter结合在一起,具体可以参考这个链接。注意,工作线程会将数据排队,UI线程在准备好处理时会进行轮询来处理这些数据。

我认为twisted这个包是处理这个问题的好方法,因为它的工作方式更像是Tcl的文件事件,将输入输出事件和用户界面事件整合在同一个事件系统中。

撰写回答