2016-05-19 43 views
0

運行多個功能我有用於使用Tkinter的用於GUI一個聊天應用程序的客戶機部分聊天窗口:Python 3中的Tkinter一次

import socket 
import select 
import time 
from threading import Thread 
from multiprocessing import Process 
import sys 
from tkinter import * 

HOST = "localhost" 
PORT = 5678 

client_socket = socket.socket() 
client_socket.settimeout(2) 

try: 
    client_socket.connect((HOST, PORT)) 
except: 
    print("Connection failed.") 
    sys.exit() 
print("Connected to [" + str(HOST) + "," + str(PORT) + "] successfully") 


class ChatWindow: 
    def __init__(self): 
     form = Tk() 
     form.minsize(200, 200) 
     form.resizable(0, 0) 
     form.title("Chat") 

     box = Entry(form) 

     form.bind("<Return>", lambda x: self.sendmessage(self.textbox.get())) 

     area = Text(form, width=20, height=10) 

     area.config(state=DISABLED) 

     area.grid(row=0, column=1, padx=5, pady=5, sticky=W) 
     box.grid(row=1, column=1, padx=5, pady=5, sticky=W) 

     self.textbox = box 
     self.textarea = area 

     p1 = Process(target=updating) 
     p1.start() 
     p2 = Process(target=tryrecvmessage) 
     p2.start() 

    def addchat(self, msg, clear=False): 
     self.textarea.config(state=NORMAL) 
     self.textarea.insert(END, msg + "\n") 
     if clear: 
      # Option to clear text in box on adding 
      self.textbox.delete(0, END) 
     self.textarea.see(END) 
     self.textarea.config(state=DISABLED) 

    def sendmessage(self, msg): 
     data = str.encode(msg) 
     client_socket.send(data) 
     self.addchat("<You> " + msg, True) 

    def updating(self): 
     while True: 
      form.update() 
      form.update_idletasks() 
      time.sleep(0.01) 

    def tryrecvmessage(self): 
     while True: 
      read_sockets, write_sockets, error_sockets = select.select([client_socket], [], []) 
      for sock in read_sockets: 
       data = sock.recv(4096) 
       if data: 
        self.addchat(data) 
       else: 
        self.addchat("Disconnected...") 
        sys.exit() 

if __name__ == "__main__": 
    window = ChatWindow() 

我希望updating()功能和tryrecvmessage()功能同時運行,以便在客戶端仍然接收來自服務器的消息時GUI繼續更新。我也嘗試過使用threading模塊,但我需要在下面創建的線程定義其他功能,但其他功能需要定義在__init__()以下。我該怎麼辦?

+0

發生了什麼呢? –

回答

0

您可以使用after方法將函數附加到Tk事件循環中,如我在this question中所解釋的。本質上after的語法是這樣的:

after(ms, command = [function object]) 

它的作用是連接傳遞爲command參數傳遞給Tk事件循環函數對象,ms毫秒已通過每次重複它。

一個警告在這裏:你會想從功能中刪除while True,因爲after會不斷重複它們。

+0

他不能在'tryrecvmessage'上做到這一點,因爲從套接字服務器接收數據可能需要很長時間,這將阻止他的主窗口運行。 –

+0

這就是我的想法。你有什麼建議? – Theo