tkinder text attributeerror:'nonetype'对象没有属性'insert'

fiei3ece  于 2021-09-08  发布在  Java
关注(0)|答案(1)|浏览(454)

我有下面显示的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()
goqiplq2

goqiplq21#

-> receive_thread = threading.Thread(target=self.receive) 你打电话给 self.receive 调用前的函数 self.write .

...
receive_thread = threading.Thread(target=self.receive)
...
else:
    self.login_screen.destroy()
    self.write()
...
``` `self.chat_transcript_area` 还是 `None` 现阶段。
必须先创建文本小部件,然后才能尝试向其写入任何内容。

相关问题