0

I have a chat window for the client portion of a chat application that uses Tkinter for the GUI:

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

I want the updating() function and the tryrecvmessage() function to run simultaneously, so that the GUI continues to update while the client still receives messages from the server. I've tried using the threading module as well, but I need to have the threads created below where the other functions are defined, but the other functions need to be defined below __init__(). What do I do?

Theo
  • 115
  • 8

1 Answers1

0

You can attach the functions to the Tk event loop using the after method, as I explained in this question. Essentially the syntax for after goes like this:

after(ms, command = [function object])

What it does is attach the function object passed in as the command argument to the Tk event loop, repeating it each time ms milliseconds has passed.

One caveat here: you would want to remove the while True from the functions as after would be constantly repeating them anyway.

Community
  • 1
  • 1
Ecko
  • 1,030
  • 9
  • 30