#python #python-3.x #oop #tkinter
#python #python-3.x #ооп #tkinter
Вопрос:
У меня проблема с использованием tkinter и объектно-ориентированного программирования. У меня есть 3 функции:
-
Сначала у меня есть
v2()
функция, которая позволяет открывать второе окно с помощью кнопки и отображать данные, сохраненные в базе данных -
Моя вторая функция
agregar_postulantes()
. Эта функция сохраняет данные в базе данных. -
Моя третья функция — это та, которая сохраняет данные
agregar_postulantes()
и отправляет их вv2()
функцию.
Я хочу подчеркнуть, что все функции находятся в одном классе и объявлены вне __init__()
.
Краткая версия кода:
def v2(self):
self.tabla_postulante=ttk.Treeview(tablaBD,columns=("Name","last name","id")
self.tabla_postulante.heading("Name",text="Name")
self.tabla_postulante.heading("last name",text="last name")
self.tabla_postulante.heading("id",text="id")
self.tabla_postulante['show']='headings'
self.tabla_postulante.column("Name",width=100)
self.tabla_postulante.column("last name",width=100)
self.tabla_postulante.column("id",width=100)
self.fetch_all()
self.tabla_postulante.pack(fill=BOTH,expand=1)
def agregar_postulantes(self):
con = pymysql.connect(host="localhost", user="root",password="", database="postulantebd")
cur = con.cursor()
cur.execute("insert into postulantes values(%s, %s, %s)",(
self.name_var.get(),
self.lastname_var.get(),
self.id_var.get(),
))
con.commit()
self.fetch_all()
con.close()
def fetch_all(self):
con = pymysql.connect(host="localhost", user="root",password="", database="postulantebd")
cur = con.cursor()
cur.execute("select * from postulantes")
rows=cur.fetchall()
if len(rows)!=0:
self.tabla_postulante.delete(*self.tabla_postulante.get_children())
for row in rows:
self.tabla_postulante.insert('',END,values=row)
con.commit()
con.close()
Появляется следующая ошибка:
Traceback (most recent call last):
File "C:UsersdimitriAppDataLocalProgramsPythonPython36-32libtkinter__init__.py", line 1705, in __call__
return self.func(*args)
File "C:UsersdimitriDocumentsProgramas de Yolopracticadeinterfazypootkinterinterfaz_tesis_poo.py", line 273, in agregar_postulantes
self.fetch_all()
File "C:UsersdimitriDocumentsProgramas de Yolopracticadeinterfazypootkinterinterfaz_tesis_poo.py", line 282, in fetch_all
self.tabla_postulante.delete(*self.tabla_postulante.get_children())
AttributeError: 'postulante' object has no attribute 'tabla_postulante'
ошибка связана с тем, что я вызываю функцию v2 после сохранения данных с использованием двух других функций
Как я могу v2
впоследствии вызвать функцию и не показывать ошибки?
Комментарии:
1. Вам необходимо вызвать
v2
, который создаетtabla_postulante
перед другими методами, которые его используют. Из этого примера неясно, был ли выполнен этот вызов.2. Неясно ли сообщение об ошибке? Например, вы понимаете, что такое an
attribute
?3. Я думаю, что tabla_postulante является атрибутом, объявленным в версии 2.
Ответ №1:
Кажется вероятным, что, как AttributeError
указано, self
не имеет tabla_postulante
атрибута. Поскольку вы создаете table_postulante
атрибут self
в v2
функции, я бы предположил, что вы не определяете self.table_postulante
в __init__()
or, который вы не вызываете v2()
перед вызовом fetch_all()
.
Что должно означать, что у вас есть пара вариантов:
-
создайте некоторую логику,
fetch_all()
которая проверяет наличиеself.tabla_postulante
и выполняется только в том случае, если этот атрибут найден. Это может принимать формуtry
except
оператора / . -
В качестве альтернативы, определите
self.tabla_postulante
атрибут в вашем вызове__init__()
при создании экземпляра объекта.
Обновить
Немного подробнее о реализации того, что я описал выше. Я предполагаю, что вы не создаете self.tabla_postulante
атрибут для своего класса в __init__()
, поскольку, если бы вы были, вы бы не получали a ValueError
, когда функция ищет его.
Итак, это дает вам пару вариантов. Можно было бы просто убедиться, что при создании экземпляра вашего класса __init__()
создается такой self.table_postulante
атрибут:
class ClassName:
def __init__(self):
#create attribute here
self.table_postulante = ttk.Treeview(tablaBD,columns=("Name", "last name","id")
...
Другой вариант, если это не имеет смысла для разрабатываемого вами приложения, — выполнить некоторую обработку исключений внутри fetch_all()
. Например, вы могли бы сделать что-то вроде:
if len(rows)!=0:
try:
self.tabla_postulante.delete(*self.tabla_postulante.get_children())
for row in rows:
self.tabla_postulante.insert('',END,values=row)
con.commit()
except:
#define some appropriate response to this attribute not existing here
Ваш вариант использования, конечно, определит, какой подход имеет наибольший смысл. Надеюсь, это поможет.
Комментарии:
1. вы правы, я вызываю 2-ю и 3-ю функции перед использованием первой. не могли бы вы быть немного более конкретными для проверки? Я новичок
2. Абсолютно! Я добавлю это в ответ, чтобы я мог воспользоваться Markdown, чтобы сделать его красивым.