| @ -1,94 +1,61 @@ | |||||
| #!/usr/bin/env python3.7 | #!/usr/bin/env python3.7 | ||||
| import tkinter | |||||
| import threading | import threading | ||||
| from ChatConnection import ChatConnection | from ChatConnection import ChatConnection | ||||
| class ChatInterface(object): | class ChatInterface(object): | ||||
| def __init__(self, connection: ChatConnection): | |||||
| def __init__(self, | |||||
| connection: ChatConnection, | |||||
| name: str = '<anonymous>'): | |||||
| # set connection to use | # set connection to use | ||||
| self.connection = connection | self.connection = connection | ||||
| self.name = name | |||||
| # initialise tkinter window | |||||
| self.window = tkinter.Tk() | |||||
| self.window.title("Chatter") # window title | |||||
| # set method to trigger when window is close | |||||
| self.window.protocol("WM_DELETE_WINDOW", self.close) | |||||
| # end of window initialisation | |||||
| # initialise message frame | |||||
| self.messagesFrame = tkinter.Frame(self.window) | |||||
| # # add scrollBar to see previously recovered messages | |||||
| self.scrollBar = tkinter.Scrollbar(self.messagesFrame) | |||||
| self.scrollBar.pack(side=tkinter.RIGHT, fill=tkinter.Y) | |||||
| # # add messagesList to print recovered messages | |||||
| self.messagesList = tkinter.Listbox( | |||||
| self.messagesFrame, height=15, width=50, yscrollcommand=self.scrollBar.set) | |||||
| self.messagesList.pack(side=tkinter.LEFT, fill=tkinter.BOTH) | |||||
| self.messagesList.pack() | |||||
| self.messagesFrame.pack() | |||||
| # end of message frame initialisation | |||||
| # initialise input | |||||
| self.input = tkinter.StringVar() | |||||
| self.input.set("Type your messages here.") | |||||
| # # initialise input frame | |||||
| self.inputFrame = tkinter.Entry(self.window, textvariable=self.input) | |||||
| self.inputFrame.bind("<Return>", self.send) | |||||
| self.inputFrame.pack() | |||||
| # # initialise send button | |||||
| self.sendButton = tkinter.Button( | |||||
| self.window, text="Send", command=self.send) | |||||
| self.sendButton.pack() | |||||
| # end of input initialisation | |||||
| def close(self, event=None) -> None: | |||||
| """ | |||||
| Set input to ':quit' and trigger send method | |||||
| """ | |||||
| self.input.set(":quit") | |||||
| self.send() | |||||
| def send(self, event=None) -> None: | |||||
| def send(self, msg) -> None: | |||||
| """ | """ | ||||
| Send message to connection | Send message to connection | ||||
| """ | """ | ||||
| msg = self.input.get() | |||||
| self.connection.send(msg) | |||||
| # check if input is quit command | # check if input is quit command | ||||
| if msg != ':quit': | |||||
| # clear the input bar | |||||
| self.input.set('') | |||||
| # output the client message to message list | |||||
| self.messagesList.insert(tkinter.END, '[YOU] {}'.format(msg)) | |||||
| # send the message to connection | |||||
| self.connection.send(msg) | |||||
| else: | |||||
| # close the connection and window | |||||
| self.connection.close() | |||||
| self.window.quit() | |||||
| if self.connection.isOpen: | |||||
| if msg[0] == '/': | |||||
| cmd = msg[1:5] | |||||
| if cmd == 'quit': | |||||
| self.connection.close() | |||||
| elif cmd == 'name': | |||||
| tmp = msg.split() | |||||
| if len(tmp) == 2: | |||||
| self.name = tmp[1] | |||||
| def listener(self) -> None: | def listener(self) -> None: | ||||
| """ | """ | ||||
| Listener method to keep receiving new message from | Listener method to keep receiving new message from | ||||
| connection | connection | ||||
| """ | """ | ||||
| while True: | |||||
| try: | |||||
| # receive messages from connection | |||||
| msg = self.connection.recv() | |||||
| # add recevied message to message list | |||||
| self.messagesList.insert(tkinter.END, msg[:-1]) | |||||
| except OSError: | |||||
| break | |||||
| while self.connection.isOpen: | |||||
| # receive messages from connection | |||||
| msg = self.connection.recv() | |||||
| if len(msg) > 0: | |||||
| # add recevied message to message list | |||||
| print('\r' + | |||||
| msg + | |||||
| '\n' + | |||||
| '[ME({})]: '.format(self.name), end='') | |||||
| else: | |||||
| self.connection.close() | |||||
| def start(self) -> None: | def start(self) -> None: | ||||
| """ | |||||
| Start background listener and tkinter.mainloop | |||||
| """ | |||||
| # initialise background listener as daemon thread | # initialise background listener as daemon thread | ||||
| backgroundListener = threading.Thread(target=self.listener) | backgroundListener = threading.Thread(target=self.listener) | ||||
| backgroundListener.daemon = True | backgroundListener.daemon = True | ||||
| backgroundListener.start() | backgroundListener.start() | ||||
| # start tkinter main loop and open the GUI window | |||||
| tkinter.mainloop() | |||||
| self.send('/name {}'.format(self.name)) | |||||
| while self.connection.isOpen: | |||||
| try: | |||||
| msg = input('[ME({})]: '.format(self.name)) | |||||
| except (EOFError, KeyboardInterrupt): | |||||
| msg = '/quit' | |||||
| finally: | |||||
| self.send(msg) | |||||