簡體   English   中英

類python之間的雙向通信(已添加編輯+代碼)

[英]Two-Way communication between classes python (edited + code added)

因此,我有一些需要彼此通信的類。 例如,我建立了聊天程序的客戶端。 一類處理套接字,另一類處理GUI。 因此,GUI類必須從套接字類獲取接收到的數據,此外還必須通過套接字類發送消息。

問題是,如果使一個類包含另一個類,則無法雙向通信。 您需要將父實例傳遞給孩子,但我認為傳遞實例不是正確的方法。

最好的做法是什么?

這里以一些代碼為例,希望它清晰(請閱讀代碼中的注釋以更好地理解):

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

為什么不將SockHandler實例SockHandler MainWindow的屬性?

像這樣:

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

現在您可以使用self.socket_handler.send_msgMainWindow發送消息

為了進行接收,請讓套接字存儲接收到的數據,以便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在此方法中處理Timeout異常無關緊要。 那取決於你。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM