361 lines
12 KiB
Python
361 lines
12 KiB
Python
import io
|
||
from tkinter import *
|
||
from tkinter import ttk, filedialog, messagebox
|
||
import configparser
|
||
import db
|
||
from PIL import ImageTk, Image
|
||
import os
|
||
|
||
root = None
|
||
database = None
|
||
config = None
|
||
listbox = None
|
||
image_label = None
|
||
desc_label = None
|
||
img = None
|
||
fViewHelp = False
|
||
fViewSearch = False
|
||
current_select = None
|
||
|
||
|
||
def load_config():
|
||
global config
|
||
config = configparser.ConfigParser()
|
||
config.read('cfg.ini')
|
||
|
||
|
||
def load_database():
|
||
global database, config
|
||
database = db.DB(config['DEFAULT']['db_path'])
|
||
|
||
|
||
def help_menu():
|
||
global root
|
||
newWindow = Toplevel(root)
|
||
newWindow.title("New Window")
|
||
newWindow.geometry("200x200")
|
||
Label(newWindow,
|
||
text="This is a new window").pack()
|
||
|
||
|
||
def fond_menu():
|
||
global root
|
||
newWindow = Toplevel(root)
|
||
newWindow.title("New Window")
|
||
newWindow.geometry("200x200")
|
||
Label(newWindow,
|
||
text="This is a new window").pack()
|
||
|
||
|
||
def close_prog(event=None):
|
||
global database
|
||
database.close()
|
||
exit()
|
||
|
||
|
||
def key_pressed(event):
|
||
print(event.keysym)
|
||
if event.keysym == 'F1':
|
||
open_help_window()
|
||
if event.keysym == 'F2':
|
||
add_record_window()
|
||
if event.keysym == 'F3':
|
||
confirm_delete()
|
||
if event.keysym == 'F4':
|
||
update_record_window()
|
||
|
||
def search_window():
|
||
global listbox, fViewSearch
|
||
|
||
def on_search():
|
||
search_term = search_entry.get()
|
||
listbox.delete(0, END)
|
||
for item in original_list:
|
||
if search_term.lower() in item.lower():
|
||
listbox.insert(END, item)
|
||
|
||
|
||
|
||
def on_cancel():
|
||
global fViewSearch
|
||
search_window.destroy()
|
||
listbox.delete(0, END)
|
||
for item in original_list:
|
||
listbox.insert(END, item)
|
||
fViewSearch = False
|
||
|
||
if not fViewSearch:
|
||
fViewSearch = True
|
||
|
||
search_window = Toplevel()
|
||
|
||
search_label = Label(search_window, text="Поиск: ")
|
||
search_label.pack()
|
||
|
||
search_button = Button(search_window, text="Найти", command=on_search)
|
||
search_button.pack()
|
||
|
||
original_list = listbox.get(0, END)
|
||
|
||
search_entry = Entry(search_window)
|
||
search_entry.pack()
|
||
|
||
cancel_button = Button(search_window, text="Отмена", command=on_cancel)
|
||
cancel_button.pack()
|
||
search_window.protocol("WM_DELETE_WINDOW", on_cancel)
|
||
|
||
search_window.mainloop()
|
||
|
||
|
||
def selected(event):
|
||
global listbox, image_label, desc_label, img, current_select
|
||
selected_indices = listbox.curselection()
|
||
selected = ''.join([listbox.get(i) for i in selected_indices])
|
||
record = database.get_record_by_name(selected)
|
||
if record != None and current_select != selected:
|
||
current_select = selected
|
||
img = ImageTk.PhotoImage(Image.open(io.BytesIO(record.img)))
|
||
image_label.config(image=img)
|
||
desc_label.delete(1.0, END)
|
||
desc_label.insert(1.0, record.description)
|
||
|
||
|
||
def add_record_window(event=""):
|
||
global database, listbox
|
||
|
||
def browse_image():
|
||
filename = filedialog.askopenfilename(parent=add_window)
|
||
path = relative_path(filename)
|
||
image_path_entry.delete(0, "end")
|
||
image_path_entry.insert(0, path)
|
||
|
||
def add_button():
|
||
img = None
|
||
with open(image_path_entry.get(), 'rb') as file:
|
||
img = file.read()
|
||
database.add_record(name=name_entry.get(), description=description_entry.get(
|
||
1.0, "end-1c"), img=img)
|
||
load_listbox()
|
||
add_window.destroy()
|
||
|
||
# Создание окна
|
||
add_window = Toplevel()
|
||
add_window.title("Добавить запись")
|
||
|
||
# Создание и размещение виджетов
|
||
name_label = Label(add_window, text="Имя:")
|
||
name_label.grid(row=0, column=0)
|
||
name_entry = Entry(add_window, width=50)
|
||
name_entry.grid(row=0, column=1)
|
||
|
||
description_label = Label(add_window, text="Описание:")
|
||
description_label.grid(row=1, column=0)
|
||
description_entry = Text(add_window, width=50, height=10)
|
||
description_entry.grid(row=1, column=1)
|
||
|
||
image_path_label = Label(add_window, text="Путь до изображения:")
|
||
image_path_label.grid(row=2, column=0)
|
||
image_path_entry = Entry(add_window, width=50)
|
||
image_path_entry.grid(row=2, column=1)
|
||
browse_button = Button(add_window, text="Обзор", command=browse_image)
|
||
browse_button.grid(row=2, column=2)
|
||
|
||
update_button = Button(add_window, text="Добавить", command=add_button)
|
||
update_button.grid(row=3, column=0, columnspan=2)
|
||
|
||
add_window.mainloop()
|
||
|
||
|
||
def update_record_window(event=""):
|
||
global database, listbox
|
||
|
||
def browse_image():
|
||
filename = filedialog.askopenfilename(parent=update_window)
|
||
path = relative_path(filename)
|
||
image_path_entry.delete(0, "end")
|
||
image_path_entry.insert(0, path)
|
||
|
||
def edit_button():
|
||
img = None
|
||
print(image_path_entry.get())
|
||
if image_path_entry.get() != "":
|
||
with open(image_path_entry.get(), 'rb') as file:
|
||
img = file.read()
|
||
else:
|
||
img = record.img
|
||
database.edit_record(selected, name=name_entry.get(), description=description_entry.get(
|
||
1.0, "end-1c"), img=img)
|
||
load_listbox()
|
||
update_window.destroy()
|
||
|
||
selected_indices = listbox.curselection()
|
||
selected = ''.join([listbox.get(i) for i in selected_indices])
|
||
record = database.get_record_by_name(selected)
|
||
|
||
if record == None:
|
||
return
|
||
|
||
# Создание окна
|
||
update_window = Toplevel()
|
||
update_window.title("Изменить запись")
|
||
update_window.lift()
|
||
|
||
# Создание и размещение виджетов
|
||
name_label = Label(update_window, text="Имя:")
|
||
name_label.grid(row=0, column=0)
|
||
name_entry = Entry(update_window, width=50)
|
||
name_entry.insert(0, record.name)
|
||
name_entry.grid(row=0, column=1)
|
||
|
||
description_label = Label(update_window, text="Описание:")
|
||
description_label.grid(row=1, column=0)
|
||
description_entry = Text(update_window, width=50, height=10)
|
||
description_entry.insert("1.0", record.description)
|
||
description_entry.grid(row=1, column=1)
|
||
|
||
image_path_label = Label(update_window, text="Путь до изображения:")
|
||
image_path_label.grid(row=2, column=0)
|
||
image_path_entry = Entry(update_window, width=50)
|
||
image_path_entry.grid(row=2, column=1)
|
||
browse_button = Button(update_window, text="Обзор", command=browse_image)
|
||
browse_button.grid(row=2, column=2)
|
||
|
||
update_button = Button(update_window, text="Изменить", command=edit_button)
|
||
update_button.grid(row=3, column=0, columnspan=2)
|
||
|
||
update_window.mainloop()
|
||
|
||
|
||
def load_listbox():
|
||
global listbox, database
|
||
listbox.delete(0, "end")
|
||
for i, record in enumerate(database.load_records(), 0):
|
||
listbox.insert(i, record.name)
|
||
|
||
|
||
def open_help_window():
|
||
global fViewHelp
|
||
|
||
def close_help():
|
||
global fViewHelp
|
||
fViewHelp = False
|
||
top.destroy()
|
||
if not fViewHelp:
|
||
top = Toplevel()
|
||
top.title("Справка")
|
||
top.geometry("400x200")
|
||
top.maxsize(400, 200)
|
||
top.minsize(400, 200)
|
||
top.focus_set()
|
||
top.protocol("WM_DELETE_WINDOW", close_help)
|
||
label = Label(top, text="База данных 'Известные моря России'\nПозволяет добавлять / изменять / удалять \n информацию.\nКлавиши программы:\nF1-вызов справки о программе,\nF2-добавить в базу данных,\nF3-удалить из базы данных,\nF4-изменить запись в базе данных,\nF10-меню программы", justify='left', anchor='w')
|
||
label.place(x=0, y=0, relwidth=0.95)
|
||
close_button = Button(top, text="Закрыть", command=close_help)
|
||
close_button.place(x=300, y=150)
|
||
fViewHelp = True
|
||
|
||
|
||
def open_about_window():
|
||
aboutwindow = Toplevel()
|
||
aboutwindow.title("О программе")
|
||
aboutwindow.geometry("300x100")
|
||
aboutwindow.maxsize(300, 100)
|
||
aboutwindow.minsize(300, 100)
|
||
aboutwindow.grab_set()
|
||
|
||
label = Label(aboutwindow, text="База данных 'Известные моря России'\n(c) Romanko M.I., Russia, 2023",
|
||
anchor=CENTER, justify='center')
|
||
label.place(relx=0.5, rely=0.5, anchor='center')
|
||
|
||
|
||
def confirm_delete():
|
||
global database, listbox
|
||
selected_indices = listbox.curselection()
|
||
selected = ''.join([listbox.get(i) for i in selected_indices])
|
||
result = messagebox.askquestion(
|
||
"Подтверждение", "Вы уверены, что хотите удалить запись?")
|
||
if result == 'yes':
|
||
database.delete_record(selected)
|
||
messagebox.showinfo("Успех", "Запись успешно удалена")
|
||
load_listbox()
|
||
else:
|
||
messagebox.showinfo("Отмена", "Удаление отменено")
|
||
|
||
|
||
def relative_path(path):
|
||
# Получение пути к текущему файлу
|
||
current_file_path = os.path.abspath(__file__)
|
||
|
||
# Получение пути к текущему рабочему каталогу
|
||
current_directory = os.path.dirname(current_file_path)
|
||
|
||
# Получение относительного пути к файлу
|
||
relative_path = os.path.relpath(path, current_directory)
|
||
|
||
return relative_path
|
||
|
||
|
||
def main():
|
||
global root, listbox, database, image_label, desc_label
|
||
|
||
load_config()
|
||
load_database()
|
||
|
||
root = Tk()
|
||
root.title("amDB")
|
||
root.geometry('700x500+50+50')
|
||
root.minsize(700, 500)
|
||
root.maxsize(700, 500)
|
||
root.bind('<KeyPress-F1>', key_pressed)
|
||
root.bind('<KeyPress-F2>', key_pressed)
|
||
root.bind('<KeyPress-F3>', key_pressed)
|
||
root.bind('<KeyPress-F4>', key_pressed)
|
||
root.bind('<KeyPress-F10>', key_pressed)
|
||
root.bind('<Control-x>', close_prog)
|
||
|
||
main_menu = Menu()
|
||
|
||
fond_menu = Menu(tearoff=0)
|
||
fond_menu.add_command(label="Найти...", command=search_window)
|
||
fond_menu.add_separator()
|
||
fond_menu.add_command(label="Добавить", accelerator="F2", command=add_record_window)
|
||
fond_menu.add_command(label="Удалить", accelerator="F3", command=confirm_delete)
|
||
fond_menu.add_command(label="Изменить", accelerator="F4", command=update_record_window)
|
||
fond_menu.add_separator()
|
||
fond_menu.add_command(label="Выход", accelerator="Ctrl+X", command=close_prog)
|
||
|
||
help_menu = Menu(tearoff=0)
|
||
help_menu.add_command(label="Содержание", command=open_help_window)
|
||
help_menu.add_separator()
|
||
help_menu.add_command(label="О программе", command=open_about_window)
|
||
|
||
main_menu.add_cascade(label="Фонд", menu=fond_menu)
|
||
main_menu.add_cascade(label="Справка", menu=help_menu)
|
||
|
||
label_bottom = Label(root, text="F1-справка F2-добавить F3-удалить F4-изменить F10-меню",
|
||
bd=1, relief=SUNKEN, anchor=W, height=1)
|
||
label_bottom.place(relx=0.0, rely=0.95, relwidth=1)
|
||
|
||
listbox = Listbox(root, justify="left", width=30)
|
||
listbox.bind("<<ListboxSelect>>", selected)
|
||
listbox.place(x=0, y=0, relheight=0.95)
|
||
|
||
load_listbox()
|
||
|
||
image_frame = ttk.Frame(root)
|
||
image_label = Label(image_frame)
|
||
image_label.place(relx=0.0, rely=0.0, relheight=1.0, relwidth=1.0)
|
||
image_frame.place(x=200, rely=0.0, relheight=0.95, width=300)
|
||
|
||
desc_frame = ttk.Frame(root)
|
||
desc_label = Text(desc_frame, wrap="word")
|
||
desc_label.place(relx=0.0, rely=0.0, relheight=1.0, relwidth=1.0)
|
||
desc_frame.place(x=500, rely=0.0, relwidth=0.3, relheight=0.95)
|
||
root.config(menu=main_menu)
|
||
|
||
root.mainloop()
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main()
|