2017-05-12 3 views
0

So drucken, ich habe einen Server komplett in Python geschrieben 2.7:ständig Daten von einem Server aktualisieren und zu einem Textfeld

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 

Was ich tun muß, ist ständiges Updates für Daten (Nachrichten) erhalten von der Server und drucken sie in ein Textfeld in Tkinter.

Der Empfangscode:

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 

Es muss nicht Tkinter, aber das ist das, was ich in versucht; solange es eine GUI verwendet. Mach dir keine Sorgen über das Senden von Nachrichten, die ich nur in der Lage sein muss, die Daten zu erhalten und sie in das Textfeld/den Bereich zu drucken.

Antwort

1

Ich wollte einen Kommentar zunächst vorlegen aber einen Versuch geben:

Sie etwas anderes als eine Start-Taste verwenden können, um Dinge geht für einfache Bedienung

ich es nur dort gesetzt
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() 
+0

In diesem speziellen Fall ist der Aufruf von 'update' sehr notwendig. Ohne sie kann tkinter keine Ereignisse verarbeiten. Wenn Ereignisse (einschließlich Ereignisse, die eine Aktualisierung des Fensters auslösen) nicht verarbeitet werden können, können die Daten nicht angezeigt werden. –

2

Das Grundgerüst besteht darin, zunächst alle Widgets zu erstellen. Schreiben Sie als Nächstes eine Funktion, die die Daten liest und die Benutzeroberfläche aktualisiert. Stellen Sie schließlich sicher, dass diese Funktion alle paar Millisekunden aufgerufen wird.

Grob gesagt, sieht es so etwas wie diese:

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

Wenn die Daten nicht ein stetiger Strom ist, die sock.recv(1024) verursacht zu blockieren, UI gefriert, während sie auf Daten warten wird. Wenn dies der Fall ist, können Sie das Lesen des Sockets in einen Thread verschieben und den Thread über eine Thread-sichere Warteschlange mit der GUI kommunizieren lassen.

Wenn die Daten in einem stetigen Stream vorliegen oder Sie einen nicht blockierenden Socket einrichten, müssen Sie nichts tun.

+0

Up 1 für Thread-sichere Warteschlangen- und Tkinter-GUI-Aktualisierung. Der beste Weg zu gehen. – pstatix

Verwandte Themen