I'm making a python chat app for a school project based on code I found on a youtube video. I apologise if this seems rudimentary, but I'm still a beginner. The program consists of two files, a server.py file and a client.py file. So far, the server has run just fine, but the client.py file cannot run for the life of me. Every time I try to execute it, I am met with the following errors:
line 87, in <module>
client = Client()
TypeError: __init__() missing 1 required positional argument: 'server'
Here's the code for the client.py:
from operator import truediv
import socket
import threading
import tkinter
import tkinter.scrolledtext
from tkinter import simpledialog
class Client:
def __init__(self, server):
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server.connect(('localhost', 1234))
msg = tkinter.Tk()
msg.withdraw()
self.nickname = simpledialog.askstring("Nickname", "Please choose a nickname", parent=msg)
self.gui_done = False
self.running = True
gui_thread = threading.Thread(targer=self.gui_loop)
receive_thread = threading.Thread(targer=self.receive)
gui_thread.start()
receive_thread.start()
def gui_loop(self):
self.win = tkinter.Tk()
self.win.configure(bg="lightgray")
self.chat_label = tkinter.Label(self.win, text="Chat:", bg="lightgray")
self.chat_label.config(font=("Arial", 12))
self.chat_label.pack(padx=20, pady=5)
self.text_area = tkinter.scrolledtext.tkinter.scrolledtext.ScrolledText
self.text_area.pack(padx=20, pady=5)
self.text_area.config(state='disabled')
self.msg_label = tkinter.Label(self.win, text="Message:", bg="Lightgray")
self.msg_label.config(font=("Arial", 12))
self.msg_label.pack(padx=20, pady=5)
self.input_area = tkinter.Text(self.win, height=3)
self.input_area.pack(padx=20, pady=5)
self.send_button = tkinter.Button(self.win, text="Send", command=self.write)
self.send_button.config(font=("Arial", 12))
self.end_button.pack(padx=20, pady=5)
self.gui_done = True
self.win.protocol("WM_DELETE_WINDOW", self.stop)
self.win.mainloop()
def write(self):
message =f"{self.nickname}: {self.input_area.get('1.0', 'end')}"
def stop(self):
self.running = False
self.win.destroy()
self.server.close()
exit(0)
def receive(self):
while self.running:
try:
message = self.sock.recv(1024).decode('utf-8')
if message == 'NICKNAME':
self.server.send(self.nickname.encode('utd-8'))
else:
if self.gui_done:
self.text_area.config(state='normal')
self.text_area.insert('end', message)
self.text_area.yview('end')
self.text_area.config(state='disabled')
except ConnectionAbortedError:
break
except:
print("Error")
self.server.close()
break
client = Client()
My biggest issue is that 'server' is within the brackets of Client. Another issue is that for some reason, the last line doesn't seem to call the class.
Change the Client's init()
method by removing the server
argument, it is absolutely useless, as inside the constructor the server
variable gets declared & initialized without the need of getting passed a server-instance from outside.
Thus, simply try:
class Client:
def __init__(self): # remove the argument after 'self'
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server.connect(('localhost', 1234))
#...