我有下面显示的gui类,供用户编写和接收消息。我在gui中使用tkinder,它在传递接收函数时返回错误:
Exception in thread Thread-1:
Traceback (most recent call last):
File "C:\Python39\lib\threading.py", line 954, in _bootstrap_inner
self.run()
File "C:\Python39\lib\threading.py", line 892, in run
self._target(*self._args,**self._kwargs)
File "C:\Users\Matheus William\Documents\Desenvolvimento\python\trabalho-redes\client.py", line 71, in receive
self.chat_transcript_area.insert('end', '\n{}'.format(message))
AttributeError: 'NoneType' object has no attribute 'insert'
是的,我知道在stackoverflow上也有类似的问题,但我还没有找到任何可以帮助我的东西。谁能帮我我很感激?
守则:
import socket
import threading
import sys
import time
from tkinter import *
from tkinter import messagebox
class Principal:
# Verifica se o nome e os argumentos foram corretamente entrados
if(len(sys.argv) < 3):
print('\n\nUso: python client.py SERVER-IP PORT\n\n')
sys.exit()
host = sys.argv[1]
# Verifica se a porta é um numero inteiro
try:
port = int(sys.argv[2])
except:
print('\n\nForneça a porta do servidor.\n\n')
sys.exit()
# verifica se é possivel conectar com o servidor
try:
# inicia o socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# conecta o usuario ao servidor
client.connect((host, port))
except:
print('\n\nErro ao conectar com o servidor\n\n')
sys.exit()
def __init__(self):
self.chat_transcript_area = None
self.enter_text_widget = None
self.main_account_screen()
def login_verify(self):
global nickname, senha
nickname = self.username_verify.get()
senha = self.password_verify.get()
self.username_login_entry.delete(0, END)
self.password_login_entry.delete(0, END)
if nickname == '' and senha == '':
messagebox.showerror("Erro", "Os campos não pode ficar vazios.")
else:
# recebendo varias mensagens
receive_thread = threading.Thread(target=self.receive)
receive_thread.start()
# valida se os dados de login estão corretos ou
# se o usuario já está logado
id = self.client.recv(4096).decode('utf-8')
if id == str(-1) or id == str(-2):
if id == str(-1):
messagebox.showerror("Erro", "Dados de login invalidos.")
else:
messagebox.showerror("Erro", "Usuario já logado.")
self.client.close()
sys.exit(0)
else:
self.login_screen.destroy()
self.write()
self.login_screen.destroy()
# fazendo uma conexão valida
def receive(self):
while True:
try:
message = self.client.recv(4096).decode('utf-8')
if message == 'NICKNAME':
self.client.send(nickname.encode('utf-8'))
self.client.send(senha.encode('utf-8'))
else:
self.chat_transcript_area.insert(
'end', '\n{}'.format(message))
self.chat_transcript_area.yview(END)
except AssertionError as error:
print("\n\n"+error)
print("Bye bye!")
sys.stderr.write()
break
def on_enter_key_pressed(self, event):
self.sendChat()
self.clear_text()
def clear_text(self):
self.enter_text_widget.delete(1.0, 'end')
def sendChat(self):
data = self.enter_text_widget.get(1.0, 'end').strip()
if data != None:
message = '{}: {}'.format(nickname, data)
self.client.send(message.encode('utf-8'))
# layout da mensagem
def write(self):
self.root = Tk()
self.root.title("Chat")
self.root.protocol("WM_DELETE_WINDOW", self.on_closing_chat)
self.frame = Frame(self.root)
Label(self.frame, text='Chat Box:',
font=("Serif", 12)).pack(side='top')
self.chat_transcript_area = Text(
self.frame, width=60, height=10, font=("Serif", 12))
self.chat_transcript_area.config(state='disabled')
self.scrollbar = Scrollbar(
self.frame, command=self.chat_transcript_area.yview, orient=VERTICAL)
self.chat_transcript_area.config(yscrollcommand=self.scrollbar.set)
self.chat_transcript_area.pack(side='left', padx=10)
self.scrollbar.pack(side='right', fill='y')
self.frame.pack(side='top')
Label(self.root, text='Enter message:',
font=("Serif", 12)).pack(side='top')
self.enter_text_widget = Text(
self.root, width=60, height=1, font=("Serif", 12))
self.enter_text_widget.pack(side='bottom', pady=1)
self.enter_text_widget.bind('<Return>', self.on_enter_key_pressed)
screen_width = self.root.winfo_screenwidth()
screen_height = self.root.winfo_screenheight()
x_cordinate = int((screen_width/2) - (400/2))
y_cordinate = int((screen_height/2) - (270/2))
self.root.geometry(
"{}x{}+{}+{}".format(400, 270, x_cordinate, y_cordinate))
self.root.mainloop()
def on_closing_chat(self):
if messagebox.askokcancel("Sair", "Deseja sair do chat?"):
self.root.destroy()
self.client.close()
exit(0)
def on_closing(self):
if messagebox.askokcancel("Sair", "Deseja sair do login?"):
self.login_screen.destroy()
self.client.close()
exit(0)
# Designing Main(first) window
def main_account_screen(self):
self.login_screen = Tk()
# This code helps to disable windows from resizing
self.login_screen.resizable(False, False)
self.login_screen.protocol("WM_DELETE_WINDOW", self.on_closing)
self.login_screen.title("Login")
Label(self.login_screen, text="Faça o login para usar o chat").pack()
Label(self.login_screen, text="").pack()
self.username_verify = StringVar()
self.password_verify = StringVar()
Label(self.login_screen, text="Username * ").pack()
self.username_login_entry = Entry(
self.login_screen, textvariable=self.username_verify)
self.username_login_entry.pack()
Label(self.login_screen, text="").pack()
Label(self.login_screen, text="Password * ").pack()
self.password_login_entry = Entry(
self.login_screen, textvariable=self.password_verify, show='*')
self.password_login_entry.pack()
Label(self.login_screen, text="").pack()
Button(self.login_screen, text="Login", width=10,
height=1, command=self.login_verify).pack()
screen_width = self.login_screen.winfo_screenwidth()
screen_height = self.login_screen.winfo_screenheight()
x_cordinate = int((screen_width/2) - (300/2))
y_cordinate = int((screen_height/2) - (210/2))
self.login_screen.geometry(
"{}x{}+{}+{}".format(300, 210, x_cordinate, y_cordinate))
self.login_screen.mainloop()
Principal()
1条答案
按热度按时间goqiplq21#
->
receive_thread = threading.Thread(target=self.receive)
你打电话给self.receive
调用前的函数self.write
.