不断更新服务器中的数据并打印到文本框

时间:2017-05-12 15:33:11

标签: python python-2.7 tkinter

所以,我有一个完全用Python 2.7编写的服务器:

from socket import *
from select import *

HOST = "127.0.0.1"
PORT = 1993

server = socket(AF_INET, SOCK_STREAM)    
server.bind((HOST, PORT))  
server.listen(5)    
clients = []

def getClients():
    to_use = []
    for client in clients:
        to_use.append(client[0])
    return to_use

while(True):
    read, write, error = select([server],[],[],0)

    if(len(read)):
        client, address = server.accept()
        clients.append([client, address, []])

    to_use = getClients()

    try:
        read, write,error = select(to_use,[],[],0)
        if(len(read)):
            for client in read:
                data = client.recv(1024)
                print(bytes.decode(data))
                if(data == 0):
                    for c in clients:
                        if c[0] == client:
                            clients.remove(c)
                            break
                else:
                    for c in clients:
                        c[2].append(data)

    except:
        pass

    try:
        to_use = getClients()
        read, write, error = select([], to_use, [], 0)

        if(len(write)):
            for client in write:
                for c in clients:
                    if c[0] == client:
                        for data in c[2]:
                            sent = client.send(data)
                            if(sent == len(data)):
                               c[2].remove(data)
                        break
    except:
        pass
  

我需要做的是从中获取数据(消息)的持续更新   服务器并将它们打印到Tkinter制作的文本框中。

接收代码:

from socket import *
from select import *

HOST = "127.0.0.1"
PORT = 1993

sock = socket(AF_INET, SOCK_STREAM)
sock.connect((HOST, PORT))

while True:
    data = bytes.decode(sock.recv(1024))
    print data

它不一定是Tkinter,但这就是我一直在尝试的;只要它使用GUI。不要担心发送消息我只需要能够接收数据并将其打印到文本框/区域。

2 个答案:

答案 0 :(得分:3)

基本框架是首先创建所有小部件。接下来,编写一个读取数据并更新UI的函数。最后,安排每隔几毫秒调用一次此函数。

粗略地说,它看起来像这样:

import Tkinter as tk
...

class Example(object):
    def __init__(self):
        self.root = tk.Tk()
        self.text = tk.Text(root)
        self.text.pack(fill="both", expand=True)
        ...

    def start(self):
        self.read_periodically()
        self.root.mainloop()

    def read_periodically(self):
        # read the data
        data = bytes.decode(sock.recv(1024))

        # update the UI
        self.text.insert("end", data)

        # cause this function to be called again in 100ms
        self.after(100, self.read_periodically)


example = Example()
example.start()

如果数据不是导致sock.recv(1024)阻止的稳定流,那么您的用户界面会在等待数据时冻结。如果是这种情况,您可以将套接字的读取移动到线程,并让线程通过线程安全队列与GUI通信。

如果数据是稳定的,或者您设置了非阻塞套接字,则不必执行任何操作。

答案 1 :(得分:1)

我想先提交一条评论,但请尝试一下:

你可以使用开始按钮之外的其他东西来推动事情我只是把它放在那里以方便使用

from Tkinter import *
import threading
from socket import *
from select import *

    master = Tk() #create the GUI window

    #put the test program in a seperate thread so it doesn't lock up the GUI
    def test_program_thread():
        thread = threading.Thread(None, test_program, None, (), {})
        thread.start()


    def test_program():
        HOST = "127.0.0.1"
        PORT = 1993

        sock = socket(AF_INET, SOCK_STREAM)
        sock.connect((HOST, PORT))

        while True:
            data = bytes.decode(sock.recv(1024))
            terminal_listbox.insert(END, str(data))
            master.update() #I don't think this line is necessary, but put it here just in case


    # set the gui window dimensions and the title on the GUI
    master.minsize(width=450, height=450)
    master.wm_title("Stack Problem")

    # Start button is set to y and starts the test program when hit
    start_button = Button(master, text='START', command=test_program_thread)
    start_button.place(x=5, y=5)

    # scroll bar for the terminal outputs
    scrollbar = Scrollbar(master)
    scrollbar.place(x=420, y=150)

    # Terminal output. Auto scrolls to the bottom but also has the scroll bar incase you want to go back up
    terminal_listbox = Listbox(master, width=65, height=13)
    terminal_listbox.place(x=5, y=100)
    terminal_listbox.see(END)
    scrollbar.config(command=terminal_listbox.yview)

    #GUI loops here
    master.mainloop()