Dataclasses WIP

This commit is contained in:
2025-09-17 06:46:05 +02:00
parent c52b2953d2
commit 891a0a8d2e
5 changed files with 258 additions and 92 deletions

View File

@@ -2,10 +2,15 @@
import tkinter as tk
from tkinter import ttk
from src.gui.gui import main
from src.gui.gui import App
from src.core.file_handler import list_files
from src.core.SQL_handler import SQLite3FileHandler
# Functions
main()
a = list_files("./src/core")
print(a)
class State():
def __init__(self) -> None:
self.app = App()
self.sql_handler = SQLite3FileHandler(Path("Test.db3"))
STATE = State()
STATE.app.main()

View File

@@ -0,0 +1,125 @@
import sqlite3
from pathlib import Path
from typing import Any, List, Tuple
class SQLite3FileHandler:
def __init__(self, db_path: Path):
self.db_path = Path(db_path)
need_init = not self.db_path.exists() # zjistíme, jestli soubor existuje před connect
self.conn = sqlite3.connect(str(self.db_path))
self.cursor = self.conn.cursor()
if need_init:
self.create_tables()
def create_tables(self) -> None:
"""
Vytvoří tabulky (bez chyby pokud už existují).
"""
script = """
CREATE TABLE IF NOT EXISTS TAGS (
ID INTEGER PRIMARY KEY,
TAG_NAME TEXT NOT NULL UNIQUE
);
CREATE TABLE IF NOT EXISTS FILES (
ID INTEGER PRIMARY KEY,
PATH TEXT NOT NULL,
FILE_NAME TEXT NOT NULL,
HASH TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS RELATIONS (
ID INTEGER PRIMARY KEY,
IDS INTEGER NOT NULL,
TYPE TEXT NOT NULL,
IDT INTEGER NOT NULL
);
CREATE TABLE IF NOT EXISTS TAG_CATEGORY (
ID INTEGER PRIMARY KEY,
TAG_CAT_NAME TEXT NOT NULL UNIQUE
);
"""
# executescript umí více příkazů najednou
self.conn.executescript(script)
self.conn.commit()
def insert_tag(self, tag_name: str) -> None:
query = "INSERT INTO TAGS (TAG_NAME) VALUES (?)"
self.cursor.execute(query, (tag_name,))
self.conn.commit()
def delete_tag(self, tag_name: str) -> None:
query = "DELETE FROM TAGS WHERE TAG_NAME = ?"
self.cursor.execute(query, (tag_name,))
self.conn.commit()
def insert_category(self, tag_cat_name: str) -> None:
query = "INSERT INTO TAG_CATEGORY (TAG_CAT_NAME) VALUES (?)"
self.cursor.execute(query, (tag_cat_name,))
self.conn.commit()
def delete_category(self, tag_cat_name: str) -> None:
"""
Smaže kategorii podle názvu.
"""
query = "DELETE FROM TAG_CATEGORY WHERE TAG_CAT_NAME = ?"
self.cursor.execute(query, (tag_cat_name,))
self.conn.commit()
def insert_relation_tag_cat(self, tag_id: int, tag_cat_id: int) -> None:
query = "INSERT INTO RELATIONS (IDS, TYPE, IDT) VALUES (?, ?, ?)"
self.cursor.execute(query, (tag_id, "Category", tag_cat_id))
self.conn.commit()
def delete_relation_tag_cat(self, tag_id: int, tag_cat_id: int) -> None:
"""
Smaže vztah mezi tagem a kategorií podle IDS a IDT.
TYPE je pevně "Category".
"""
query = "DELETE FROM RELATIONS WHERE IDS = ? AND TYPE = ? AND IDT = ?"
self.cursor.execute(query, (tag_id, "Category", tag_cat_id))
self.conn.commit()
def insert_file(self, path: str, file_name: str, hash_value: str) -> None:
"""
Vloží nový soubor do tabulky FILES.
"""
query = "INSERT INTO FILES (PATH, FILE_NAME, HASH) VALUES (?, ?, ?)"
self.cursor.execute(query, (path, file_name, hash_value))
self.conn.commit()
def delete_file(self, file_id: int) -> None:
"""
Smaže soubor podle jeho ID.
"""
query = "DELETE FROM FILES WHERE ID = ?"
self.cursor.execute(query, (file_id,))
self.conn.commit()
def insert_relation_tag_file(self, tag_id: int, file_id: int) -> None:
query = "INSERT INTO RELATIONS (IDS, TYPE, IDT) VALUES (?, ?, ?)"
self.cursor.execute(query, (tag_id, "File", file_id))
self.conn.commit()
def delete_relation_tag_file(self, tag_id: int, file_id: int) -> None:
"""
Smaže vztah mezi tagem a souborem podle IDS a IDT.
TYPE je pevně "File".
"""
query = "DELETE FROM RELATIONS WHERE IDS = ? AND TYPE = ? AND IDT = ?"
self.cursor.execute(query, (tag_id, "File", file_id))
self.conn.commit()
def fetch_all(self, table_name: str) -> List[Tuple[Any]]:
"""Vrátí všechny řádky z tabulky."""
query = f"SELECT * FROM {table_name}"
self.cursor.execute(query)
return self.cursor.fetchall()
def close(self) -> None:
"""Zavře připojení k databázi."""
self.conn.close()

12
src/core/dataclass.py Normal file
View File

@@ -0,0 +1,12 @@
from pathlib import Path
class State(self):
class TagManager(self, SaveHandler, ):
self.SaveHandler = SaveHandler
class FileManager():

View File

@@ -9,102 +9,105 @@ import tkinter as tk
from tkinter import ttk
from src.core.image_handler import load_icon
# Functions
def main() -> None:
root = tk.Tk()
root.title("Ukázka rozložení")
root.geometry("800x600")
class App():
def __init__(self):
pass
# ==== MENU ====
menu_bar = tk.Menu(root)
root.config(menu=menu_bar)
def main(self) -> None:
root = tk.Tk()
root.title("Ukázka rozložení")
root.geometry("800x600")
file_menu = tk.Menu(menu_bar, tearoff=0)
file_menu.add_command(label="Otevřít")
file_menu.add_command(label="Ukončit", command=root.quit)
menu_bar.add_cascade(label="Soubor", menu=file_menu)
# ==== MENU ====
menu_bar = tk.Menu(root)
root.config(menu=menu_bar)
# ==== HLAVNÍ RÁM ====
main_frame = tk.Frame(root)
main_frame.pack(fill="both", expand=True)
file_menu = tk.Menu(menu_bar, tearoff=0)
file_menu.add_command(label="Otevřít")
file_menu.add_command(label="Ukončit", command=root.quit)
menu_bar.add_cascade(label="Soubor", menu=file_menu)
main_frame.columnconfigure(0, weight=1)
main_frame.columnconfigure(1, weight=2)
main_frame.rowconfigure(0, weight=1)
# ==== HLAVNÍ RÁM ====
main_frame = tk.Frame(root)
main_frame.pack(fill="both", expand=True)
# ==== Ikony ====
unchecked = load_icon("src/resources/images/32/32_unchecked.png")
checked = load_icon("src/resources/images/32/32_checked.png")
icons = {"unchecked": unchecked, "checked": checked}
main_frame.columnconfigure(0, weight=1)
main_frame.columnconfigure(1, weight=2)
main_frame.rowconfigure(0, weight=1)
# ==== VLEVO: STROM ====
tree = ttk.Treeview(main_frame)
tree.grid(row=0, column=0, sticky="nsew", padx=2, pady=2)
# ==== Ikony ====
unchecked = load_icon("src/resources/images/32/32_unchecked.png")
checked = load_icon("src/resources/images/32/32_checked.png")
icons = {"unchecked": unchecked, "checked": checked}
# Slovník pro stavy checkboxů
states = {}
# ==== VLEVO: STROM ====
tree = ttk.Treeview(main_frame)
tree.grid(row=0, column=0, sticky="nsew", padx=2, pady=2)
# Funkce pro přepnutí checkboxu
def toggle(event) -> None:
region = tree.identify("region", event.x, event.y)
if region == "tree":
# Slovník pro stavy checkboxů
states = {}
# Funkce pro přepnutí checkboxu
def toggle(event) -> None:
region = tree.identify("region", event.x, event.y)
if region == "tree":
item_id = tree.identify_row(event.y)
if item_id:
states[item_id] = not states[item_id]
tree.item(item_id, image=icons["checked"] if states[item_id] else icons["unchecked"])
tree.bind("<Button-1>", toggle)
# Přidání uzlů se stavem
root_node = tree.insert("", "end", text="Root", image=icons["unchecked"])
states[root_node] = False
child1 = tree.insert(root_node, "end", text="Child 1", image=icons["unchecked"])
states[child1] = False
child2 = tree.insert(root_node, "end", text="Child 2", image=icons["unchecked"])
states[child2] = False
tree.item(root_node, open=True)
# ==== VPRAVO: SEZNAM ====
listbox = tk.Listbox(main_frame)
listbox.grid(row=0, column=1, sticky="nsew", padx=2, pady=2)
for i in range(1, 21):
listbox.insert("end", f"Položka {i}")
# ==== STAVOVÝ ŘÁDEK ====
status_bar = tk.Label(root, text="Připraven", anchor="w", relief="sunken")
status_bar.pack(side="bottom", fill="x")
# ==== KONTEXTOVÁ MENU ====
tree_menu = tk.Menu(root, tearoff=0)
tree_menu.add_command(
label="Akce na stromu",
command=lambda: status_bar.config(text="Klikl jsi na strom")
)
list_menu = tk.Menu(root, tearoff=0)
list_menu.add_command(
label="Akce na seznamu",
command=lambda: status_bar.config(text="Klikl jsi na seznam")
)
# ==== HANDLERY ====
def tree_right_click(event):
item_id = tree.identify_row(event.y)
if item_id:
states[item_id] = not states[item_id]
tree.item(item_id, image=icons["checked"] if states[item_id] else icons["unchecked"])
if item_id: # klik na uzel
tree.selection_set(item_id)
tree_menu.tk_popup(event.x_root, event.y_root)
tree.bind("<Button-1>", toggle)
def list_right_click(event):
index = listbox.nearest(event.y)
if index >= 0: # klik na položku
listbox.selection_clear(0, "end")
listbox.selection_set(index)
list_menu.tk_popup(event.x_root, event.y_root)
# Přidání uzlů se stavem
root_node = tree.insert("", "end", text="Root", image=icons["unchecked"])
states[root_node] = False
tree.bind("<Button-3>", tree_right_click)
listbox.bind("<Button-3>", list_right_click)
child1 = tree.insert(root_node, "end", text="Child 1", image=icons["unchecked"])
states[child1] = False
child2 = tree.insert(root_node, "end", text="Child 2", image=icons["unchecked"])
states[child2] = False
tree.item(root_node, open=True)
# ==== VPRAVO: SEZNAM ====
listbox = tk.Listbox(main_frame)
listbox.grid(row=0, column=1, sticky="nsew", padx=2, pady=2)
for i in range(1, 21):
listbox.insert("end", f"Položka {i}")
# ==== STAVOVÝ ŘÁDEK ====
status_bar = tk.Label(root, text="Připraven", anchor="w", relief="sunken")
status_bar.pack(side="bottom", fill="x")
# ==== KONTEXTOVÁ MENU ====
tree_menu = tk.Menu(root, tearoff=0)
tree_menu.add_command(
label="Akce na stromu",
command=lambda: status_bar.config(text="Klikl jsi na strom")
)
list_menu = tk.Menu(root, tearoff=0)
list_menu.add_command(
label="Akce na seznamu",
command=lambda: status_bar.config(text="Klikl jsi na seznam")
)
# ==== HANDLERY ====
def tree_right_click(event):
item_id = tree.identify_row(event.y)
if item_id: # klik na uzel
tree.selection_set(item_id)
tree_menu.tk_popup(event.x_root, event.y_root)
def list_right_click(event):
index = listbox.nearest(event.y)
if index >= 0: # klik na položku
listbox.selection_clear(0, "end")
listbox.selection_set(index)
list_menu.tk_popup(event.x_root, event.y_root)
tree.bind("<Button-3>", tree_right_click)
listbox.bind("<Button-3>", list_right_click)
root.mainloop()
root.mainloop()

21
test/SQL_handler_test.py Normal file
View File

@@ -0,0 +1,21 @@
import sys, os
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
from src.core.SQL_handler import SQLite3FileHandler
from pathlib import Path
db_path = Path("Test.db3")
test = SQLite3FileHandler(db_path=db_path)
try:
test.insert_tag("test")
except:
pass
try:
test.insert_category("Test")
except:
pass
test.insert_relation_tag_cat(4, 7)
print(test.fetch_all("RELATIONS"))
test.close()