некорректно выводятся элементы таблицы БД через Tkinter
Приложение, созданное на Tkinter, представляет из себя таблицу БД, должно показывать данные типов text и integer, но выдает набор некорректных символов после того как принимает и сохраняет таблицу
import tkinter as tk
from tkinter import filedialog
import pandas as pd
import matplotlib
matplotlib.use("TkAgg")
import matplotlib.pyplot as plt
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2Tk)
from tkinter import ttk
import sqlite3
# Cоздание главного окна
class Main(tk.Frame):
def __init__(self, root):
super().__init__(root)
self.init_main()
self.db = db
self.view_records()
# Функция-конструктор главного окна
def init_main(self):
# Создание области функций-инструментов добавления окон
toolbar = tk.Frame(bg='#d7d7d7', bd=2)
toolbar.pack(side=tk.TOP, fill=tk.X)
# Создание графической визуализации функции-инструмента поиска месяца
self.add_img = tk.PhotoImage(file='C:/Users/Maxim/Documents/Python/UpdDB/2891642.png')
btn_add = tk.Button(toolbar, bg='#d7d7d7', bd=0, image=self.add_img, command=self.open_dialog)
btn_add.pack(side=tk.LEFT)
self.create_boxplot = tk.PhotoImage(file='C:/Users/Maxim/Documents/Python/UpdDB/3281111.png')
btn_add = tk.Button(toolbar, bg='#d7d7d7', bd=0, image=self.create_boxplot, command=self.create)
btn_add.pack(side=tk.LEFT)
# Создание графической визуализации функции-инструмента редактирования месяца
self.edit_img = tk.PhotoImage(file='C:/Users/Maxim/Documents/Python/UpdDB/1827951.png')
btn_edit = tk.Button(toolbar, bg='#d7d7d7', bd=0, image=self.edit_img, command=self.open_edit)
btn_edit.pack(side=tk.LEFT)
# Создание графической визуализации функции-инструмента удаления месяца
self.del_img = tk.PhotoImage(file='C:/Users/Maxim/Documents/Python/UpdDB/3221803.png')
btn_del = tk.Button(toolbar, bg='#d7d7d7', bd=0, image=self.del_img, command=self.delete_records)
btn_del.pack(side=tk.LEFT)
# Создание графической визуализации функции-инструмента поиска месяца
self.search_img = tk.PhotoImage(file='C:/Users/Maxim/Documents/Python/UpdDB/711319.png')
btn_search = tk.Button(toolbar, bg='#d7d7d7', bd=0, image=self.search_img, command=self.open_search)
btn_search.pack(side=tk.LEFT)
# Создание графической визуализации функции-инструмента обновления месяца
self.refresh_img = tk.PhotoImage(file='C:/Users/Maxim/Documents/Python/UpdDB/64056.png')
btn_refresh = tk.Button(toolbar, bg='#d7d7d7', bd=0, image=self.refresh_img, command=self.view_records)
btn_refresh.pack(side=tk.LEFT)
# Создание таблицы
self.tree = ttk.Treeview(root, columns=('id', 'month', 'revenue', 'income', 'prod_costs', 'indirect_costs', 'loan_percents', 'inc_tax', 'depreciation', 'path'), height=45, show='headings')
# Добавление параметров столбцов
self.tree.column('id', width=45, anchor=tk.CENTER)
self.tree.column('month', width=150, anchor=tk.CENTER)
self.tree.column('revenue', width=300, anchor=tk.CENTER)
self.tree.column('income', width=150, anchor=tk.CENTER)
self.tree.column('prod_costs', width=150, anchor=tk.CENTER)
self.tree.column('indirect_costs', width=150, anchor=tk.CENTER)
self.tree.column('loan_percents', width=150, anchor=tk.CENTER)
self.tree.column('inc_tax', width=150, anchor=tk.CENTER)
self.tree.column('depreciation', width=150, anchor=tk.CENTER)
self.tree.column('path', width=150, anchor=tk.CENTER)
self.tree.heading('id', text='id')
self.tree.heading('month', text='Дата')
self.tree.heading('revenue', text='Выручка')
self.tree.heading('income', text='Чистая прибыль')
self.tree.heading('prod_costs', text='Производственные расходы')
self.tree.heading('indirect_costs', text='Косвенные расходы')
self.tree.heading('loan_percents', text='Проценты по кредиту')
self.tree.heading('inc_tax', text='Налог на прибыль')
self.tree.heading('depreciation', text='Амортизация')
self.tree.heading('path', text='Файл')
self.tree.pack(side=tk.LEFT)
scroll = tk.Scrollbar(root, command=self.tree.yview)
scroll.pack(side=tk.LEFT, fill=tk.Y)
self.tree.configure(yscrollcommand=scroll.set)
# Функция-инструмент записи
def records(self, month, revenue, income, prod_costs, indirect_costs, loan_percents, inc_tax, depreciation, path):
self.db.insert_data(month, revenue, income, prod_costs, indirect_costs, loan_percents, inc_tax, depreciation, path)
self.view_records()
# Функция-инструмент редактирования
def edit_record(self, month, revenue, income, prod_costs, indirect_costs, loan_percents, inc_tax, depreciation, path):
ind = self.tree.set(self.tree.selection()[0], '#1')
self.db.cur.execute('''
UPDATE econometrics SET month = ?, revenue = ?, income = ?, prod_costs = ?, indirect_costs = ?, loan_percents = ?, inc_tax = ?, depreciation = ?, path =?
WHERE id = ? ''', (month, revenue, income, prod_costs, indirect_costs, loan_percents, inc_tax, depreciation, path, ind), )
self.db.conn.commit()
self.view_records()
# Функция-инструмент удаления выделенной строки в таблице
def delete_records(self):
for i in self.tree.selection():
id = self.tree.set(i, '#1')
self.db.cur.execute('''
DELETE FROM econometrics
WHERE id = ?
''', (id, ))
self.db.conn.commit()
self.view_records()
# Функция-инструмент поиска
def search_records(self, month):
[self.tree.delete(i) for i in self.tree.get_children()]
self.db.cur.execute("""SELECT * FROM econometrics WHERE month LIKE ?""",
('%' + month + '%',))
[self.tree.insert('', 'end', values=i) for i in self.db.cur.fetchall()]
def create(self):
Creating_boxplot(root)
# Вызов придаточного окна
def open_dialog(self):
Additional(root)
# Вызов окна редактирования
def open_edit(self):
Update()
def open_search(self):
Search(root)
def view_records(self):
self.db.cur.execute("""SELECT * FROM econometrics""")
[self.tree.delete(i) for i in self.tree.get_children()]
[self.tree.insert('', 'end', values=i) for i in self.db.cur.fetchall()]
def boxplotting(self, month):
month = ('%' + month + '%')
path = db.cur.execute("""SELECT path FROM econometrics WHERE month LIKE ?""", (month, ))
df = pd.read_excel(path)
fig = Figure(figsize=(20, 10), dpi=1000)
ax = fig.add_subplot(111)
labels = df.columns.tolist()
red_circle = dict(markerfacecolor='mediumseagreen', marker= 'o')
mean_shape = dict(markerfacecolor='green', marker= '+')
ax.set_ylabel('Значения (руб.)')
bplot = ax.boxplot(df,
patch_artist=True,
vert=True,
flierprops=red_circle,
showmeans=True,
meanprops=mean_shape,
tick_labels=labels,
notch=True)
bplot.set_facecolor('black')
for boxes in zip(bplot['boxes']):
boxes.set_facecolor('turquoise')
canvas1 = FigureCanvasTkAgg(fig, master = app)
canvas1.draw()
canvas1.get_tk_widget().pack(side='top', fill=None, expand=0)
app.after(200, None)
# Создание придаточного окна
class Additional(tk.Toplevel):
def __init__(self, root):
super().__init__(root)
self.init_additional()
self.view = app
# Функция-конструктор придаточного окна
def init_additional(self):
self.title('Добавление информации по месяцу')
self.geometry('450x200')
# Запрет на изменение размеров окна
self.resizable(False, False)
# Установка перехвата всех событий приложения
self.grab_set()
# Установка захвата фокуса
self.focus_set()
# Создание графической визуализации таблицы
filename = filedialog.askopenfilename(title="Выберите файл", filetype=(("Excel", "*.xlsx"), ("Excel", "*.xls"), ("Excel", "*.csv")))
path = filename
df = pd.read_excel(path)
df = df.assign(Чистая_прибыль = df['Выручка'] - (df['Производственные_расходы']+ df['Косвенные_расходы']+ df['Налог_на_прибыль'] + df['Проценты_по_кредитам'] + df['Амортизация']))
label_month = tk.Label(self, text='Месяц')
label_month.place(x=50, y=50)
self.entry_month = tk.Entry(self)
self.entry_month.place(x=200, y=50)
self.entry_revenue = df['Выручка'].sum()
self.entry_income = df['Чистая_прибыль'].sum()
self.entry_prod_costs = df['Производственные_расходы'].sum()
self.entry_indirect_costs = df['Косвенные_расходы'].sum()
self.entry_loan_percents = df['Проценты_по_кредитам'].sum()
self.entry_inc_tax = df['Налог_на_прибыль'].sum()
self.entry_depreciation = df['Амортизация'].sum()
self.entry_path = path
self.btn_ok = tk.Button(self, text='Добавить')
self.btn_ok.bind('<Button-1>', lambda ev: self.view.records(self.entry_month.get(),
self.entry_revenue,
self.entry_income,
self.entry_indirect_costs,
self.entry_prod_costs,
self.entry_loan_percents,
self.entry_inc_tax,
self.entry_depreciation,
self.entry_path))
self.btn_ok.place(x=300, y=160)
btn_cancel = tk.Button(self, text='Закрыть', command=self.destroy)
btn_cancel.place(x=220, y=160)
class Update(Additional):
def __init__(self):
super().__init__(root)
self.db = db
self.init_edit()
self.load_data()
def init_edit(self):
self.title('Изменение текущей информации')
# Удаление функции-инструмента добавления
self.btn_ok.destroy()
# Добавление функции-инструмента редактирования
self.btn_ok = tk.Button(self, text='Редактировать')
self.btn_ok.bind('<Button-1>',
lambda ev: self.view.edit_record(
self.entry_month.get(),
self.entry_revenue,
self.entry_income,
self.entry_prod_costs,
self.entry_indirect_costs,
self.entry_loan_percents,
self.entry_inc_tax,
self.entry_depreciation,
self.entry_path))
self.btn_ok.bind('<Button-1>', lambda ev: self.destroy(), add='+')
self.btn_ok.place(x=300, y=160)
# Функция-инструмент заполнения старыми данными
def load_data(self):
self.db.cur.execute('''SELECT * FROM econometrics WHERE id = ? ''',
self.view.tree.set(self.view.tree.selection()[0], '#1'))
row = self.db.cur.fetchone()
self.entry_month.insert(0, row[1])
self.entry_revenue.insert(0, row[2])
self.entry_income.insert(0, row[3])
self.entry_prod_costs.insert(0, row[4])
self.entry_indirect_costs.insert(0, row[5])
self.entry_loan_percents.insert(0, row[6])
self.entry_inc_tax.insert(0, row[7])
self.entry_depreciation.insert(0, row[8])
self.entry_path.insert(0, row[9])
# Создание поискового окна
class Search(tk.Toplevel):
def __init__(self, root):
super().__init__(root)
self.init_search()
self.view = app
# Функция-конструктор окна поиска
def init_search(self):
self.title('Поиск по дате')
self.geometry('300x100')
# Запрет на изменение размеров окна
self.resizable(False, False)
# Установка перехвата всех событий приложения
self.grab_set()
# Установка захвата фокуса
self.focus_set()
# Создание графической визуализации окна поиска
label_month = tk.Label(self, text='Дата')
label_month.place(x=50, y=30)
label_month.pack(anchor='nw', padx=6, pady=6)
self.entry_month = tk.Entry(self)
self.entry_month.place(x=150, y=30)
self.entry_month.pack(anchor='nw', padx=6, pady=6)
self.btn_ok = tk.Button(self, text='Найти')
self.btn_ok.bind('<Button-1>', lambda ev: self.view.search_records(self.entry_month.get()))
self.btn_ok.bind('<Button-1>', lambda ev: self.destroy(), add='+')
self.btn_ok.place(x=230, y=70)
btn_cancel = tk.Button(self, text='Закрыть', command=self.destroy)
btn_cancel.place(x=160, y=70)
class Creating_boxplot(tk.Toplevel):
def __init__(self, root):
super().__init__(root)
self.db = db
self.init_creating()
self.view = app
def init_creating(self):
self.title('Создание графика')
self.geometry('300x100')
# Запрет на изменение размеров окна
self.resizable(False, False)
# Установка перехвата всех событий приложения
self.grab_set()
# Установка захвата фокуса
self.focus_set()
label_month = tk.Label(self, text='Дата')
label_month.place(x=50, y=30)
label_month.pack(anchor='nw', padx=6, pady=6)
self.entry_month = tk.Entry(self)
self.entry_month.place(x=150, y=30)
self.entry_month.pack(anchor='nw', padx=6, pady=6)
self.btn_ok = tk.Button(self, text='Создать')
self.btn_ok.bind('<Button-1>', lambda ev: self.view.boxplotting(self.entry_month.get()))
self.btn_ok.place(x=230, y=70)
btn_cancel = tk.Button(self, text='Закрыть', command=self.destroy)
btn_cancel.place(x=160, y=70)
# Создание БД
class Db():
def __init__(self):
self.conn = sqlite3.connect('info.db')
self.cur = self.conn.cursor()
self.cur.execute ('''
CREATE TABLE IF NOT EXISTS econometrics (
id INTEGER PRIMARY KEY,
month TEXT,
revenue INTEGER,
income INTEGER,
prod_costs INTEGER,
indirect_costs INTEGER,
loan_percents INTEGER,
inc_tax INTEGER,
depreciation INTEGER,
path TEXT
)''')
# Функция-инструмент добавления в БД
def insert_data(self, month, revenue, income, prod_costs, indirect_costs, loan_percents, inc_tax, depreciation, path):
self.cur.execute('''
INSERT INTO econometrics (month, revenue, income, prod_costs, indirect_costs, loan_percents, inc_tax, depreciation, path)
VALUES (?,?,?,?,?,?,?,?,?)''', (month, revenue, income, prod_costs, indirect_costs, loan_percents, inc_tax, depreciation, path))
self.conn.commit()
# Создание окна и вызов класса Main
if __name__ == '__main__':
root = tk.Tk()
db = Db()
app = Main(root)
app.pack()
root.title('Таблица для эконометрики')
root.geometry('1000x600')
# Запрет на изменение размеров окна
root.resizable(False, False)
root.mainloop()