Класс не может найти свою переменную

Рейтинг: 0Ответов: 1Опубликовано: 17.06.2023

Я никак не могу понять как так выходит, что после объявления self.display_text = tk.StringVar() в __init__() , она пропадает.. Подскажите пожалуйста:

from tkinter import *
import tkinter as tk

import client
import json


class ClientWindow:
    def __init__(self, clientCode):
        self.clientCode = clientCode

        self.window_client = Tk()

        self.window_client.title("Клиент "+self.clientCode.client_info)  
        self.window_client.geometry('960x480') # 12 колонок в длину и 33 в ширь

        self.common_frame_client = Frame(self.window_client, width=300)
        self.common_frame_client.pack(anchor=SE, side=BOTTOM, padx=10, pady=10)

        self.btn_clien = tk.Button(self.common_frame_client, text="send", command=self.clicked(), width=10, height=1)
        self.btn_clien.pack(side=RIGHT, padx=10)

        self.entry_to_clien = tk.Entry(self.common_frame_client, width=300, font="Helvetica 12")
        self.entry_to_clien.pack(side=LEFT)

        self.display_text = tk.StringVar()
        self.display_client = tk.Label(self.window_client, textvariable=self.display_text, borderwidth=2, relief="groove", width=300, height=100, anchor=NW)
        self.display_client.pack()

        self.window_client.protocol('WM_DELETE_WINDOW', lambda: self.on_close_window_client())
        self.window_client.mainloop()

    def on_close_window_client(self):
        self.window_client.destroy()

    def clicked(self):
        self.add_text_to_display("Complite!")
        self.command = self.entry_to_clien.get()
        self.clientCode.command_to_client(self.command, self.add_text_to_display)

    def add_text_to_display(self, new_line):
        self.line = self.display_text.get()
        self.line += new_line
        self.display_text.set(self.line)

Код ошибки:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Python311\Lib\tkinter\__init__.py", line 1948, in __call__
    return self.func(*args)
           ^^^^^^^^^^^^^^^^
  File "C:\Users\user\Desktop\Сервер\server_window.py", line 48, in <lambda>
    btn = tk.Button(common_frame, text="send", command=lambda: clicked(add_text_to_display), width=10, height=1)
                                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\user\Desktop\Сервер\server_window.py", line 22, in clicked
    server.client_connect(client_number, add_text_to_display)
  File "C:\Users\user\Desktop\Сервер\server.py", line 110, in client_connect
    ClientWindow(clientCode)
  File "C:\Users\user\Desktop\Сервер\client_window.py", line 29, in __init__
    self.btn_clien = tk.Button(self.common_frame_client, text="send", command=self.clicked(), width=10, height=1)
                                                                              ^^^^^^^^^^^^^^
  File "C:\Users\user\Desktop\Сервер\client_window.py", line 49, in clicked
    self.add_text_to_display("Complite!")
  File "C:\Users\user\Desktop\Сервер\client_window.py", line 55, in add_text_to_display
    line = self.display_text.get()

Ответы

▲ 0

Бесит, но дело в том, что я допустил ошибку, я вызвал clicked() прям в кнопке(рукаизжопа):

self.btn_clien = tk.Button(self.common_frame_client, text="send", command=self.clicked(), width=10, height=1)
self.btn_clien.pack(side=RIGHT, padx=10)

Что и привело к тому, что кнопка создалась, а StringVar нет, т.к код метода запустился первее чем код объявления StringVar

Также я заметил, что во фрейме кнопка справа объявлена после поля ввода которое слева и это в моём случае ошибка, должно быть наоборот, вот так:

self.btn_client = tk.Button(self.common_frame_client, text="send", command=self.client_clicked, width=10, height=1)
self.btn_client.pack(side=RIGHT, padx=10)

self.entry_to_client = tk.Entry(self.common_frame_client, width=300, font="Helvetica 12")
self.entry_to_client.pack(side=LEFT)

Причина в том, что поле ввода в ширину аж 300(вроде пикселей) и этого достаточно, чтобы перекрыть созданную перед этим кнопку