2017-04-19 74 views
0

所以,我有需要相互溝通的類。例如,我建立聊天程序的客戶端。一個類處理套接字,另一個類處理GUI。因此,GUI類必須從套接字類中獲取接收到的數據,並且還必須通過套接字類發送消息。類之間的雙向通信python(已編輯+添加代碼)

問題是,如果你讓一個類包含另一個你不能雙向溝通。你需要將父母的一個實例傳遞給孩子但是我不認爲通過這個實例是正確的。

什麼是最好的做什麼呢?

這裏例如一些代碼,希望其明確的(請閱讀代碼中的註釋,以更好地理解):

class MainWindow: 
    def __init__(self, master, username, sock): 
     # Tkinter Code Here 

    def insert_msg(self, data): # d_type 1 - msg 
     self.chat_textbox.insert(END, "\n%s %s" % (datetime.now().strftime('%H:%M:%S'), data)) 
     self.chat_textbox.see(END) 

    def send_msg(self, data, d_type=SEND_ENUM.TYPE_MSG, arg=0): 
     data = str(data) 
     if len(data) >= 1 and d_type == SEND_ENUM.TYPE_MSG: 
      try: 
       self.chat_textbox.insert(END, "\n%s [Me] %s" % (datetime.now().strftime('%H:%M:%S'), data)) 

       # For example, here has to use send_msg method from SockHandler class 
       # self.sock_handler.send_msg(data) 

      except sock_handling.ConnectionError as error: 
       self.chat_textbox.insert(END, "\nError: The message was not delivered", "RED") 
      else: 
       pass 
      finally: 
       self.msg_box_entry.delete(0, 'end') 
       self.chat_textbox.see(END) 
     elif d_type != SEND_ENUM.TYPE_MSG: 
      try: 
       # also here self.sock_handler.send_msg(data, d_type) 
      except sock_handling.ConnectionError as error: 
       pass 
     else: 
      pass 

class SockHandler: 
    def __init__(self, client_socket): 
     # nothing relevant for the Q 

    def send_msg(self, data, d_type=SEND_ENUM.TYPE_MSG, arg=0): 
     packed_data = self.pack_data(d_type, arg, data) 

     if len(data) >= 1 and d_type == SEND_ENUM.TYPE_MSG: 
      try: 
       self.client_socket.send(packed_data) 
      except socket.error: 
       raise ConnectionError("Connection Error") 

      finally: 
       pass 

     elif d_type != SEND_ENUM.TYPE_MSG: 
      try: 
       self.client_socket.send(packed_data) 
      except socket.error: 
       raise ConnectionError("Connection Error") 

    def receive_data(self): 
     try: 
      while True: 
       recv_data = self.client_socket.recv(self.BUFFER) 
       (d_type,), data = struct.unpack("!I", recv_data[:4]), recv_data[4:] 
       if d_type == RECV_ENUM.TYPE_MSG: 

        # For example, here has to use insert_msg method from MainWindow class 

       elif d_type == RECV_ENUM.TYPE_USER_LIST: 
        pass 
       elif d_type == RECV_ENUM.TYPE_POKE: 
        pass 
     except socket.error: 
      self.client_socket.close() 
      raise ConnectionError("Connection Error") 

回答

0

爲什麼不能實例化SockHandler作爲對MainWindow屬性?

像這樣:

class MainWindow: 
    def __init__(self, master, username, sock): 
     # Tkinter Code Here 
     self.socket_handler = SockHandler(sock) 

現在你可以使用self.socket_handler.send_msg

爲了接收來自MainWindow發送郵件,讓您的插座商店獲得其中的MainWindow可以找回數據。

像這樣:

class SockHandler: 
    def __init__(self, client_socket): 
     # nothing relevant for the Q 
     self.received_messages = Queue.Queue() 

現在你需要公開的方式爲MainWindow訪問收到的消息。如果你願意,你可以把它通過查詢隊列直接獲取信息,但我寧願是這樣的:

# Within the SockHandler Class 
def get_next_message(): 
    try: 
     return self.received_messages.get(True, 5) 
    except: 
     return None 

不要緊,如果SockHandlerMainWindow處理此方法中的超時異常。那取決於你。