Jak w tkinter połączyć bind() z obsługą zdarzenia dla przycisku?

0

Witam

Chciałbym aby, kiedy zostanie naciśnięty klawisz enter, została wywołana funkcja dla buttona z zakładki aktualnie na wierzchu

Może przy okazji ktoś podpowie jakie podejście zastosować kiedy próbuję napisać aplikację która posiada wiele pól entry i następuje przeliczanie pomiędzy nimi.Obecnie aby nie dochodziło do błędów kiedy wpisuje coś w jedno pole usuwam wartości w polach które mogą ulec zmianie kiedy ta wartość jest zmieniana (obliczenia pól, powierzchni, wag, cen ceowników, blach itp. )

Stosuję podejście obiektowe, tutaj uproszczony kod:

import tkinter as tk
from tkinter import ttk

def click_button_1():
    print('klik 1')

def click_button_2():
    print('klik 2')

def on_entry_change(event):
    print(f'Wartość pola Entry zmieniona na: {event.widget.get()}')

def setup_entry_bindings(frame):
    for entry_widget in frame.winfo_children():
        if isinstance(entry_widget, tk.Entry):
            entry_widget.bind('<Return>', on_entry_change)

# Utwórz główne okno
root = tk.Tk()
root.title("Prosty program Tkinter")

# Utwórz zakładki
notebook = ttk.Notebook(root)

# Zakładka 1
frame_tab1 = ttk.Frame(notebook)
notebook.add(frame_tab1, text='Zakładka 1')

label = tk.Label(frame_tab1, text='Wprowadź tekst:')
label.pack(pady=10)

entry = tk.Entry(frame_tab1)
entry.pack(pady=10)

entry1 = tk.Entry(frame_tab1)
entry1.pack(pady=10)

button = tk.Button(frame_tab1, text='button 1', command=click_button_1)
button.pack(pady=10)

# Zakładka 2
frame_tab2 = ttk.Frame(notebook)
notebook.add(frame_tab2, text='Zakładka 2')

label2 = tk.Label(frame_tab2, text='Wprowadź tekst:')
label2.pack(pady=10)

entry2 = tk.Entry(frame_tab2)
entry2.pack(pady=10)

entry3 = tk.Entry(frame_tab2)
entry3.pack(pady=10)

button2 = tk.Button(frame_tab2, text='button 2', command=click_button_2)
button2.pack(pady=10)

# Dodaj ogólne bindy dla pól Entry
setup_entry_bindings(frame_tab1)
setup_entry_bindings(frame_tab2)

# Wyświetl zakładki
notebook.pack(expand=True, fill="both")

# Uruchom pętlę główną
root.mainloop()
0

Jak to ma być obiektowo to może wykorzystaj jakieś wzorce np:. wzorzec projektowy strategia do obsługi zdarzenia naciśnięcia klawisza Enter. Utwórz klasę strategii, która będzie wywoływać odpowiednią funkcję dla aktualnie wybranej zakładki. A w drugim przykładzie gdzie trzeba obsłużyć aplikację z wieloma polami, gdzie zachodzi potrzeba przeliczania wartości między nimi (np. obliczenia do ceownika), możemy zastosować wzorzec projektowy Obserwator. (Wzorzec ten pozwala na zapewnienie komunikacji między obiektami w taki sposób, że zmiana stanu jednego obiektu powoduje automatyczne powiadomienie i aktualizację pozostałych obiektów.)

Możesz stworzyć też klasę Tab, wtedy każda klasa Tab może mieć swój widget lub layout. Możesz wykorzystać wtedy taka klasę wielokrotnie.

Przykładowy kod:

import tkinter as tk
from tkinter import ttk


class CommandStrategy:
    def __init__(self, command):
        self.command = command

    def execute(self):
        self.command.execute()


class ClickButton1Command:
    def execute(self):
        print("klik 1")


class ClickButton2Command:
    def execute(self):
        print("klik 2")


class OnEntryChangeStrategy:
    def __init__(self, notebook):
        self.notebook = notebook

    def execute(self, event):
        current_tab_index = self.notebook.index(self.notebook.select())
        current_tab = self.notebook.winfo_children()[current_tab_index]
        entry_widgets = current_tab.winfo_children()

        for widget in entry_widgets:
            if isinstance(widget, tk.Entry) and widget is event.widget:
                print(f"Wartość pola Entry zmieniona na: {widget.get()}")


class Tab:
    def __init__(self, parent, click_button_command):
        self.frame = ttk.Frame(parent)

        self.label = tk.Label(self.frame, text="Wprowadź tekst:")
        self.label.pack(pady=10)

        self.entry1 = tk.Entry(self.frame)
        self.entry1.pack(pady=10)

        self.entry2 = tk.Entry(self.frame)
        self.entry2.pack(pady=10)

        self.button = tk.Button(
            self.frame, text="button", command=click_button_command.execute
        )
        self.button.pack(pady=10)

        self.entry_change_strategy = OnEntryChangeStrategy(parent)
        self.setup_entry_bindings()

    def setup_entry_bindings(self):
        for entry_widget in self.frame.winfo_children():
            if isinstance(entry_widget, tk.Entry):
                entry_widget.bind("<Return>", self.entry_change_strategy.execute)


class Application(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Prosty program Tkinter")
        self.notebook = ttk.Notebook(self)

        self.setup_tabs()

        self.notebook.pack(expand=True, fill="both")

    def setup_tabs(self):
        click_button1_command = ClickButton1Command()
        click_button2_command = ClickButton2Command()

        tab1 = Tab(self.notebook, CommandStrategy(click_button1_command))
        self.notebook.add(tab1.frame, text="Zakładka 1")

        tab2 = Tab(self.notebook, CommandStrategy(click_button2_command))
        self.notebook.add(tab2.frame, text="Zakładka 2")


if __name__ == "__main__":
    app = Application()
    app.mainloop()

0

Dziękuję, postaram się douczyć o tych wzorcach bo dopiero zacząłem przygodę z kodowaniem.

A jak zrobić, aby kiedy jestem na zakładce pierwszej, została wywołana odpowiednia metoda (czyli pojawi się 'klik 1'), na drugiej 'klik 2'? Próbowałem z pomocą ChatGPT ale nie udało się. Chodzi o to, niezależnie czy nacisnę button czy klawisz enter ma zostać wykonane to samo.

Czy bind() zaproponowany w moim przykładzie jest poprawny? Wydaje się taki mało 'elegancki'?

0

Musisz wiedzieć na której zakładce akurat jesteś. Wtedy Enter powiążesz z 'butonem' w tej zakładce. Dla prostych, małych projektów nie brnij w obiektowe. Niepotrzebna frustracja. Na funkcjach wystarczy.

0

Staram się od razu obiektowo bo i tak tego nie uniknę, a jak sprawdzić na jakiej zakładce jestem?

0

Przez focus ustawiasz startową zakładkę, tak?
A dalej pod notebook masz podpięte taby i tam też podpinasz .bind. Ten bind kieruje do funkcji ;-) , a tam:

print(event.widget.index(event.widget.select()))

i pojawiają się numerki klikniętego taba.

0

Ja tez kod mam zrobiony też z tego chatu żeby było szybciej, trochę korzystałem z dokumentacji, odpaliłem tez to z debuggerem żeby zobaczyć rezultat. Nie przejmuj sie, czy kod jest elegancki czy nie, według mnie ważniejsze jest czy spełnia określony cel i kryteria jakie sobie założysz. Kod ma pokazać ogólny zarys problemu i spełnia swoje zadanie. Jeśli czas na to pozwala kod można zawsze ulepszyć.

W poniższym przykładzie obud owalem w funkcje print, żeby to byla jakaś customowa funkcja stworzona np do obliczenia ceny. Mam nadzieje że o to chodzi. Z dokumentacji wynika, że aby wiedzieć która zakładka jest aktywna możesz użyć metody index() oraz metody select() np:
current_tab_index = notebook.index(notebook.select())
i wtedy masz numer indeksu zakładki który jest aktywny sa dwie zakładki, wiec biedzie wartość 0 albo 1.
teraz jak wciśnie sie określony button

import tkinter as tk
from tkinter import ttk

def calculate_price():
    # jakies obliczenia
    print('klik 1')

def calculate_inventory():
    # jakies obliczenia
    print('klik 2')

def click_button_1():
    # index aktualnie zaznaczona zakladki
    current_tab_index = notebook.index(notebook.select())
    
    # jeśli aktywna jest zakladka to wywołaj odpowiednia funkcje
    if current_tab_index == 0:
        calculate_price()
    else:
        calculate_inventory()

def click_button_2():
    # Index aktualnie zaznaczona zakladki ( 0 - pierwsza zakladka ; 1 - druga zakladka)
    current_tab_index = notebook.index(notebook.select())
    
    # jeśli aktywna jest zakladka to wywołaj odpowiednia funkcje
    if current_tab_index == 0:
        calculate_price()
    else:
        calculate_inventory()

def on_entry_change(event):
    # aktualnie zaznaczona zakladka
    current_tab_index = notebook.index(notebook.select())
    
    if current_tab_index == 0:
        calculate_price()
    else:
        calculate_inventory()

def setup_entry_bindings(frame):
    for entry_widget in frame.winfo_children():
        if isinstance(entry_widget, tk.Entry):
            entry_widget.bind('<Return>', on_entry_change)

# Create the main window
root = tk.Tk()
root.title("Prosty program Tkinter")

# Create tabs
notebook = ttk.Notebook(root)

# Tab 1
frame_tab1 = ttk.Frame(notebook)
notebook.add(frame_tab1, text='Zakładka 1')

label = tk.Label(frame_tab1, text='Wprowadź tekst:')
label.pack(pady=10)

entry = tk.Entry(frame_tab1)
entry.pack(pady=10)

entry1 = tk.Entry(frame_tab1)
entry1.pack(pady=10)

button = tk.Button(frame_tab1, text='button 1', command=click_button_1)
button.pack(pady=10)

# Tab 2
frame_tab2 = ttk.Frame(notebook)
notebook.add(frame_tab2, text='Zakładka 2')

label2 = tk.Label(frame_tab2, text='Wprowadź tekst:')
label2.pack(pady=10)

entry2 = tk.Entry(frame_tab2)
entry2.pack(pady=10)

entry3 = tk.Entry(frame_tab2)
entry3.pack(pady=10)

button2 = tk.Button(frame_tab2, text='button 2', command=click_button_2)
button2.pack(pady=10)

setup_entry_bindings(frame_tab1)
setup_entry_bindings(frame_tab2)

notebook.pack(expand=True, fill="both")

root.mainloop()

Mozna jeszcze ten kod ulepszyc bo sa powtorzenia itp. lub rozpisac całkiem inaczej klasami. Tutaj powinno sie wyswietlać to samo przy kliknieciu buttona i wcisnieciu enter. Jak jest wiecej tabow to wiecej bedzie ifow lub może wykorzystac match case. Jak chcesz to rozpisac klasami to możesz wpisać "Can you refactor this code using OOP and design paterns?" może coś sensownego chat wypluje i bedzie mało poprawiania ;-). Mam nadzieje, że to coś pomogło w rozwiazaniu Twojego problemu.

0

Wyszedł mi taki potworek. Jest taki długi ponieważ nie mogę sobie poradzić z tworzeniem widżetów entry i interakcjami pomiędzy nimi. Zakładki są podobne ale interakcje i obliczenia są już różne. Wydaje mi się, że dla zakładek długościowych: Tab_dlu_rura itd. oraz dla zakładek powierzchniowych: Tab_powierzchniowe_arkusz itd. wystarczyłoby po jednej klasie.

Program działa ale chciałbym go poprawić bo utrzymanie i wprowadzanie zmian jest uciążliwe. Może ktoś coś podpowie

Najlepiej uruchomić program to wtedy wszysto będzie dużo łatwiejsze do zrozumienia, bo teraz wiekszość kodu to wyświetlanie widżetów.
Każde entry ma walidację danych, przy tworzeniu dostaje słownik slownik_wyczysc w którym jest lista pól entry które ulegną czyszczeniu jeżeli to entry zostanie zmienione(zapisane tak dziwnie bo użyte z innego programu)

import tkinter as tk
from tkinter import ttk
import logging


class Apk(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Materiały")
        self.geometry('850x450')
        self.minsize(850, 450)

        logging.basicConfig(level=logging.DEBUG,  # filename="Materialy_log.log",
                            format='%(asctime)s - %(levelname)s - %(message)s')
        logging.debug("-------------Rozpoczęcie programu------------------")  # debug,info,warning,critical


        style = ttk.Style()

        style.configure("TNotebook.Tab",  padding=(10, 5), font=("Helvetica", 10))

        self.zakladki_r_materialu = ttk.Notebook(self)
        self.tab_dlugosciowe = Tab_dlugosciowe()
        self.zakladki_r_materialu.add(self.tab_dlugosciowe, text="Materiały długościowe")

        self.tab_powierzchniowe = Tab_powierzchniowe()
        self.zakladki_r_materialu.add(self.tab_powierzchniowe, text="Materiały powierzchniowe")

        self.tab_armatura = Tab_armatura()
        self.zakladki_r_materialu.add(self.tab_armatura, text="Armatura")

        self.zakladki_r_materialu.place(relx=0, rely=0, relwidth=1, relheight=1)
        self.mainloop()


class Tab_armatura(ttk.Frame):
    def __init__(self, master=None):
        super().__init__(master)

        self.frame_iso = tk.Frame(self)
        rows = [
            ["ISO", '10', '13,5', '17,2', '21,3', '26,9', '33,7', '42,4', '48,3', '60,3', '76,1', '88,9', '114,3'],
            ["Cale", '1/8"', '1/3"', '3/8"', '1/2"', '3/4"', '1"', '1 1/4"', '1 1/2"', '2"', '2 1/2"', '3"', '4"']
        ]

        for row, data_row in enumerate(rows):
            for col, value in enumerate(data_row):
                label = tk.Label(self.frame_iso, text=value, borderwidth=1, relief="solid", width=8)
                label.grid(row=row, column=col)
                if col % 2 == 0:
                    label.configure(bg='yellow')
                else:
                    label.configure(bg="#EFEF00")

        self.frame_iso.grid(column=0, row=0, padx=10, pady=10)


class Tab_dlugosciowe(ttk.Frame):
    def __init__(self, master=None):
        super().__init__(master)

        self.zakladki_dlugosciowe = ttk.Notebook(self)

        self.tab_dlu_rura = Tab_dlu_rura()
        self.zakladki_dlugosciowe.add(self.tab_dlu_rura, text="Rura")

        self.tab_dlu_pret = Tab_dlu_pret()
        self.zakladki_dlugosciowe.add(self.tab_dlu_pret, text="Pret")

        self.tab_dlu_plaskownik = Tab_dlu_plaskownik()
        self.zakladki_dlugosciowe.add(self.tab_dlu_plaskownik, text="Płaskownik")

        self.tab_dlu_ksztaltownik = Tab_dlu_ksztaltownik()
        self.zakladki_dlugosciowe.add(self.tab_dlu_ksztaltownik, text="Kształtownik")

        self.tab_dlu_katownik = Tab_dlu_katownik()
        self.zakladki_dlugosciowe.add(self.tab_dlu_katownik, text="Kątownik")

        self.tab_dlu_ceownik = Tab_dlu_ceownik()
        self.zakladki_dlugosciowe.add(self.tab_dlu_ceownik, text="Ceownik")

        self.zakladki_dlugosciowe.place(relx=0, rely=0, relwidth=1, relheight=1)


class Tab_dlu_rura(ttk.Frame):
    def __init__(self, master=None):
        super().__init__(master)


        self.tworzenie_widzetow_glownych()
        self.tworzenie_widzetow_waga_cena()
        self.btn_przelicz = ttk.Button(self, text='Przelicz', command=self.oblicz_dla_rura)

        self.umieszczanie_widzetow_glownych(wiersz=1, px=5, py=1)
        self.umieszczanie_widzetow_waga_cena(wiersz=4, px=5, py=1)
        self.btn_przelicz.grid(column=5, row=7)
        for entry_widget in self.winfo_children():
            if isinstance(entry_widget, tk.Entry):
                entry_widget.bind("<Return>", lambda event: self.oblicz_dla_rura())

    def oblicz_dla_rura(self):

        if self.g_jed_str.get() and self.g_jed_str.get() != '0':
            g_jednos = float(self.g_jed_str.get().replace(',', '.'))
        else:
            g_jednos = False

        if self.sredn_mm_str.get() and self.sredn_mm_str.get() != '0':
            promien_m = float(self.sredn_mm_str.get().replace(',', '.')) / 2000
        else:
            promien_m = False

        if self.sredn_cal_str.get() and self.sredn_cal_str.get() != '0':
            promien_cal = float(self.sredn_cal_str.get().replace(',', '.')) / 2
        else:
            promien_cal = False

        if self.dlugosc_str.get() and self.dlugosc_str.get() != '0':
            dlugo = float(self.dlugosc_str.get().replace(',', '.')) / 1000
        else:
            dlugo = False

        if self.grub_scianki_str.get() and self.grub_scianki_str.get() != '0':
            grub_scianki = float(self.grub_scianki_str.get().replace(',', '.')) / 1000
        else:
            grub_scianki = False

        if self.waga_1mb_str.get() and self.waga_1mb_str.get() != '0':
            waga_1mb = float(self.waga_1mb_str.get().replace(',', '.'))
        else:
            waga_1mb = False

        if self.waga_podanego_str.get() and self.waga_podanego_str.get() != '0':
            waga_dla_podan = float(self.waga_podanego_str.get().replace(',', '.'))
        else:
            waga_dla_podan = False

        if self.cena_1mb_str.get() and self.cena_1mb_str.get() != '0':
            cena_1mb = float(self.cena_1mb_str.get().replace(',', '.'))
        else:
            cena_1mb = False

        if self.cena_1kg_str.get() and self.cena_1kg_str.get() != '0':
            cena_1kg = float(self.cena_1kg_str.get().replace(',', '.'))
        else:
            cena_1kg = False

        if self.cena_dla_podanego_str.get() and self.cena_dla_podanego_str.get() != '0':
            cena_dla_podan = float(self.cena_dla_podanego_str.get().replace(',', '.'))
        else:
            cena_dla_podan = False

        # --------------OBLICZENIA-----------------------

        if promien_m and not promien_cal:
            self.sredn_cal_str.set(str(round(promien_m * 200 / 2.54, 2)))
            promien_cal = float(self.sredn_cal_str.get().replace(',', '.')) / 2

        if promien_cal and not promien_m:
            self.sredn_mm_str.set(str(round(promien_cal * 20 * 2.54, 2)))
            promien_m = float(self.sredn_mm_str.get().replace(',', '.')) / 2000

        if waga_1mb and not waga_dla_podan and dlugo:  # oblicz waga dla podanego
            self.waga_podanego_str.set(str(round(waga_1mb * dlugo, 2)))
            waga_dla_podan = float(self.waga_podanego_str.get().replace(',', '.'))

        if waga_dla_podan and not waga_1mb and dlugo:  # oblicz waga 1m
            self.waga_1mb_str.set(str(round(waga_dla_podan / dlugo, 2)))
            waga_1mb = float(self.waga_1mb_str.get().replace(',', '.'))

        if not g_jednos and waga_1mb and promien_m and grub_scianki:  # oblicz gestosc jednostkowa
            promien_wew_m = promien_m - grub_scianki
            obj_zew = 3.14 * promien_m ** 2
            obj_wew = 3.14 * promien_wew_m ** 2
            objetosc = obj_zew - obj_wew
            self.g_jed_str.set(str(round(waga_1mb * (1 / objetosc), 2)))
            g_jednos = float(self.g_jed_str.get().replace(',', '.'))

        if not waga_1mb and not waga_dla_podan and promien_m and grub_scianki and g_jednos:  # oblicz waga 1m i waga podanego
            promien_wew_m = promien_m - grub_scianki
            objetosc = 3.14 * (promien_m ** 2 - promien_wew_m ** 2)

            self.waga_1mb_str.set(str(round(objetosc * g_jednos, 2)))
            waga_1mb = float(self.waga_1mb_str.get().replace(',', '.'))
            if dlugo:
                self.waga_podanego_str.set(str(round(waga_1mb * dlugo, 2)))
                waga_dla_podan = float(self.waga_podanego_str.get().replace(',', '.'))

        if cena_1mb and not cena_1kg and not cena_dla_podan and waga_1mb:

            self.cena_1kg_str.set(str(round(cena_1mb / waga_1mb, 2)))
            cena_1kg = float(self.cena_1kg_str.get().replace(',', '.'))

            if dlugo:
                self.cena_dla_podanego_str.set(str(round(cena_1mb * dlugo, 2)))
                cena_dla_podan = float(self.cena_dla_podanego_str.get().replace(',', '.'))




        if cena_1kg and not cena_1mb and not cena_dla_podan and waga_1mb:
            self.cena_1mb_str.set(str(round(cena_1kg * waga_1mb, 2)))
            cena_1mb = float(self.cena_1mb_str.get().replace(',', '.'))

            if dlugo:
                self.cena_dla_podanego_str.set(str(round(dlugo * cena_1mb, 2)))
                cena_dla_podan = float(self.cena_dla_podanego_str.get().replace(',', '.'))

        if cena_dla_podan and not cena_1kg and not cena_1mb and dlugo:

            self.cena_1mb_str.set(str(round(cena_dla_podan / dlugo, 2)))
            cena_1mb = float(self.cena_1mb_str.get().replace(',', '.'))

            if waga_1mb:
                self.cena_1kg_str.set(str(round(cena_1mb / waga_1mb, 2)))
                cena_1kg = float(self.cena_1kg_str.get().replace(',', '.'))

    def tworzenie_widzetow_glownych(self):

        self.lbl_pusty_gora = ttk.Label(self, text=' ')
        self.material_str = tk.StringVar()
        self.keys_materialow = list(c.materialy.keys())
        self.omenu_material = ttk.OptionMenu(self, self.material_str, self.keys_materialow[0], *self.keys_materialow,
                                             command=self.omenu_materialy_f)

        self.lbl_g_jed = ttk.Label(self, text='Gęstość jedn.\n [kg/m3]')
        self.g_jed_str = tk.StringVar()
        self.entry_g_jed = EntryValid(self, textvariable=self.g_jed_str,
                                      slownik_wyczysc={'clr_waga_1m': self.clr_waga_1mb,
                                                       'clr_waga_podanego': self.clr_waga_podanego,
                                                       'clr_cena_1kg': self.clr_cena_1kg,
                                                       'clr_cena_1mb': self.clr_cena_1mb,
                                                       'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_sredn_cal = ttk.Label(self, text='Średnica\n [cal]')
        self.sredn_cal_str = tk.StringVar()
        self.entry_sredn_cal = EntryValid(self, textvariable=self.sredn_cal_str,
                                          slownik_wyczysc={'clr_srednica_mm': self.clr_srednica_mm,
                                                           'clr_waga_1m': self.clr_waga_1mb,
                                                           'clr_waga_podanego': self.clr_waga_podanego,
                                                           'clr_cena_1kg': self.clr_cena_1kg,
                                                           'clr_cena_1mb': self.clr_cena_1mb,
                                                           'clr_cena_dla_podanego': self.clr_cena_dla_podanego})


        self.lbl_sredn_mm = ttk.Label(self, text='Średnica\n [mm]')
        self.sredn_mm_str = tk.StringVar()
        self.entry_sredn_mm = EntryValid(self, textvariable=self.sredn_mm_str,
                                         slownik_wyczysc={'clr_srednica_cal': self.clr_srednica_cal,
                                                          'clr_waga_1m': self.clr_waga_1mb,
                                                          'clr_waga_podanego': self.clr_waga_podanego,
                                                          'clr_cena_1kg': self.clr_cena_1kg,
                                                          'clr_cena_1mb': self.clr_cena_1mb,
                                                          'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_grub_scianki = ttk.Label(self, text='Grub. ścianki\n [mm]')
        self.grub_scianki_str = tk.StringVar()
        self.entry_grub_scianki = EntryValid(self, textvariable=self.grub_scianki_str,
                                             slownik_wyczysc={'clr_waga_1m': self.clr_waga_1mb,
                                                              'clr_waga_podanego': self.clr_waga_podanego,
                                                              'clr_cena_1kg': self.clr_cena_1kg,
                                                              'clr_cena_1mb': self.clr_cena_1mb,
                                                              'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_dlugosc = ttk.Label(self, text='Długość\n[mm]')
        self.dlugosc_str = tk.StringVar()
        self.entry_dlugosc = EntryValid(self, textvariable=self.dlugosc_str,
                                        slownik_wyczysc={'clr_waga_podanego': self.clr_waga_podanego,
                                                         'clr_cena_1kg': self.clr_cena_1kg,
                                                         'clr_cena_1mb': self.clr_cena_1mb,
                                                         'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_pusty_pod_glownymi = ttk.Label(self, text=' ')
        '''
        self.lbl_ = ttk.Label(self, text='\n[]')
        self._str = tk.StringVar(value=1)
        self.entry_ = EntryValid(self) 
        '''

    def tworzenie_widzetow_waga_cena(self):



        self.lbl_waga_1mb = ttk.Label(self, text='Waga 1mb\n[kg]')
        self.waga_1mb_str = tk.StringVar()
        self.entry_waga_1mb = EntryValid(self, textvariable=self.waga_1mb_str,
                                         slownik_wyczysc={'clr_g_jedn': self.clr_g_jedn,
                                                          'clr_waga_podanego': self.clr_waga_podanego,
                                                          'clr_cena_1kg': self.clr_cena_1kg,
                                                          'clr_cena_1mb': self.clr_cena_1mb,
                                                          'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_waga_podanego = ttk.Label(self, text='Waga dla p. długości\n[kg]')
        self.waga_podanego_str = tk.StringVar()
        self.entry_waga_podanego = EntryValid(self, textvariable=self.waga_podanego_str,
                                              slownik_wyczysc={'clr_g_jedn': self.clr_g_jedn,
                                                               'clr_waga_1mb': self.clr_waga_1mb,
                                                               'clr_cena_1kg': self.clr_cena_1kg,
                                                               'clr_cena_1mb': self.clr_cena_1mb,
                                                               'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_cena_1mb = ttk.Label(self, text='Cena 1m\n[zł]')
        self.cena_1mb_str = tk.StringVar()
        self.entry_cena_1mb = EntryValid(self, textvariable=self.cena_1mb_str,
                                         slownik_wyczysc={'clr_cena_1kg': self.clr_cena_1kg,
                                                          'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_cena_1kg = ttk.Label(self, text='Cena 1kg\n[zł]')
        self.cena_1kg_str = tk.StringVar()
        self.entry_cena_1kg = EntryValid(self, textvariable=self.cena_1kg_str,
                                         slownik_wyczysc={'clr_cena_1mb': self.clr_cena_1mb,
                                                          'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_cena_dla_podanego = ttk.Label(self, text=f'Cena dla p. długości\n[zł]')
        self.cena_dla_podanego_str = tk.StringVar()
        self.entry_cena_dla_podanego = EntryValid(self, textvariable=self.cena_dla_podanego_str,
                                                  slownik_wyczysc={'clr_cena_1kg': self.clr_cena_1kg,
                                                                   'clr_cena_1mb': self.clr_cena_1mb})
        self.lbl_pusty_pod_waga_cena = ttk.Label(self, text=' ')

    def umieszczanie_widzetow_glownych(self, wiersz, px, py):

        self.lbl_pusty_gora.grid(column=1, row=0)

        self.omenu_material.grid(column=0, row=wiersz, padx=px, pady=py)
        self.lbl_g_jed.grid(column=1, row=wiersz, padx=px, pady=py)
        self.lbl_sredn_mm.grid(column=2, row=wiersz, padx=px, pady=py)
        self.lbl_sredn_cal.grid(column=3, row=wiersz, padx=px, pady=py)
        self.lbl_grub_scianki.grid(column=4, row=wiersz, padx=px, pady=py)
        self.lbl_dlugosc.grid(column=5, row=wiersz, padx=px, pady=py)

        self.entry_g_jed.grid(column=1, row=wiersz + 1, padx=px, pady=py)
        self.entry_sredn_mm.grid(column=2, row=wiersz + 1, padx=px, pady=py)
        self.entry_sredn_cal.grid(column=3, row=wiersz + 1, padx=px, pady=py)
        self.entry_grub_scianki.grid(column=4, row=wiersz + 1, padx=px, pady=py)
        self.entry_dlugosc.grid(column=5, row=wiersz + 1, padx=px, pady=py)

        self.lbl_pusty_pod_glownymi.grid(column=1, row=3)

    def umieszczanie_widzetow_waga_cena(self, wiersz, px, py):

        self.lbl_waga_1mb.grid(column=0, row=wiersz, padx=px, pady=py)
        self.lbl_waga_podanego.grid(column=1, row=wiersz, padx=px, pady=py)
        self.lbl_cena_1mb.grid(column=2, row=wiersz, padx=px, pady=py)
        self.lbl_cena_1kg.grid(column=3, row=wiersz, padx=px, pady=py)
        self.lbl_cena_dla_podanego.grid(column=4, row=wiersz, padx=px, pady=py)

        self.entry_waga_1mb.grid(column=0, row=wiersz + 1, padx=px, pady=py)
        self.entry_waga_podanego.grid(column=1, row=wiersz + 1, padx=px, pady=py)
        self.entry_cena_1mb.grid(column=2, row=wiersz + 1, padx=px, pady=py)
        self.entry_cena_1kg.grid(column=3, row=wiersz + 1, padx=px, pady=py)
        self.entry_cena_dla_podanego.grid(column=4, row=wiersz + 1, padx=px, pady=py)
        self.lbl_pusty_pod_waga_cena.grid(column=1, row=wiersz + 2, padx=px, pady=py)

        self.canvas_obraz_rury = tk.Canvas(self, width=700, height=150)
        self.canvas_obraz_rury.place(relx = 0.5,rely = 0.8, anchor='center')
        self.image_rury = tk.PhotoImage(data=kod_obr.zakodowana_rura_img)
        self.canvas_obraz_rury.create_image(0, 0, anchor="nw", image=self.image_rury)

    def omenu_materialy_f(self, mater):
        if mater in c.materialy:
            self.waga_1mb_str.set('')
            self.waga_podanego_str.set('')
            self.cena_1mb_str.set('')
            self.cena_1kg_str.set('')
            self.cena_dla_podanego_str.set('')
            g_jedno = c.materialy[mater]['g_jednostkowa']
            self.g_jed_str.set(g_jedno)

    def clr_g_jedn(self):
        self.g_jed_str.set('')
        self.entry_g_jed.delete(0, 'end')

    def clr_srednica_cal(self):
        self.sredn_cal_str.set('')
        self.entry_sredn_cal.delete(0, 'end')

    def clr_srednica_mm(self):
        self.sredn_mm_str.set('')
        self.entry_sredn_mm.delete(0, 'end')

    def clr_waga_1mb(self):
        self.waga_1mb_str.set('')
        self.entry_waga_1mb.delete(0, 'end')

    def clr_waga_podanego(self):
        self.waga_podanego_str.set('')
        self.entry_waga_podanego.delete(0, 'end')

    def clr_cena_1mb(self):
        self.cena_1mb_str.set('')
        self.entry_cena_1mb.delete(0, 'end')

    def clr_cena_1kg(self):
        self.cena_1kg_str.set('')
        self.entry_cena_1kg.delete(0, 'end')

    def clr_cena_dla_podanego(self):
        self.cena_dla_podanego_str.set('')
        self.entry_cena_dla_podanego.delete(0, 'end')


class Tab_dlu_pret(ttk.Frame):
    def __init__(self, master=None):
        super().__init__(master)

        self.tworzenie_widzetow_glownych()
        self.tworzenie_widzetow_waga_cena()
        self.btn_przelicz = ttk.Button(self, text='Przelicz', command=self.oblicz_dla_pret)

        self.umieszczanie_widzetow_glownych(wiersz=1, px=5, py=1)
        self.umieszczanie_widzetow_waga_cena(wiersz=4, px=5, py=1)
        self.btn_przelicz.grid(column=5, row=7)
        for entry_widget in self.winfo_children():
            if isinstance(entry_widget, tk.Entry):
                entry_widget.bind("<Return>", lambda event: self.oblicz_dla_pret())
    def oblicz_dla_pret(self):

        if self.g_jed_str.get() and self.g_jed_str.get() != '0':
            g_jednos = float(self.g_jed_str.get().replace(',', '.'))
        else:
            g_jednos = False

        if self.sredn_mm_str.get() and self.sredn_mm_str.get() != '0':
            promien_m = float(self.sredn_mm_str.get().replace(',', '.')) / 2000
        else:
            promien_m = False

        if self.dlugosc_str.get() and self.dlugosc_str.get() != '0':
            dlugo = float(self.dlugosc_str.get().replace(',', '.')) / 1000
        else:
            dlugo = False

        if self.waga_1mb_str.get() and self.waga_1mb_str.get() != '0':
            waga_1mb = float(self.waga_1mb_str.get().replace(',', '.'))
        else:
            waga_1mb = False

        if self.waga_podanego_str.get() and self.waga_podanego_str.get() != '0':
            waga_dla_podan = float(self.waga_podanego_str.get().replace(',', '.'))
        else:
            waga_dla_podan = False

        if self.cena_1mb_str.get() and self.cena_1mb_str.get() != '0':
            cena_1mb = float(self.cena_1mb_str.get().replace(',', '.'))
        else:
            cena_1mb = False

        if self.cena_1kg_str.get() and self.cena_1kg_str.get() != '0':
            cena_1kg = float(self.cena_1kg_str.get().replace(',', '.'))
        else:
            cena_1kg = False

        if self.cena_dla_podanego_str.get() and self.cena_dla_podanego_str.get() != '0':
            cena_dla_podan = float(self.cena_dla_podanego_str.get().replace(',', '.'))
        else:
            cena_dla_podan = False

        # --------------OBLICZENIA-----------------------

        if waga_1mb and not waga_dla_podan and dlugo:
            self.waga_podanego_str.set(str(round(waga_1mb * dlugo, 2)))
            waga_dla_podan = float(self.waga_podanego_str.get().replace(',', '.'))

        if waga_dla_podan and not waga_1mb and dlugo:
            self.waga_1mb_str.set(str(round(waga_dla_podan / dlugo, 2)))
            waga_1mb = float(self.waga_1mb_str.get().replace(',', '.'))

        if not g_jednos and waga_1mb and promien_m:
            objetosc = 3.14 * (promien_m ** 2)
            self.g_jed_str.set(str(round(waga_1mb * (1 / objetosc), 2)))
            g_jednos = float(self.g_jed_str.get().replace(',', '.'))

        if not waga_1mb and not waga_dla_podan and promien_m and g_jednos:
            objetosc = 3.14 * (promien_m ** 2)

            self.waga_1mb_str.set(str(round(objetosc * g_jednos, 2)))
            waga_1mb = float(self.waga_1mb_str.get().replace(',', '.'))
            if dlugo:
                self.waga_podanego_str.set(str(round(waga_1mb * dlugo, 2)))
                waga_dla_podan = float(self.waga_podanego_str.get().replace(',', '.'))

        if cena_1mb and not cena_1kg and not cena_dla_podan and waga_1mb:

            self.cena_1kg_str.set(str(round(cena_1mb / waga_1mb, 2)))
            cena_1kg = float(self.cena_1kg_str.get().replace(',', '.'))

            if dlugo:
                self.cena_dla_podanego_str.set(str(round(cena_1mb * dlugo, 2)))
                cena_dla_podan = float(self.cena_dla_podanego_str.get().replace(',', '.'))

        if cena_1kg and not cena_1mb and not cena_dla_podan and waga_1mb:
            self.cena_1mb_str.set(str(round(cena_1kg * waga_1mb, 2)))
            cena_1mb = float(self.cena_1mb_str.get().replace(',', '.'))

            if dlugo:
                self.cena_dla_podanego_str.set(str(round(dlugo * cena_1mb, 2)))
                cena_dla_podan = float(self.cena_dla_podanego_str.get().replace(',', '.'))

        if cena_dla_podan and not cena_1kg and not cena_1mb and dlugo:

            self.cena_1mb_str.set(str(round(cena_dla_podan / dlugo, 2)))
            cena_1mb = float(self.cena_1mb_str.get().replace(',', '.'))

            if waga_1mb:
                self.cena_1kg_str.set(str(round(cena_1mb / waga_1mb, 2)))
                cena_1kg = float(self.cena_1kg_str.get().replace(',', '.'))

    def tworzenie_widzetow_glownych(self):

        self.lbl_pusty_gora = ttk.Label(self, text=' ')
        self.material_str = tk.StringVar()
        self.keys_materialow = list(c.materialy.keys())
        self.omenu_material = ttk.OptionMenu(self, self.material_str, self.keys_materialow[0], *self.keys_materialow,
                                             command=self.omenu_materialy_f)

        self.lbl_g_jed = ttk.Label(self, text='Gęstość jedn.\n [kg/m3]')
        self.g_jed_str = tk.StringVar()
        self.entry_g_jed = EntryValid(self, textvariable=self.g_jed_str,
                                      slownik_wyczysc={'clr_waga_1m': self.clr_waga_1mb,
                                                       'clr_waga_podanego': self.clr_waga_podanego,
                                                       'clr_cena_1kg': self.clr_cena_1kg,
                                                       'clr_cena_1mb': self.clr_cena_1mb,
                                                       'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_sredn_mm = ttk.Label(self, text='Średnica\n [mm]')
        self.sredn_mm_str = tk.StringVar()
        self.entry_sredn_mm = EntryValid(self, textvariable=self.sredn_mm_str,
                                         slownik_wyczysc={'clr_waga_1m': self.clr_waga_1mb,
                                                          'clr_waga_podanego': self.clr_waga_podanego,
                                                          'clr_cena_1kg': self.clr_cena_1kg,
                                                          'clr_cena_1mb': self.clr_cena_1mb,
                                                          'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_dlugosc = ttk.Label(self, text='Długość\n[mm]')
        self.dlugosc_str = tk.StringVar()
        self.entry_dlugosc = EntryValid(self, textvariable=self.dlugosc_str,
                                        slownik_wyczysc={'clr_waga_podanego': self.clr_waga_podanego,
                                                         'clr_cena_1kg': self.clr_cena_1kg,
                                                         'clr_cena_1mb': self.clr_cena_1mb,
                                                         'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_pusty_pod_glownymi = ttk.Label(self, text=' ')
        '''
        self.lbl_ = ttk.Label(self, text='\n[]')
        self._str = tk.StringVar(value=1)
        self.entry_ = EntryValid(self) 
        '''

    def tworzenie_widzetow_waga_cena(self):

        self.lbl_waga_1mb = ttk.Label(self, text='Waga 1mb\n[kg]')
        self.waga_1mb_str = tk.StringVar()
        self.entry_waga_1mb = EntryValid(self, textvariable=self.waga_1mb_str,
                                         slownik_wyczysc={'clr_g_jedn': self.clr_g_jedn,
                                                          'clr_waga_podanego': self.clr_waga_podanego,
                                                          'clr_cena_1kg': self.clr_cena_1kg,
                                                          'clr_cena_1mb': self.clr_cena_1mb,
                                                          'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_waga_podanego = ttk.Label(self, text='Waga dla p. długości\n[kg]')
        self.waga_podanego_str = tk.StringVar()
        self.entry_waga_podanego = EntryValid(self, textvariable=self.waga_podanego_str,
                                              slownik_wyczysc={'clr_g_jedn': self.clr_g_jedn,
                                                               'clr_waga_1mb': self.clr_waga_1mb,
                                                               'clr_cena_1kg': self.clr_cena_1kg,
                                                               'clr_cena_1mb': self.clr_cena_1mb,
                                                               'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_cena_1mb = ttk.Label(self, text='Cena 1m\n[zł]')
        self.cena_1mb_str = tk.StringVar()
        self.entry_cena_1mb = EntryValid(self, textvariable=self.cena_1mb_str,
                                         slownik_wyczysc={'clr_cena_1kg': self.clr_cena_1kg,
                                                          'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_cena_1kg = ttk.Label(self, text='Cena 1kg\n[zł]')
        self.cena_1kg_str = tk.StringVar()
        self.entry_cena_1kg = EntryValid(self, textvariable=self.cena_1kg_str,
                                         slownik_wyczysc={'clr_cena_1mb': self.clr_cena_1mb,
                                                          'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_cena_dla_podanego = ttk.Label(self, text=f'Cena dla p. długości\n[zł]')
        self.cena_dla_podanego_str = tk.StringVar()
        self.entry_cena_dla_podanego = EntryValid(self, textvariable=self.cena_dla_podanego_str,
                                                  slownik_wyczysc={'clr_cena_1kg': self.clr_cena_1kg,
                                                                   'clr_cena_1mb': self.clr_cena_1mb})
        self.lbl_pusty_pod_waga_cena = ttk.Label(self, text=' ')

    def umieszczanie_widzetow_glownych(self, wiersz, px, py):

        self.lbl_pusty_gora.grid(column=1, row=0)

        self.omenu_material.grid(column=0, row=wiersz, padx=px, pady=py)
        self.lbl_g_jed.grid(column=1, row=wiersz, padx=px, pady=py)
        self.lbl_sredn_mm.grid(column=2, row=wiersz, padx=px, pady=py)
        self.lbl_dlugosc.grid(column=3, row=wiersz, padx=px, pady=py)

        self.entry_g_jed.grid(column=1, row=wiersz + 1, padx=px, pady=py)
        self.entry_sredn_mm.grid(column=2, row=wiersz + 1, padx=px, pady=py)
        self.entry_dlugosc.grid(column=3, row=wiersz + 1, padx=px, pady=py)

        self.lbl_pusty_pod_glownymi.grid(column=1, row=3)

    def umieszczanie_widzetow_waga_cena(self, wiersz, px, py):

        self.lbl_waga_1mb.grid(column=0, row=wiersz, padx=px, pady=py)
        self.lbl_waga_podanego.grid(column=1, row=wiersz, padx=px, pady=py)
        self.lbl_cena_1mb.grid(column=2, row=wiersz, padx=px, pady=py)
        self.lbl_cena_1kg.grid(column=3, row=wiersz, padx=px, pady=py)
        self.lbl_cena_dla_podanego.grid(column=4, row=wiersz, padx=px, pady=py)

        self.entry_waga_1mb.grid(column=0, row=wiersz + 1, padx=px, pady=py)
        self.entry_waga_podanego.grid(column=1, row=wiersz + 1, padx=px, pady=py)
        self.entry_cena_1mb.grid(column=2, row=wiersz + 1, padx=px, pady=py)
        self.entry_cena_1kg.grid(column=3, row=wiersz + 1, padx=px, pady=py)
        self.entry_cena_dla_podanego.grid(column=4, row=wiersz + 1, padx=px, pady=py)
        self.lbl_pusty_pod_waga_cena.grid(column=1, row=wiersz + 2, padx=px, pady=py)

        self.canvas_obraz_pret = tk.Canvas(self, width=700, height=150)
        self.canvas_obraz_pret.place(relx = 0.5,rely = 0.8, anchor='center')
        self.image_pret = tk.PhotoImage(data=kod_obr.zakodowany_pret_img)
        self.canvas_obraz_pret.create_image(0, 0, anchor="nw", image=self.image_pret)

    def omenu_materialy_f(self, mater):
        if mater in c.materialy:
            self.waga_1mb_str.set('')
            self.waga_podanego_str.set('')
            self.cena_1mb_str.set('')
            self.cena_1kg_str.set('')
            self.cena_dla_podanego_str.set('')
            g_jedno = c.materialy[mater]['g_jednostkowa']
            self.g_jed_str.set(g_jedno)

    def clr_g_jedn(self):
        self.g_jed_str.set('')
        self.entry_g_jed.delete(0, 'end')

    def clr_srednica_mm(self):
        self.sredn_mm_str.set('')
        self.entry_sredn_mm.delete(0, 'end')

    def clr_waga_1mb(self):
        self.waga_1mb_str.set('')
        self.entry_waga_1mb.delete(0, 'end')

    def clr_waga_podanego(self):
        self.waga_podanego_str.set('')
        self.entry_waga_podanego.delete(0, 'end')

    def clr_cena_1mb(self):
        self.cena_1mb_str.set('')
        self.entry_cena_1mb.delete(0, 'end')

    def clr_cena_1kg(self):
        self.cena_1kg_str.set('')
        self.entry_cena_1kg.delete(0, 'end')

    def clr_cena_dla_podanego(self):
        self.cena_dla_podanego_str.set('')
        self.entry_cena_dla_podanego.delete(0, 'end')


class Tab_dlu_plaskownik(ttk.Frame):
    def __init__(self, master=None):
        super().__init__(master)

        self.tworzenie_widzetow_glownych()
        self.tworzenie_widzetow_waga_cena()
        self.btn_przelicz = ttk.Button(self, text='Przelicz', command=self.oblicz_dla_plaskownik)

        self.umieszczanie_widzetow_glownych(wiersz=1, px=5, py=1)
        self.umieszczanie_widzetow_waga_cena(wiersz=4, px=5, py=1)
        self.btn_przelicz.grid(column=5, row=7)
        for entry_widget in self.winfo_children():
            if isinstance(entry_widget, tk.Entry):
                entry_widget.bind("<Return>", lambda event: self.oblicz_dla_plaskownik())

    def oblicz_dla_plaskownik(self):

        if self.g_jed_str.get() and self.g_jed_str.get() != '0':
            g_jednos = float(self.g_jed_str.get().replace(',', '.'))
        else:
            g_jednos = False

        if self.szerokosc_str.get() and self.szerokosc_str.get() != '0':
            szerokosc = float(self.szerokosc_str.get().replace(',', '.')) / 1000
        else:
            szerokosc = False

        if self.dlugosc_str.get() and self.dlugosc_str.get() != '0':
            dlugo = float(self.dlugosc_str.get().replace(',', '.')) / 1000
        else:
            dlugo = False

        if self.grubosc_str.get() and self.grubosc_str.get() != '0':
            grubo = float(self.grubosc_str.get().replace(',', '.')) / 1000
        else:
            grubo = False

        if self.waga_1mb_str.get() and self.waga_1mb_str.get() != '0':
            waga_1mb = float(self.waga_1mb_str.get().replace(',', '.'))
        else:
            waga_1mb = False

        if self.waga_podanego_str.get() and self.waga_podanego_str.get() != '0':
            waga_dla_podan = float(self.waga_podanego_str.get().replace(',', '.'))
        else:
            waga_dla_podan = False

        if self.cena_1mb_str.get() and self.cena_1mb_str.get() != '0':
            cena_1mb = float(self.cena_1mb_str.get().replace(',', '.'))
        else:
            cena_1mb = False

        if self.cena_1kg_str.get() and self.cena_1kg_str.get() != '0':
            cena_1kg = float(self.cena_1kg_str.get().replace(',', '.'))
        else:
            cena_1kg = False

        if self.cena_dla_podanego_str.get() and self.cena_dla_podanego_str.get() != '0':
            cena_dla_podan = float(self.cena_dla_podanego_str.get().replace(',', '.'))
        else:
            cena_dla_podan = False

        # --------------OBLICZENIA-----------------------

        if waga_1mb and not waga_dla_podan and dlugo:
            self.waga_podanego_str.set(str(round(waga_1mb * dlugo, 2)))
            waga_dla_podan = float(self.waga_podanego_str.get().replace(',', '.'))

        if waga_dla_podan and not waga_1mb and dlugo:
            self.waga_1mb_str.set(str(round(waga_dla_podan / dlugo, 2)))
            waga_1mb = float(self.waga_1mb_str.get().replace(',', '.'))

        if not g_jednos and waga_1mb and dlugo and szerokosc and grubo:
            o = szerokosc*grubo
            self.g_jed_str.set(str(round(waga_1mb * (1 / o), 2)))
            g_jednos = float(self.g_jed_str.get().replace(',', '.'))

        if not waga_1mb and not waga_dla_podan and szerokosc and grubo and dlugo and g_jednos:
            o = szerokosc*grubo

            self.waga_1mb_str.set(str(round(o * g_jednos, 2)))
            waga_1mb = float(self.waga_1mb_str.get().replace(',', '.'))
            if dlugo:
                self.waga_podanego_str.set(str(round(waga_1mb * dlugo, 2)))
                waga_dla_podan = float(self.waga_podanego_str.get().replace(',', '.'))

        if cena_1mb and not cena_1kg and not cena_dla_podan and waga_1mb:

            self.cena_1kg_str.set(str(round(cena_1mb / waga_1mb, 2)))
            cena_1kg = float(self.cena_1kg_str.get().replace(',', '.'))

            if dlugo:
                self.cena_dla_podanego_str.set(str(round(cena_1mb * dlugo, 2)))
                cena_dla_podan = float(self.cena_dla_podanego_str.get().replace(',', '.'))

        if cena_1kg and not cena_1mb and not cena_dla_podan and waga_1mb:
            self.cena_1mb_str.set(str(round(cena_1kg * waga_1mb, 2)))
            cena_1mb = float(self.cena_1mb_str.get().replace(',', '.'))

            if dlugo:
                self.cena_dla_podanego_str.set(str(round(dlugo * cena_1mb, 2)))
                cena_dla_podan = float(self.cena_dla_podanego_str.get().replace(',', '.'))

        if cena_dla_podan and not cena_1kg and not cena_1mb and dlugo:

            self.cena_1mb_str.set(str(round(cena_dla_podan / dlugo, 2)))
            cena_1mb = float(self.cena_1mb_str.get().replace(',', '.'))

            if waga_1mb:
                self.cena_1kg_str.set(str(round(cena_1mb / waga_1mb, 2)))
                cena_1kg = float(self.cena_1kg_str.get().replace(',', '.'))

    def tworzenie_widzetow_glownych(self):

        self.lbl_pusty_gora = ttk.Label(self, text=' ')
        self.material_str = tk.StringVar()
        self.keys_materialow = list(c.materialy.keys())
        self.omenu_material = ttk.OptionMenu(self, self.material_str, self.keys_materialow[0], *self.keys_materialow,
                                             command=self.omenu_materialy_f)

        self.lbl_g_jed = ttk.Label(self, text='Gęstość jedn.\n [kg/m3]')
        self.g_jed_str = tk.StringVar()
        self.entry_g_jed = EntryValid(self, textvariable=self.g_jed_str,
                                      slownik_wyczysc={'clr_waga_1m': self.clr_waga_1mb,
                                                       'clr_waga_podanego': self.clr_waga_podanego,
                                                       'clr_cena_1kg': self.clr_cena_1kg,
                                                       'clr_cena_1mb': self.clr_cena_1mb,
                                                       'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_szerokosc = ttk.Label(self, text='Szerokość\n [mm]')
        self.szerokosc_str = tk.StringVar()
        self.entry_szerokosc = EntryValid(self, textvariable=self.szerokosc_str,
                                         slownik_wyczysc={'clr_waga_1m': self.clr_waga_1mb,
                                                          'clr_waga_podanego': self.clr_waga_podanego,
                                                          'clr_cena_1kg': self.clr_cena_1kg,
                                                          'clr_cena_1mb': self.clr_cena_1mb,
                                                          'clr_cena_dla_podanego': self.clr_cena_dla_podanego})


        self.lbl_grubosc = ttk.Label(self, text='Grubość\n [mm]')
        self.grubosc_str = tk.StringVar()
        self.entry_grubosc = EntryValid(self, textvariable=self.grubosc_str,
                                             slownik_wyczysc={'clr_waga_1m': self.clr_waga_1mb,
                                                              'clr_waga_podanego': self.clr_waga_podanego,
                                                              'clr_cena_1kg': self.clr_cena_1kg,
                                                              'clr_cena_1mb': self.clr_cena_1mb,
                                                              'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_dlugosc = ttk.Label(self, text='Długość\n[mm]')
        self.dlugosc_str = tk.StringVar()
        self.entry_dlugosc = EntryValid(self, textvariable=self.dlugosc_str,
                                        slownik_wyczysc={'clr_waga_podanego': self.clr_waga_podanego,
                                                         'clr_cena_1kg': self.clr_cena_1kg,
                                                         'clr_cena_1mb': self.clr_cena_1mb,
                                                         'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_pusty_pod_glownymi = ttk.Label(self, text=' ')

    def tworzenie_widzetow_waga_cena(self):

        self.lbl_waga_1mb = ttk.Label(self, text='Waga 1mb\n[kg]')
        self.waga_1mb_str = tk.StringVar()
        self.entry_waga_1mb = EntryValid(self, textvariable=self.waga_1mb_str,
                                         slownik_wyczysc={'clr_g_jedn': self.clr_g_jedn,
                                                          'clr_waga_podanego': self.clr_waga_podanego,
                                                          'clr_cena_1kg': self.clr_cena_1kg,
                                                          'clr_cena_1mb': self.clr_cena_1mb,
                                                          'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_waga_podanego = ttk.Label(self, text='Waga dla p. długości\n[kg]')
        self.waga_podanego_str = tk.StringVar()
        self.entry_waga_podanego = EntryValid(self, textvariable=self.waga_podanego_str,
                                              slownik_wyczysc={'clr_g_jedn': self.clr_g_jedn,
                                                               'clr_waga_1mb': self.clr_waga_1mb,
                                                               'clr_cena_1kg': self.clr_cena_1kg,
                                                               'clr_cena_1mb': self.clr_cena_1mb,
                                                               'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_cena_1mb = ttk.Label(self, text='Cena 1m\n[zł]')
        self.cena_1mb_str = tk.StringVar()
        self.entry_cena_1mb = EntryValid(self, textvariable=self.cena_1mb_str,
                                         slownik_wyczysc={'clr_cena_1kg': self.clr_cena_1kg,
                                                          'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_cena_1kg = ttk.Label(self, text='Cena 1kg\n[zł]')
        self.cena_1kg_str = tk.StringVar()
        self.entry_cena_1kg = EntryValid(self, textvariable=self.cena_1kg_str,
                                         slownik_wyczysc={'clr_cena_1mb': self.clr_cena_1mb,
                                                          'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_cena_dla_podanego = ttk.Label(self, text=f'Cena dla p. długości\n[zł]')
        self.cena_dla_podanego_str = tk.StringVar()
        self.entry_cena_dla_podanego = EntryValid(self, textvariable=self.cena_dla_podanego_str,
                                                  slownik_wyczysc={'clr_cena_1kg': self.clr_cena_1kg,
                                                                   'clr_cena_1mb': self.clr_cena_1mb})
        self.lbl_pusty_pod_waga_cena = ttk.Label(self, text=' ')

    def umieszczanie_widzetow_glownych(self, wiersz, px, py):


        self.lbl_pusty_gora.grid(column=1, row=0)

        self.omenu_material.grid(column=0, row=wiersz, padx=px, pady=py)
        self.lbl_g_jed.grid(column=1, row=wiersz, padx=px, pady=py)
        self.lbl_szerokosc.grid(column=2, row=wiersz, padx=px, pady=py)
        self.lbl_grubosc.grid(column=3, row=wiersz, padx=px, pady=py)
        self.lbl_dlugosc.grid(column=4, row=wiersz, padx=px, pady=py)

        self.entry_g_jed.grid(column=1, row=wiersz + 1, padx=px, pady=py)
        self.entry_szerokosc.grid(column=2, row=wiersz + 1, padx=px, pady=py)
        self.entry_grubosc.grid(column=3, row=wiersz + 1, padx=px, pady=py)
        self.entry_dlugosc.grid(column=4, row=wiersz + 1, padx=px, pady=py)

        self.lbl_pusty_pod_glownymi.grid(column=1, row=3)

    def umieszczanie_widzetow_waga_cena(self, wiersz, px, py):

        self.lbl_waga_1mb.grid(column=0, row=wiersz, padx=px, pady=py)
        self.lbl_waga_podanego.grid(column=1, row=wiersz, padx=px, pady=py)
        self.lbl_cena_1mb.grid(column=2, row=wiersz, padx=px, pady=py)
        self.lbl_cena_1kg.grid(column=3, row=wiersz, padx=px, pady=py)
        self.lbl_cena_dla_podanego.grid(column=4, row=wiersz, padx=px, pady=py)

        self.entry_waga_1mb.grid(column=0, row=wiersz + 1, padx=px, pady=py)
        self.entry_waga_podanego.grid(column=1, row=wiersz + 1, padx=px, pady=py)
        self.entry_cena_1mb.grid(column=2, row=wiersz + 1, padx=px, pady=py)
        self.entry_cena_1kg.grid(column=3, row=wiersz + 1, padx=px, pady=py)
        self.entry_cena_dla_podanego.grid(column=4, row=wiersz + 1, padx=px, pady=py)
        self.lbl_pusty_pod_waga_cena.grid(column=1, row=wiersz + 2, padx=px, pady=py)

        self.canvas_obraz_plaskownik = tk.Canvas(self, width=700, height=150)
        self.canvas_obraz_plaskownik.place(relx = 0.5,rely = 0.8, anchor='center')
        self.image_plaskownik = tk.PhotoImage(data=kod_obr.zakodowany_plaskownik_img)
        self.canvas_obraz_plaskownik.create_image(0, 0, anchor="nw", image=self.image_plaskownik)

    def omenu_materialy_f(self, mater):
        if mater in c.materialy:
            self.waga_1mb_str.set('')
            self.waga_podanego_str.set('')
            self.cena_1mb_str.set('')
            self.cena_1kg_str.set('')
            self.cena_dla_podanego_str.set('')
            g_jedno = c.materialy[mater]['g_jednostkowa']
            self.g_jed_str.set(g_jedno)

    def clr_g_jedn(self):
        self.g_jed_str.set('')
        self.entry_g_jed.delete(0, 'end')

    def clr_grubosc(self):
        self.grubosc_str.set('')
        self.entry_grubosc.delete(0, 'end')

    def clr_szerokosc(self):
        self.szerokosc_str.set('')
        self.entry_szerokosc.delete(0, 'end')

    def clr_waga_1mb(self):
        self.waga_1mb_str.set('')
        self.entry_waga_1mb.delete(0, 'end')

    def clr_waga_podanego(self):
        self.waga_podanego_str.set('')
        self.entry_waga_podanego.delete(0, 'end')

    def clr_cena_1mb(self):
        self.cena_1mb_str.set('')
        self.entry_cena_1mb.delete(0, 'end')

    def clr_cena_1kg(self):
        self.cena_1kg_str.set('')
        self.entry_cena_1kg.delete(0, 'end')

    def clr_cena_dla_podanego(self):
        self.cena_dla_podanego_str.set('')
        self.entry_cena_dla_podanego.delete(0, 'end')


class Tab_dlu_ksztaltownik(ttk.Frame):
    def __init__(self, master=None):
        super().__init__(master)

        self.tworzenie_widzetow_glownych()
        self.tworzenie_widzetow_waga_cena()
        self.btn_przelicz = ttk.Button(self, text='Przelicz', command=self.oblicz_dla_ksztaltownik)

        self.umieszczanie_widzetow_glownych(wiersz=1, px=5, py=1)
        self.umieszczanie_widzetow_waga_cena(wiersz=4, px=5, py=1)
        self.btn_przelicz.grid(column=5, row=7)
        for entry_widget in self.winfo_children():
            if isinstance(entry_widget, tk.Entry):
                entry_widget.bind("<Return>", lambda event: self.oblicz_dla_ksztaltownik())
    def oblicz_dla_ksztaltownik(self):

        if self.g_jed_str.get() and self.g_jed_str.get() != '0':
            g_jednos = float(self.g_jed_str.get().replace(',', '.'))
        else:
            g_jednos = False

        if self.szerokosc_str.get() and self.szerokosc_str.get() != '0':
            szerokosc = float(self.szerokosc_str.get().replace(',', '.')) / 1000
        else:
            szerokosc = False

        if self.wysokosc_str.get() and self.wysokosc_str.get() != '0':
            wysokosc = float(self.wysokosc_str.get().replace(',', '.')) / 1000
        else:
            wysokosc = False

        if self.dlugosc_str.get() and self.dlugosc_str.get() != '0':
            dlugo = float(self.dlugosc_str.get().replace(',', '.')) / 1000
        else:
            dlugo = False

        if self.grub_scianki_str.get() and self.grub_scianki_str.get() != '0':
            grub_scianki = float(self.grub_scianki_str.get().replace(',', '.')) / 1000
        else:
            grub_scianki = False

        if self.waga_1mb_str.get() and self.waga_1mb_str.get() != '0':
            waga_1mb = float(self.waga_1mb_str.get().replace(',', '.'))
        else:
            waga_1mb = False

        if self.waga_podanego_str.get() and self.waga_podanego_str.get() != '0':
            waga_dla_podan = float(self.waga_podanego_str.get().replace(',', '.'))
        else:
            waga_dla_podan = False

        if self.cena_1mb_str.get() and self.cena_1mb_str.get() != '0':
            cena_1mb = float(self.cena_1mb_str.get().replace(',', '.'))
        else:
            cena_1mb = False

        if self.cena_1kg_str.get() and self.cena_1kg_str.get() != '0':
            cena_1kg = float(self.cena_1kg_str.get().replace(',', '.'))
        else:
            cena_1kg = False

        if self.cena_dla_podanego_str.get() and self.cena_dla_podanego_str.get() != '0':
            cena_dla_podan = float(self.cena_dla_podanego_str.get().replace(',', '.'))
        else:
            cena_dla_podan = False

        # --------------OBLICZENIA-----------------------

        if waga_1mb and not waga_dla_podan and dlugo:
            self.waga_podanego_str.set(str(round(waga_1mb * dlugo, 2)))
            waga_dla_podan = float(self.waga_podanego_str.get().replace(',', '.'))

        if waga_dla_podan and not waga_1mb and dlugo:
            self.waga_1mb_str.set(str(round(waga_dla_podan / dlugo, 2)))
            waga_1mb = float(self.waga_1mb_str.get().replace(',', '.'))

        if not g_jednos and waga_1mb and wysokosc and szerokosc and grub_scianki:
            obj_wew = (wysokosc - 2 * grub_scianki) * (szerokosc - 2 * grub_scianki)
            objetosc = wysokosc * szerokosc  - obj_wew
            self.g_jed_str.set(str(round(waga_1mb / objetosc, 2)))
            g_jednos = float(self.g_jed_str.get().replace(',', '.'))

        if not waga_1mb and not waga_dla_podan and wysokosc and szerokosc and grub_scianki and g_jednos:
            obj_wew = (wysokosc - 2 * grub_scianki) * (szerokosc - 2 * grub_scianki)
            objetosc = wysokosc * szerokosc  - obj_wew

            self.waga_1mb_str.set(str(round(objetosc * g_jednos, 2)))
            waga_1mb = float(self.waga_1mb_str.get().replace(',', '.'))
            if dlugo:
                self.waga_podanego_str.set(str(round(waga_1mb * dlugo, 2)))
                waga_dla_podan = float(self.waga_podanego_str.get().replace(',', '.'))


        if cena_1mb and not cena_1kg and not cena_dla_podan and waga_1mb:

            self.cena_1kg_str.set(str(round(cena_1mb / waga_1mb, 2)))
            cena_1kg = float(self.cena_1kg_str.get().replace(',', '.'))

            if dlugo:
                self.cena_dla_podanego_str.set(str(round(cena_1mb * dlugo, 2)))
                cena_dla_podan = float(self.cena_dla_podanego_str.get().replace(',', '.'))

        if cena_1kg and not cena_1mb and not cena_dla_podan and waga_1mb:
            self.cena_1mb_str.set(str(round(cena_1kg * waga_1mb, 2)))
            cena_1mb = float(self.cena_1mb_str.get().replace(',', '.'))

            if dlugo:
                self.cena_dla_podanego_str.set(str(round(dlugo * cena_1mb, 2)))
                cena_dla_podan = float(self.cena_dla_podanego_str.get().replace(',', '.'))

        if cena_dla_podan and not cena_1kg and not cena_1mb and dlugo:

            self.cena_1mb_str.set(str(round(cena_dla_podan / dlugo, 2)))
            cena_1mb = float(self.cena_1mb_str.get().replace(',', '.'))

            if waga_1mb:
                self.cena_1kg_str.set(str(round(cena_1mb / waga_1mb, 2)))
                cena_1kg = float(self.cena_1kg_str.get().replace(',', '.'))



    def tworzenie_widzetow_glownych(self):

        self.lbl_pusty_gora = ttk.Label(self, text=' ')
        self.material_str = tk.StringVar()
        self.keys_materialow = list(c.materialy.keys())
        self.omenu_material = ttk.OptionMenu(self, self.material_str, self.keys_materialow[0], *self.keys_materialow,
                                             command=self.omenu_materialy_f)

        self.lbl_g_jed = ttk.Label(self, text='Gęstość jedn.\n [kg/m3]')
        self.g_jed_str = tk.StringVar()
        self.entry_g_jed = EntryValid(self, textvariable=self.g_jed_str,
                                      slownik_wyczysc={'clr_waga_1m': self.clr_waga_1mb,
                                                       'clr_waga_podanego': self.clr_waga_podanego,
                                                       'clr_cena_1kg': self.clr_cena_1kg,
                                                       'clr_cena_1mb': self.clr_cena_1mb,
                                                       'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_wysokosc = ttk.Label(self, text='Wysokosc\n [mm]')
        self.wysokosc_str = tk.StringVar()
        self.entry_wysokosc = EntryValid(self, textvariable=self.wysokosc_str,
                                         slownik_wyczysc={'clr_waga_1m': self.clr_waga_1mb,
                                                          'clr_waga_podanego': self.clr_waga_podanego,
                                                          'clr_cena_1kg': self.clr_cena_1kg,
                                                          'clr_cena_1mb': self.clr_cena_1mb,
                                                          'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_szerokosc = ttk.Label(self, text='Szerokosc\n [mm]')
        self.szerokosc_str = tk.StringVar()
        self.entry_szerokosc = EntryValid(self, textvariable=self.szerokosc_str,
                                          slownik_wyczysc={'clr_waga_1m': self.clr_waga_1mb,
                                                           'clr_waga_podanego': self.clr_waga_podanego,
                                                           'clr_cena_1kg': self.clr_cena_1kg,
                                                           'clr_cena_1mb': self.clr_cena_1mb,
                                                           'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_grub_scianki = ttk.Label(self, text='Grub. ścianki\n [mm]')
        self.grub_scianki_str = tk.StringVar()
        self.entry_grub_scianki = EntryValid(self, textvariable=self.grub_scianki_str,
                                             slownik_wyczysc={'clr_waga_1m': self.clr_waga_1mb,
                                                              'clr_waga_podanego': self.clr_waga_podanego,
                                                              'clr_cena_1kg': self.clr_cena_1kg,
                                                              'clr_cena_1mb': self.clr_cena_1mb,
                                                              'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_dlugosc = ttk.Label(self, text='Długość\n[mm]')
        self.dlugosc_str = tk.StringVar()
        self.entry_dlugosc = EntryValid(self, textvariable=self.dlugosc_str,
                                        slownik_wyczysc={'clr_waga_podanego': self.clr_waga_podanego,
                                                         'clr_cena_1kg': self.clr_cena_1kg,
                                                         'clr_cena_1mb': self.clr_cena_1mb,
                                                         'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_pusty_pod_glownymi = ttk.Label(self, text=' ')

    def tworzenie_widzetow_waga_cena(self):


        self.lbl_waga_1mb = ttk.Label(self, text='Waga 1mb\n[kg]')
        self.waga_1mb_str = tk.StringVar()
        self.entry_waga_1mb = EntryValid(self, textvariable=self.waga_1mb_str,
                                         slownik_wyczysc={'clr_g_jedn': self.clr_g_jedn,
                                                          'clr_waga_podanego': self.clr_waga_podanego,
                                                          'clr_cena_1kg': self.clr_cena_1kg,
                                                          'clr_cena_1mb': self.clr_cena_1mb,
                                                          'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_waga_podanego = ttk.Label(self, text='Waga dla p. długości\n[kg]')
        self.waga_podanego_str = tk.StringVar()
        self.entry_waga_podanego = EntryValid(self, textvariable=self.waga_podanego_str,
                                              slownik_wyczysc={'clr_g_jedn': self.clr_g_jedn,
                                                               'clr_waga_1mb': self.clr_waga_1mb,
                                                               'clr_cena_1kg': self.clr_cena_1kg,
                                                               'clr_cena_1mb': self.clr_cena_1mb,
                                                               'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_cena_1mb = ttk.Label(self, text='Cena 1m\n[zł]')
        self.cena_1mb_str = tk.StringVar()
        self.entry_cena_1mb = EntryValid(self, textvariable=self.cena_1mb_str,
                                         slownik_wyczysc={'clr_cena_1kg': self.clr_cena_1kg,
                                                          'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_cena_1kg = ttk.Label(self, text='Cena 1kg\n[zł]')
        self.cena_1kg_str = tk.StringVar()
        self.entry_cena_1kg = EntryValid(self, textvariable=self.cena_1kg_str,
                                         slownik_wyczysc={'clr_cena_1mb': self.clr_cena_1mb,
                                                          'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_cena_dla_podanego = ttk.Label(self, text=f'Cena dla p. długości\n[zł]')
        self.cena_dla_podanego_str = tk.StringVar()
        self.entry_cena_dla_podanego = EntryValid(self, textvariable=self.cena_dla_podanego_str,
                                                  slownik_wyczysc={'clr_cena_1kg': self.clr_cena_1kg,
                                                                   'clr_cena_1mb': self.clr_cena_1mb})
        self.lbl_pusty_pod_waga_cena = ttk.Label(self, text=' ')

    def umieszczanie_widzetow_glownych(self, wiersz, px, py):


        self.lbl_pusty_gora.grid(column=1, row=0)

        self.omenu_material.grid(column=0, row=wiersz, padx=px, pady=py)
        self.lbl_g_jed.grid(column=1, row=wiersz, padx=px, pady=py)
        self.lbl_wysokosc.grid(column=2, row=wiersz, padx=px, pady=py)
        self.lbl_szerokosc.grid(column=3, row=wiersz, padx=px, pady=py)
        self.lbl_grub_scianki.grid(column=4, row=wiersz, padx=px, pady=py)
        self.lbl_dlugosc.grid(column=5, row=wiersz, padx=px, pady=py)

        self.entry_g_jed.grid(column=1, row=wiersz + 1, padx=px, pady=py)
        self.entry_wysokosc.grid(column=2, row=wiersz + 1, padx=px, pady=py)
        self.entry_szerokosc.grid(column=3, row=wiersz + 1, padx=px, pady=py)
        self.entry_grub_scianki.grid(column=4, row=wiersz + 1, padx=px, pady=py)
        self.entry_dlugosc.grid(column=5, row=wiersz + 1, padx=px, pady=py)

        self.lbl_pusty_pod_glownymi.grid(column=1, row=3)

    def umieszczanie_widzetow_waga_cena(self, wiersz, px, py):

        self.lbl_waga_1mb.grid(column=0, row=wiersz, padx=px, pady=py)
        self.lbl_waga_podanego.grid(column=1, row=wiersz, padx=px, pady=py)
        self.lbl_cena_1mb.grid(column=2, row=wiersz, padx=px, pady=py)
        self.lbl_cena_1kg.grid(column=3, row=wiersz, padx=px, pady=py)
        self.lbl_cena_dla_podanego.grid(column=4, row=wiersz, padx=px, pady=py)

        self.entry_waga_1mb.grid(column=0, row=wiersz + 1, padx=px, pady=py)
        self.entry_waga_podanego.grid(column=1, row=wiersz + 1, padx=px, pady=py)
        self.entry_cena_1mb.grid(column=2, row=wiersz + 1, padx=px, pady=py)
        self.entry_cena_1kg.grid(column=3, row=wiersz + 1, padx=px, pady=py)
        self.entry_cena_dla_podanego.grid(column=4, row=wiersz + 1, padx=px, pady=py)
        self.lbl_pusty_pod_waga_cena.grid(column=1, row=wiersz + 2, padx=px, pady=py)

        self.canvas_obraz_ksztaltownik = tk.Canvas(self, width=700, height=150)
        self.canvas_obraz_ksztaltownik.place(relx = 0.5,rely = 0.8, anchor='center')
        self.image_ksztaltownik = tk.PhotoImage(data=kod_obr.zakodowany_ksztaltownik_img)
        self.canvas_obraz_ksztaltownik.create_image(0, 0, anchor="nw", image=self.image_ksztaltownik)

    def omenu_materialy_f(self, mater):
        if mater in c.materialy:
            self.waga_1mb_str.set('')
            self.waga_podanego_str.set('')
            self.cena_1mb_str.set('')
            self.cena_1kg_str.set('')
            self.cena_dla_podanego_str.set('')
            g_jedno = c.materialy[mater]['g_jednostkowa']
            self.g_jed_str.set(g_jedno)

    def clr_g_jedn(self):
        self.g_jed_str.set('')
        self.entry_g_jed.delete(0, 'end')

    def clr_wysokosc(self):
        self.wysokosc_str.set('')
        self.entry_wysokosc.delete(0, 'end')

    def clr_szerokosc(self):
        self.szerokosc_str.set('')
        self.entry_szerokosc.delete(0, 'end')

    def clr_waga_1mb(self):
        self.waga_1mb_str.set('')
        self.entry_waga_1mb.delete(0, 'end')

    def clr_waga_podanego(self):
        self.waga_podanego_str.set('')
        self.entry_waga_podanego.delete(0, 'end')

    def clr_cena_1mb(self):
        self.cena_1mb_str.set('')
        self.entry_cena_1mb.delete(0, 'end')

    def clr_cena_1kg(self):
        self.cena_1kg_str.set('')
        self.entry_cena_1kg.delete(0, 'end')

    def clr_cena_dla_podanego(self):
        self.cena_dla_podanego_str.set('')
        self.entry_cena_dla_podanego.delete(0, 'end')


class Tab_dlu_katownik(ttk.Frame):
    def __init__(self, master=None):
        super().__init__(master)

        self.tworzenie_widzetow_glownych()
        self.tworzenie_widzetow_waga_cena()
        self.btn_przelicz = ttk.Button(self, text='Przelicz', command=self.oblicz_dla_katownik)

        self.umieszczanie_widzetow_glownych(wiersz=1, px=5, py=1)
        self.umieszczanie_widzetow_waga_cena(wiersz=4, px=5, py=1)
        self.btn_przelicz.grid(column=5, row=7)
        for entry_widget in self.winfo_children():
            if isinstance(entry_widget, tk.Entry):
                entry_widget.bind("<Return>", lambda event: self.oblicz_dla_katownik())

    def oblicz_dla_katownik(self):

        if self.g_jed_str.get() and self.g_jed_str.get() != '0':
            g_jednos = float(self.g_jed_str.get().replace(',', '.'))
        else:
            g_jednos = False

        if self.szerokosc_str.get() and self.szerokosc_str.get() != '0':
            szerokosc = float(self.szerokosc_str.get().replace(',', '.')) / 1000
        else:
            szerokosc = False

        if self.wysokosc_str.get() and self.wysokosc_str.get() != '0':
            wysokosc = float(self.wysokosc_str.get().replace(',', '.')) / 1000
        else:
            wysokosc = False

        if self.dlugosc_str.get() and self.dlugosc_str.get() != '0':
            dlugo = float(self.dlugosc_str.get().replace(',', '.')) / 1000
        else:
            dlugo = False

        if self.grub_scianki_str.get() and self.grub_scianki_str.get() != '0':
            grub_scianki = float(self.grub_scianki_str.get().replace(',', '.')) / 1000
        else:
            grub_scianki = False

        if self.waga_1mb_str.get() and self.waga_1mb_str.get() != '0':
            waga_1mb = float(self.waga_1mb_str.get().replace(',', '.'))
        else:
            waga_1mb = False

        if self.waga_podanego_str.get() and self.waga_podanego_str.get() != '0':
            waga_dla_podan = float(self.waga_podanego_str.get().replace(',', '.'))
        else:
            waga_dla_podan = False

        if self.cena_1mb_str.get() and self.cena_1mb_str.get() != '0':
            cena_1mb = float(self.cena_1mb_str.get().replace(',', '.'))
        else:
            cena_1mb = False

        if self.cena_1kg_str.get() and self.cena_1kg_str.get() != '0':
            cena_1kg = float(self.cena_1kg_str.get().replace(',', '.'))
        else:
            cena_1kg = False

        if self.cena_dla_podanego_str.get() and self.cena_dla_podanego_str.get() != '0':
            cena_dla_podan = float(self.cena_dla_podanego_str.get().replace(',', '.'))
        else:
            cena_dla_podan = False

        # --------------OBLICZENIA-----------------------

        if waga_1mb and not waga_dla_podan and dlugo:
            self.waga_podanego_str.set(str(round(waga_1mb * dlugo, 2)))
            waga_dla_podan = float(self.waga_podanego_str.get().replace(',', '.'))

        if waga_dla_podan and not waga_1mb and dlugo:
            self.waga_1mb_str.set(str(round(waga_dla_podan / dlugo, 2)))
            waga_1mb = float(self.waga_1mb_str.get().replace(',', '.'))

        if not g_jednos and waga_1mb and wysokosc and szerokosc and grub_scianki and dlugo:
            objetosc = (wysokosc * grub_scianki + (szerokosc - grub_scianki) * grub_scianki) * dlugo
            self.g_jed_str.set(str(round(waga_1mb * (1 / objetosc), 2)))
            g_jednos = float(self.g_jed_str.get().replace(',', '.'))

        if not waga_1mb and not waga_dla_podan and wysokosc and szerokosc and grub_scianki and g_jednos:
            objetosc = (wysokosc * grub_scianki + (szerokosc - grub_scianki) * grub_scianki)

            self.waga_1mb_str.set(str(round(objetosc * g_jednos, 2)))
            waga_1mb = float(self.waga_1mb_str.get().replace(',', '.'))
            if dlugo:
                self.waga_podanego_str.set(str(round(waga_1mb * dlugo, 2)))
                waga_dla_podan = float(self.waga_podanego_str.get().replace(',', '.'))

        if cena_1mb and not cena_1kg and not cena_dla_podan and waga_1mb:

            self.cena_1kg_str.set(str(round(cena_1mb / waga_1mb, 2)))
            cena_1kg = float(self.cena_1kg_str.get().replace(',', '.'))

            if dlugo:
                self.cena_dla_podanego_str.set(str(round(cena_1mb * dlugo, 2)))
                cena_dla_podan = float(self.cena_dla_podanego_str.get().replace(',', '.'))

        if cena_1kg and not cena_1mb and not cena_dla_podan and waga_1mb:
            self.cena_1mb_str.set(str(round(cena_1kg * waga_1mb, 2)))
            cena_1mb = float(self.cena_1mb_str.get().replace(',', '.'))

            if dlugo:
                self.cena_dla_podanego_str.set(str(round(dlugo * cena_1mb, 2)))
                cena_dla_podan = float(self.cena_dla_podanego_str.get().replace(',', '.'))

        if cena_dla_podan and not cena_1kg and not cena_1mb and dlugo:

            self.cena_1mb_str.set(str(round(cena_dla_podan / dlugo, 2)))
            cena_1mb = float(self.cena_1mb_str.get().replace(',', '.'))

            if waga_1mb:
                self.cena_1kg_str.set(str(round(cena_1mb / waga_1mb, 2)))
                cena_1kg = float(self.cena_1kg_str.get().replace(',', '.'))

    def tworzenie_widzetow_glownych(self):

        self.lbl_pusty_gora = ttk.Label(self, text=' ')
        self.material_str = tk.StringVar()
        self.keys_materialow = list(c.materialy.keys())
        self.omenu_material = ttk.OptionMenu(self, self.material_str, self.keys_materialow[0], *self.keys_materialow,
                                             command=self.omenu_materialy_f)

        self.lbl_g_jed = ttk.Label(self, text='Gęstość jedn.\n [kg/m3]')
        self.g_jed_str = tk.StringVar()
        self.entry_g_jed = EntryValid(self, textvariable=self.g_jed_str,
                                      slownik_wyczysc={'clr_waga_1m': self.clr_waga_1mb,
                                                       'clr_waga_podanego': self.clr_waga_podanego,
                                                       'clr_cena_1kg': self.clr_cena_1kg,
                                                       'clr_cena_1mb': self.clr_cena_1mb,
                                                       'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_wysokosc = ttk.Label(self, text='Wysokosc\n [mm]')
        self.wysokosc_str = tk.StringVar()
        self.entry_wysokosc = EntryValid(self, textvariable=self.wysokosc_str,
                                         slownik_wyczysc={'clr_waga_1m': self.clr_waga_1mb,
                                                          'clr_waga_podanego': self.clr_waga_podanego,
                                                          'clr_cena_1kg': self.clr_cena_1kg,
                                                          'clr_cena_1mb': self.clr_cena_1mb,
                                                          'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_szerokosc = ttk.Label(self, text='Szerokosc\n [mm]')
        self.szerokosc_str = tk.StringVar()
        self.entry_szerokosc = EntryValid(self, textvariable=self.szerokosc_str,
                                          slownik_wyczysc={'clr_waga_1m': self.clr_waga_1mb,
                                                           'clr_waga_podanego': self.clr_waga_podanego,
                                                           'clr_cena_1kg': self.clr_cena_1kg,
                                                           'clr_cena_1mb': self.clr_cena_1mb,
                                                           'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_grub_scianki = ttk.Label(self, text='Grub. ścianki\n [mm]')
        self.grub_scianki_str = tk.StringVar()
        self.entry_grub_scianki = EntryValid(self, textvariable=self.grub_scianki_str,
                                             slownik_wyczysc={'clr_waga_1m': self.clr_waga_1mb,
                                                              'clr_waga_podanego': self.clr_waga_podanego,
                                                              'clr_cena_1kg': self.clr_cena_1kg,
                                                              'clr_cena_1mb': self.clr_cena_1mb,
                                                              'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_dlugosc = ttk.Label(self, text='Długość\n[mm]')
        self.dlugosc_str = tk.StringVar()
        self.entry_dlugosc = EntryValid(self, textvariable=self.dlugosc_str,
                                        slownik_wyczysc={'clr_waga_podanego': self.clr_waga_podanego,
                                                         'clr_cena_1kg': self.clr_cena_1kg,
                                                         'clr_cena_1mb': self.clr_cena_1mb,
                                                         'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_pusty_pod_glownymi = ttk.Label(self, text=' ')

    def tworzenie_widzetow_waga_cena(self):

        self.lbl_waga_1mb = ttk.Label(self, text='Waga 1mb\n[kg]')
        self.waga_1mb_str = tk.StringVar()
        self.entry_waga_1mb = EntryValid(self, textvariable=self.waga_1mb_str,
                                         slownik_wyczysc={'clr_g_jedn': self.clr_g_jedn,
                                                          'clr_waga_podanego': self.clr_waga_podanego,
                                                          'clr_cena_1kg': self.clr_cena_1kg,
                                                          'clr_cena_1mb': self.clr_cena_1mb,
                                                          'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_waga_podanego = ttk.Label(self, text='Waga dla p. długości\n[kg]')
        self.waga_podanego_str = tk.StringVar()
        self.entry_waga_podanego = EntryValid(self, textvariable=self.waga_podanego_str,
                                              slownik_wyczysc={'clr_g_jedn': self.clr_g_jedn,
                                                               'clr_waga_1mb': self.clr_waga_1mb,
                                                               'clr_cena_1kg': self.clr_cena_1kg,
                                                               'clr_cena_1mb': self.clr_cena_1mb,
                                                               'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_cena_1mb = ttk.Label(self, text='Cena 1m\n[zł]')
        self.cena_1mb_str = tk.StringVar()
        self.entry_cena_1mb = EntryValid(self, textvariable=self.cena_1mb_str,
                                         slownik_wyczysc={'clr_cena_1kg': self.clr_cena_1kg,
                                                          'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_cena_1kg = ttk.Label(self, text='Cena 1kg\n[zł]')
        self.cena_1kg_str = tk.StringVar()
        self.entry_cena_1kg = EntryValid(self, textvariable=self.cena_1kg_str,
                                         slownik_wyczysc={'clr_cena_1mb': self.clr_cena_1mb,
                                                          'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_cena_dla_podanego = ttk.Label(self, text=f'Cena dla p. długości\n[zł]')
        self.cena_dla_podanego_str = tk.StringVar()
        self.entry_cena_dla_podanego = EntryValid(self, textvariable=self.cena_dla_podanego_str,
                                                  slownik_wyczysc={'clr_cena_1kg': self.clr_cena_1kg,
                                                                   'clr_cena_1mb': self.clr_cena_1mb})
        self.lbl_pusty_pod_waga_cena = ttk.Label(self, text=' ')

    def umieszczanie_widzetow_glownych(self, wiersz, px, py):


        self.lbl_pusty_gora.grid(column=1, row=0)

        self.omenu_material.grid(column=0, row=wiersz, padx=px, pady=py)
        self.lbl_g_jed.grid(column=1, row=wiersz, padx=px, pady=py)
        self.lbl_wysokosc.grid(column=2, row=wiersz, padx=px, pady=py)
        self.lbl_szerokosc.grid(column=3, row=wiersz, padx=px, pady=py)
        self.lbl_grub_scianki.grid(column=4, row=wiersz, padx=px, pady=py)
        self.lbl_dlugosc.grid(column=5, row=wiersz, padx=px, pady=py)

        self.entry_g_jed.grid(column=1, row=wiersz + 1, padx=px, pady=py)
        self.entry_wysokosc.grid(column=2, row=wiersz + 1, padx=px, pady=py)
        self.entry_szerokosc.grid(column=3, row=wiersz + 1, padx=px, pady=py)
        self.entry_grub_scianki.grid(column=4, row=wiersz + 1, padx=px, pady=py)
        self.entry_dlugosc.grid(column=5, row=wiersz + 1, padx=px, pady=py)

        self.lbl_pusty_pod_glownymi.grid(column=1, row=3)

    def umieszczanie_widzetow_waga_cena(self, wiersz, px, py):

        self.lbl_waga_1mb.grid(column=0, row=wiersz, padx=px, pady=py)
        self.lbl_waga_podanego.grid(column=1, row=wiersz, padx=px, pady=py)
        self.lbl_cena_1mb.grid(column=2, row=wiersz, padx=px, pady=py)
        self.lbl_cena_1kg.grid(column=3, row=wiersz, padx=px, pady=py)
        self.lbl_cena_dla_podanego.grid(column=4, row=wiersz, padx=px, pady=py)

        self.entry_waga_1mb.grid(column=0, row=wiersz + 1, padx=px, pady=py)
        self.entry_waga_podanego.grid(column=1, row=wiersz + 1, padx=px, pady=py)
        self.entry_cena_1mb.grid(column=2, row=wiersz + 1, padx=px, pady=py)
        self.entry_cena_1kg.grid(column=3, row=wiersz + 1, padx=px, pady=py)
        self.entry_cena_dla_podanego.grid(column=4, row=wiersz + 1, padx=px, pady=py)
        self.lbl_pusty_pod_waga_cena.grid(column=1, row=wiersz + 2, padx=px, pady=py)

        self.canvas_obraz_katownik = tk.Canvas(self, width=700, height=150)
        self.canvas_obraz_katownik.place(relx = 0.5,rely = 0.8, anchor='center')
        self.image_katownik = tk.PhotoImage(data=kod_obr.zakodowany_katownik_img)
        self.canvas_obraz_katownik.create_image(0, 0, anchor="nw", image=self.image_katownik)

    def omenu_materialy_f(self, mater):
        if mater in c.materialy:
            self.waga_1mb_str.set('')
            self.waga_podanego_str.set('')
            self.cena_1mb_str.set('')
            self.cena_1kg_str.set('')
            self.cena_dla_podanego_str.set('')
            g_jedno = c.materialy[mater]['g_jednostkowa']
            self.g_jed_str.set(g_jedno)

    def clr_g_jedn(self):
        self.g_jed_str.set('')
        self.entry_g_jed.delete(0, 'end')

    def clr_wysokosc(self):
        self.wysokosc_str.set('')
        self.entry_wysokosc.delete(0, 'end')

    def clr_szerokosc(self):
        self.szerokosc_str.set('')
        self.entry_szerokosc.delete(0, 'end')

    def clr_waga_1mb(self):
        self.waga_1mb_str.set('')
        self.entry_waga_1mb.delete(0, 'end')

    def clr_waga_podanego(self):
        self.waga_podanego_str.set('')
        self.entry_waga_podanego.delete(0, 'end')

    def clr_cena_1mb(self):
        self.cena_1mb_str.set('')
        self.entry_cena_1mb.delete(0, 'end')

    def clr_cena_1kg(self):
        self.cena_1kg_str.set('')
        self.entry_cena_1kg.delete(0, 'end')

    def clr_cena_dla_podanego(self):
        self.cena_dla_podanego_str.set('')
        self.entry_cena_dla_podanego.delete(0, 'end')


class Tab_dlu_ceownik(ttk.Frame):
    def __init__(self, master=None):
        super().__init__(master)

        self.tworzenie_widzetow_glownych()
        self.tworzenie_widzetow_waga_cena()
        self.btn_przelicz = ttk.Button(self, text='Przelicz', command=self.oblicz_dla_ceownik)

        self.umieszczanie_widzetow_glownych(wiersz=1, px=5, py=1)
        self.umieszczanie_widzetow_waga_cena(wiersz=4, px=5, py=1)
        self.btn_przelicz.grid(column=5, row=7)
        for entry_widget in self.winfo_children():
            if isinstance(entry_widget, tk.Entry):
                entry_widget.bind("<Return>", lambda event: self.oblicz_dla_ceownik())
    def oblicz_dla_ceownik(self):

        if self.g_jed_str.get() and self.g_jed_str.get() != '0':
            g_jednos = float(self.g_jed_str.get().replace(',', '.'))
        else:
            g_jednos = False

        if self.szerokosc_str.get() and self.szerokosc_str.get() != '0':
            szerokosc = float(self.szerokosc_str.get().replace(',', '.')) / 1000
        else:
            szerokosc = False

        if self.wysokosc_str.get() and self.wysokosc_str.get() != '0':
            wysokosc = float(self.wysokosc_str.get().replace(',', '.')) / 1000
        else:
            wysokosc = False

        if self.dlugosc_str.get() and self.dlugosc_str.get() != '0':
            dlugo = float(self.dlugosc_str.get().replace(',', '.')) / 1000
        else:
            dlugo = False

        if self.grub_scianki_str.get() and self.grub_scianki_str.get() != '0':
            grub_scianki = float(self.grub_scianki_str.get().replace(',', '.')) / 1000
        else:
            grub_scianki = False

        if self.waga_1mb_str.get() and self.waga_1mb_str.get() != '0':
            waga_1mb = float(self.waga_1mb_str.get().replace(',', '.'))
        else:
            waga_1mb = False

        if self.waga_podanego_str.get() and self.waga_podanego_str.get() != '0':
            waga_dla_podan = float(self.waga_podanego_str.get().replace(',', '.'))
        else:
            waga_dla_podan = False

        if self.cena_1mb_str.get() and self.cena_1mb_str.get() != '0':
            cena_1mb = float(self.cena_1mb_str.get().replace(',', '.'))
        else:
            cena_1mb = False

        if self.cena_1kg_str.get() and self.cena_1kg_str.get() != '0':
            cena_1kg = float(self.cena_1kg_str.get().replace(',', '.'))
        else:
            cena_1kg = False

        if self.cena_dla_podanego_str.get() and self.cena_dla_podanego_str.get() != '0':
            cena_dla_podan = float(self.cena_dla_podanego_str.get().replace(',', '.'))
        else:
            cena_dla_podan = False

        # --------------OBLICZENIA-----------------------

        if waga_1mb and not waga_dla_podan and dlugo:
            self.waga_podanego_str.set(str(round(waga_1mb * dlugo, 2)))
            waga_dla_podan = float(self.waga_podanego_str.get().replace(',', '.'))

        if waga_dla_podan and not waga_1mb and dlugo:
            self.waga_1mb_str.set(str(round(waga_dla_podan / dlugo, 2)))
            waga_1mb = float(self.waga_1mb_str.get().replace(',', '.'))

        if not g_jednos and waga_1mb and wysokosc and szerokosc and grub_scianki:
            objetosc = (2 * (wysokosc * grub_scianki) + (szerokosc - 2 * grub_scianki) * grub_scianki)
            self.g_jed_str.set(str(round(waga_1mb * (1 / objetosc), 2)))
            g_jednos = float(self.g_jed_str.get().replace(',', '.'))

        if not waga_1mb and not waga_dla_podan and wysokosc and szerokosc and grub_scianki and dlugo and g_jednos:
            objetosc = (2 * (szerokosc * grub_scianki) + (wysokosc - 2 * grub_scianki) * grub_scianki)

            self.waga_1mb_str.set(str(round(objetosc * g_jednos, 2)))
            waga_1mb = float(self.waga_1mb_str.get().replace(',', '.'))
            if dlugo:
                self.waga_podanego_str.set(str(round(waga_1mb * dlugo, 2)))
                waga_dla_podan = float(self.waga_podanego_str.get().replace(',', '.'))

        if cena_1mb and not cena_1kg and not cena_dla_podan and waga_1mb:

            self.cena_1kg_str.set(str(round(cena_1mb / waga_1mb, 2)))
            cena_1kg = float(self.cena_1kg_str.get().replace(',', '.'))

            if dlugo:
                self.cena_dla_podanego_str.set(str(round(cena_1mb * dlugo, 2)))
                cena_dla_podan = float(self.cena_dla_podanego_str.get().replace(',', '.'))

        if cena_1kg and not cena_1mb and not cena_dla_podan and waga_1mb:
            self.cena_1mb_str.set(str(round(cena_1kg * waga_1mb, 2)))
            cena_1mb = float(self.cena_1mb_str.get().replace(',', '.'))

            if dlugo:
                self.cena_dla_podanego_str.set(str(round(dlugo * cena_1mb, 2)))
                cena_dla_podan = float(self.cena_dla_podanego_str.get().replace(',', '.'))

        if cena_dla_podan and not cena_1kg and not cena_1mb and dlugo:

            self.cena_1mb_str.set(str(round(cena_dla_podan / dlugo, 2)))
            cena_1mb = float(self.cena_1mb_str.get().replace(',', '.'))

            if waga_1mb:
                self.cena_1kg_str.set(str(round(cena_1mb / waga_1mb, 2)))
                cena_1kg = float(self.cena_1kg_str.get().replace(',', '.'))

    def tworzenie_widzetow_glownych(self):

        self.lbl_pusty_gora = ttk.Label(self, text=' ')
        self.material_str = tk.StringVar()
        self.keys_materialow = list(c.materialy.keys())
        self.omenu_material = ttk.OptionMenu(self, self.material_str, self.keys_materialow[0], *self.keys_materialow,
                                             command=self.omenu_materialy_f)

        self.lbl_g_jed = ttk.Label(self, text='Gęstość jedn.\n [kg/m3]')
        self.g_jed_str = tk.StringVar()
        self.entry_g_jed = EntryValid(self, textvariable=self.g_jed_str,
                                      slownik_wyczysc={'clr_waga_1m': self.clr_waga_1mb,
                                                       'clr_waga_podanego': self.clr_waga_podanego,
                                                       'clr_cena_1kg': self.clr_cena_1kg,
                                                       'clr_cena_1mb': self.clr_cena_1mb,
                                                       'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_wysokosc = ttk.Label(self, text='Wysokosc\n [mm]')
        self.wysokosc_str = tk.StringVar()
        self.entry_wysokosc = EntryValid(self, textvariable=self.wysokosc_str,
                                         slownik_wyczysc={'clr_waga_1m': self.clr_waga_1mb,
                                                          'clr_waga_podanego': self.clr_waga_podanego,
                                                          'clr_cena_1kg': self.clr_cena_1kg,
                                                          'clr_cena_1mb': self.clr_cena_1mb,
                                                          'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_szerokosc = ttk.Label(self, text='Szerokosc\n [mm]')
        self.szerokosc_str = tk.StringVar()
        self.entry_szerokosc = EntryValid(self, textvariable=self.szerokosc_str,
                                          slownik_wyczysc={'clr_waga_1m': self.clr_waga_1mb,
                                                           'clr_waga_podanego': self.clr_waga_podanego,
                                                           'clr_cena_1kg': self.clr_cena_1kg,
                                                           'clr_cena_1mb': self.clr_cena_1mb,
                                                           'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_grub_scianki = ttk.Label(self, text='Grub. ścianki\n [mm]')
        self.grub_scianki_str = tk.StringVar()
        self.entry_grub_scianki = EntryValid(self, textvariable=self.grub_scianki_str,
                                             slownik_wyczysc={'clr_waga_1m': self.clr_waga_1mb,
                                                              'clr_waga_podanego': self.clr_waga_podanego,
                                                              'clr_cena_1kg': self.clr_cena_1kg,
                                                              'clr_cena_1mb': self.clr_cena_1mb,
                                                              'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_dlugosc = ttk.Label(self, text='Długość\n[mm]')
        self.dlugosc_str = tk.StringVar()
        self.entry_dlugosc = EntryValid(self, textvariable=self.dlugosc_str,
                                        slownik_wyczysc={'clr_waga_podanego': self.clr_waga_podanego,
                                                         'clr_cena_1kg': self.clr_cena_1kg,
                                                         'clr_cena_1mb': self.clr_cena_1mb,
                                                         'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_pusty_pod_glownymi = ttk.Label(self, text=' ')

    def tworzenie_widzetow_waga_cena(self):


        self.lbl_waga_1mb = ttk.Label(self, text='Waga 1mb\n[kg]')
        self.waga_1mb_str = tk.StringVar()
        self.entry_waga_1mb = EntryValid(self, textvariable=self.waga_1mb_str,
                                         slownik_wyczysc={'clr_g_jedn': self.clr_g_jedn,
                                                          'clr_waga_podanego': self.clr_waga_podanego,
                                                          'clr_cena_1kg': self.clr_cena_1kg,
                                                          'clr_cena_1mb': self.clr_cena_1mb,
                                                          'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_waga_podanego = ttk.Label(self, text='Waga dla p. długości\n[kg]')
        self.waga_podanego_str = tk.StringVar()
        self.entry_waga_podanego = EntryValid(self, textvariable=self.waga_podanego_str,
                                              slownik_wyczysc={'clr_g_jedn': self.clr_g_jedn,
                                                               'clr_waga_1mb': self.clr_waga_1mb,
                                                               'clr_cena_1kg': self.clr_cena_1kg,
                                                               'clr_cena_1mb': self.clr_cena_1mb,
                                                               'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_cena_1mb = ttk.Label(self, text='Cena 1m\n[zł]')
        self.cena_1mb_str = tk.StringVar()
        self.entry_cena_1mb = EntryValid(self, textvariable=self.cena_1mb_str,
                                         slownik_wyczysc={'clr_cena_1kg': self.clr_cena_1kg,
                                                          'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_cena_1kg = ttk.Label(self, text='Cena 1kg\n[zł]')
        self.cena_1kg_str = tk.StringVar()
        self.entry_cena_1kg = EntryValid(self, textvariable=self.cena_1kg_str,
                                         slownik_wyczysc={'clr_cena_1mb': self.clr_cena_1mb,
                                                          'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_cena_dla_podanego = ttk.Label(self, text=f'Cena dla p. długości\n[zł]')
        self.cena_dla_podanego_str = tk.StringVar()
        self.entry_cena_dla_podanego = EntryValid(self, textvariable=self.cena_dla_podanego_str,
                                                  slownik_wyczysc={'clr_cena_1kg': self.clr_cena_1kg,
                                                                   'clr_cena_1mb': self.clr_cena_1mb})
        self.lbl_pusty_pod_waga_cena = ttk.Label(self, text=' ')

    def umieszczanie_widzetow_glownych(self, wiersz, px, py):


        self.lbl_pusty_gora.grid(column=1, row=0)

        self.omenu_material.grid(column=0, row=wiersz, padx=px, pady=py)
        self.lbl_g_jed.grid(column=1, row=wiersz, padx=px, pady=py)
        self.lbl_wysokosc.grid(column=2, row=wiersz, padx=px, pady=py)
        self.lbl_szerokosc.grid(column=3, row=wiersz, padx=px, pady=py)
        self.lbl_grub_scianki.grid(column=4, row=wiersz, padx=px, pady=py)
        self.lbl_dlugosc.grid(column=5, row=wiersz, padx=px, pady=py)

        self.entry_g_jed.grid(column=1, row=wiersz + 1, padx=px, pady=py)
        self.entry_wysokosc.grid(column=2, row=wiersz + 1, padx=px, pady=py)
        self.entry_szerokosc.grid(column=3, row=wiersz + 1, padx=px, pady=py)
        self.entry_grub_scianki.grid(column=4, row=wiersz + 1, padx=px, pady=py)
        self.entry_dlugosc.grid(column=5, row=wiersz + 1, padx=px, pady=py)

        self.lbl_pusty_pod_glownymi.grid(column=1, row=3)

    def umieszczanie_widzetow_waga_cena(self, wiersz, px, py):

        self.lbl_waga_1mb.grid(column=0, row=wiersz, padx=px, pady=py)
        self.lbl_waga_podanego.grid(column=1, row=wiersz, padx=px, pady=py)
        self.lbl_cena_1mb.grid(column=2, row=wiersz, padx=px, pady=py)
        self.lbl_cena_1kg.grid(column=3, row=wiersz, padx=px, pady=py)
        self.lbl_cena_dla_podanego.grid(column=4, row=wiersz, padx=px, pady=py)

        self.entry_waga_1mb.grid(column=0, row=wiersz + 1, padx=px, pady=py)
        self.entry_waga_podanego.grid(column=1, row=wiersz + 1, padx=px, pady=py)
        self.entry_cena_1mb.grid(column=2, row=wiersz + 1, padx=px, pady=py)
        self.entry_cena_1kg.grid(column=3, row=wiersz + 1, padx=px, pady=py)
        self.entry_cena_dla_podanego.grid(column=4, row=wiersz + 1, padx=px, pady=py)
        self.lbl_pusty_pod_waga_cena.grid(column=1, row=wiersz + 2, padx=px, pady=py)

        self.canvas_obraz_ceownik = tk.Canvas(self, width=700, height=150)
        self.canvas_obraz_ceownik.place(relx = 0.5,rely = 0.8, anchor='center')
        self.image_ceownik = tk.PhotoImage(data=kod_obr.zakodowany_ceownik_img)
        self.canvas_obraz_ceownik.create_image(0, 0, anchor="nw", image=self.image_ceownik)

    def omenu_materialy_f(self, mater):
        if mater in c.materialy:
            self.waga_1mb_str.set('')
            self.waga_podanego_str.set('')
            self.cena_1mb_str.set('')
            self.cena_1kg_str.set('')
            self.cena_dla_podanego_str.set('')
            g_jedno = c.materialy[mater]['g_jednostkowa']
            self.g_jed_str.set(g_jedno)

    def clr_g_jedn(self):
        self.g_jed_str.set('')
        self.entry_g_jed.delete(0, 'end')

    def clr_wysokosc(self):
        self.wysokosc_str.set('')
        self.entry_wysokosc.delete(0, 'end')

    def clr_szerokosc(self):
        self.szerokosc_str.set('')
        self.entry_szerokosc.delete(0, 'end')

    def clr_waga_1mb(self):
        self.waga_1mb_str.set('')
        self.entry_waga_1mb.delete(0, 'end')

    def clr_waga_podanego(self):
        self.waga_podanego_str.set('')
        self.entry_waga_podanego.delete(0, 'end')

    def clr_cena_1mb(self):
        self.cena_1mb_str.set('')
        self.entry_cena_1mb.delete(0, 'end')

    def clr_cena_1kg(self):
        self.cena_1kg_str.set('')
        self.entry_cena_1kg.delete(0, 'end')

    def clr_cena_dla_podanego(self):
        self.cena_dla_podanego_str.set('')
        self.entry_cena_dla_podanego.delete(0, 'end')


class Tab_powierzchniowe(ttk.Frame):
    def __init__(self, master=None):
        super().__init__(master)

        self.zakladki_powierzchniowe = ttk.Notebook(self)

        self.tab_pow_arkusz = Tab_powierzchniowe_arkusz()
        self.zakladki_powierzchniowe.add(self.tab_pow_arkusz, text="Arkusz")

        self.tab_pow_arkusz_perf = Tab_powierzchniowe_arkusz_perforowany()
        self.zakladki_powierzchniowe.add(self.tab_pow_arkusz_perf, text="Arkusz perforowany")

        self.zakladki_powierzchniowe.place(relx=0, rely=0, relwidth=1, relheight=1)


class Tab_powierzchniowe_arkusz(ttk.Frame):
    def __init__(self, master=None):
        super().__init__(master)

        self.tworzenie_widzetow_glownych()
        self.tworzenie_widzetow_waga_cena()
        self.btn_przelicz = ttk.Button(self, text='Przelicz', command=self.oblicz_dla_arkusz)

        self.umieszczanie_widzetow_glownych(wiersz=1, px=5, py=1)
        self.umieszczanie_widzetow_waga_cena(wiersz=4, px=5, py=1)
        self.btn_przelicz.grid(column=5, row=7)
        for entry_widget in self.winfo_children():
            if isinstance(entry_widget, tk.Entry):
                entry_widget.bind("<Return>", lambda event: self.oblicz_dla_arkusz())
    def oblicz_dla_arkusz(self):

        if self.g_jed_str.get() and self.g_jed_str.get() != '0':
            g_jednos = float(self.g_jed_str.get().replace(',', '.'))
        else:
            g_jednos = False

        if self.szerokosc_str.get() and self.szerokosc_str.get() != '0':
            szer = float(self.szerokosc_str.get().replace(',', '.')) / 1000
        else:
            szer = False

        if self.dlugosc_str.get() and self.dlugosc_str.get() != '0':
            dlugo = float(self.dlugosc_str.get().replace(',', '.')) / 1000
        else:
            dlugo = False

        if self.grubosc_str.get() and self.grubosc_str.get() != '0':
            grubo = float(self.grubosc_str.get().replace(',', '.')) / 1000
        else:
            grubo = False

        if self.waga_1m2_str.get() and self.waga_1m2_str.get() != '0':
            waga_1m2 = float(self.waga_1m2_str.get().replace(',', '.'))
        else:
            waga_1m2 = False

        if self.waga_podanego_str.get() and self.waga_podanego_str.get() != '0':
            waga_dla_podan = float(self.waga_podanego_str.get().replace(',', '.'))
        else:
            waga_dla_podan = False

        if self.cena_1m2_str.get() and self.cena_1m2_str.get() != '0':
            cena_1m2 = float(self.cena_1m2_str.get().replace(',', '.'))
        else:
            cena_1m2 = False

        if self.cena_1kg_str.get() and self.cena_1kg_str.get() != '0':
            cena_1kg = float(self.cena_1kg_str.get().replace(',', '.'))
        else:
            cena_1kg = False

        if self.cena_dla_podanego_str.get() and self.cena_dla_podanego_str.get() != '0':
            cena_dla_podan = float(self.cena_dla_podanego_str.get().replace(',', '.'))
        else:
            cena_dla_podan = False

        # --------------OBLICZENIA-----------------------

        if dlugo and szer:
            self.powierzchnia_str.set(str(round(dlugo * szer, 2)))

        if not waga_1m2 and not waga_dla_podan and g_jednos and grubo:
            self.waga_1m2_str.set(str(round(grubo * g_jednos, 2)))
            waga_1m2 = float(self.waga_1m2_str.get().replace(',', '.'))
            if dlugo and szer:
                self.waga_podanego_str.set(str(round(szer * dlugo * grubo * g_jednos, 2)))
                waga_dla_podan = float(self.waga_podanego_str.get().replace(',', '.'))

        if waga_1m2 and not waga_dla_podan and dlugo and szer:
            self.waga_podanego_str.set(str(round(waga_1m2 * dlugo * szer, 2)))
            waga_dla_podan = float(self.waga_podanego_str.get().replace(',', '.'))

        if waga_dla_podan and not waga_1m2 and dlugo and szer:
            self.waga_1m2_str.set(str(round(waga_dla_podan / (dlugo * szer), 2)))
            waga_1m2 = float(self.waga_1m2_str.get().replace(',', '.'))

        if not g_jednos and waga_1m2 and grubo:
            self.g_jed_str.set(str(round(waga_1m2 / grubo, 2)))
            g_jednos = float(self.g_jed_str.get().replace(',', '.'))

        if cena_1m2 and not cena_1kg and not cena_dla_podan and waga_1m2:

            self.cena_1kg_str.set(str(round(cena_1m2 / waga_1m2, 2)))
            cena_1kg = float(self.cena_1kg_str.get().replace(',', '.'))

            if dlugo and szer:
                self.cena_dla_podanego_str.set(str(round(cena_1m2 * dlugo * szer, 2)))
                cena_dla_podan = float(self.cena_dla_podanego_str.get().replace(',', '.'))

        if cena_1kg and not cena_1m2 and not cena_dla_podan and waga_1m2:
            self.cena_1m2_str.set(str(round(cena_1kg * waga_1m2, 2)))
            cena_1m2 = float(self.cena_1m2_str.get().replace(',', '.'))

            if dlugo and szer:
                self.cena_dla_podanego_str.set(str(round(dlugo * szer * cena_1m2, 2)))
                cena_dla_podan = float(self.cena_dla_podanego_str.get().replace(',', '.'))

        if cena_dla_podan and not cena_1kg and not cena_1m2 and dlugo and szer:

            self.cena_1m2_str.set(str(round(cena_dla_podan / (dlugo * szer), 2)))
            cena_1m2 = float(self.cena_1m2_str.get().replace(',', '.'))

            if waga_1m2:
                self.cena_1kg_str.set(str(round(cena_1m2 / waga_1m2, 2)))
                cena_1kg = float(self.cena_1kg_str.get().replace(',', '.'))

    def tworzenie_widzetow_glownych(self):

        self.lbl_pusty_gora = ttk.Label(self, text=' ')
        self.material_str = tk.StringVar()
        self.keys_materialow = list(c.materialy.keys())
        self.omenu_material = ttk.OptionMenu(self, self.material_str, self.keys_materialow[0], *self.keys_materialow,
                                             command=self.omenu_materialy_f)

        self.lbl_g_jed = ttk.Label(self, text='Gęstość jedn.\n [kg/m3]')
        self.g_jed_str = tk.StringVar()
        self.entry_g_jed = EntryValid(self, textvariable=self.g_jed_str,
                                      slownik_wyczysc={'clr_waga_1m2': self.clr_waga_1m2,
                                                       'clr_waga_podanego': self.clr_waga_podanego,
                                                       'clr_cena_1kg': self.clr_cena_1kg,
                                                       'clr_cena_1m2': self.clr_cena_1m2,
                                                       'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_szerokosc = ttk.Label(self, text='Szerokość\n [mm]')
        self.szerokosc_str = tk.StringVar()
        self.entry_szerokosc = EntryValid(self, textvariable=self.szerokosc_str,
                                          slownik_wyczysc={'clr_waga_1m2': self.clr_waga_1m2,
                                                           'clr_waga_podanego': self.clr_waga_podanego,
                                                           'clr_cena_1kg': self.clr_cena_1kg,
                                                           'clr_cena_1m2': self.clr_cena_1m2,
                                                           'clr_powierzchnia': self.clr_powierzchnia,
                                                           'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_dlugosc = ttk.Label(self, text='Długość\n [mm]')
        self.dlugosc_str = tk.StringVar()
        self.entry_dlugosc = EntryValid(self, textvariable=self.dlugosc_str,
                                        slownik_wyczysc={'clr_waga_1m2': self.clr_waga_1m2,
                                                         'clr_waga_podanego': self.clr_waga_podanego,
                                                         'clr_cena_1kg': self.clr_cena_1kg,
                                                         'clr_cena_1m2': self.clr_cena_1m2,
                                                         'clr_powierzchnia': self.clr_powierzchnia,
                                                         'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_grubosc = ttk.Label(self, text='Grubość\n [mm]')
        self.grubosc_str = tk.StringVar()
        self.entry_grubosc = EntryValid(self, textvariable=self.grubosc_str,
                                        slownik_wyczysc={'clr_waga_1m2': self.clr_waga_1m2,
                                                         'clr_waga_podanego': self.clr_waga_podanego,
                                                         'clr_cena_1kg': self.clr_cena_1kg,
                                                         'clr_cena_1m2': self.clr_cena_1m2,
                                                         'clr_cena_dla_podanego': self.clr_cena_dla_podanego})



        self.lbl_pusty_pod_glownymi = ttk.Label(self, text=' ')

    def tworzenie_widzetow_waga_cena(self):

        self.lbl_waga_1m2 = ttk.Label(self, text='Waga 1m2\n[kg]')
        self.waga_1m2_str = tk.StringVar()
        self.entry_waga_1m2 = EntryValid(self, textvariable=self.waga_1m2_str,
                                         slownik_wyczysc={'clr_g_jedn': self.clr_g_jedn,
                                                          'clr_waga_podanego': self.clr_waga_podanego,
                                                          'clr_cena_1kg': self.clr_cena_1kg,
                                                          'clr_cena_1m2': self.clr_cena_1m2,
                                                          'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_waga_podanego = ttk.Label(self, text='Waga dla p. ark\n[kg]')
        self.waga_podanego_str = tk.StringVar()
        self.entry_waga_podanego = EntryValid(self, textvariable=self.waga_podanego_str,
                                              slownik_wyczysc={'clr_g_jedn': self.clr_g_jedn,
                                                               'clr_waga_1m2': self.clr_waga_1m2,
                                                               'clr_cena_1kg': self.clr_cena_1kg,
                                                               'clr_cena_1m2': self.clr_cena_1m2,
                                                               'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_cena_1m2 = ttk.Label(self, text='Cena 1m2\n[zł]')
        self.cena_1m2_str = tk.StringVar()
        self.entry_cena_1m2 = EntryValid(self, textvariable=self.cena_1m2_str,
                                         slownik_wyczysc={'clr_cena_1kg': self.clr_cena_1kg,
                                                          'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_cena_1kg = ttk.Label(self, text='Cena 1kg\n[zł]')
        self.cena_1kg_str = tk.StringVar()
        self.entry_cena_1kg = EntryValid(self, textvariable=self.cena_1kg_str,
                                         slownik_wyczysc={'clr_cena_1m2': self.clr_cena_1m2,
                                                          'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_cena_dla_podanego = ttk.Label(self, text=f'Cena dla p. ark\n[zł]')
        self.cena_dla_podanego_str = tk.StringVar()
        self.entry_cena_dla_podanego = EntryValid(self, textvariable=self.cena_dla_podanego_str,
                                                  slownik_wyczysc={'clr_cena_1kg': self.clr_cena_1kg,
                                                                   'clr_cena_1m2': self.clr_cena_1m2})

        self.lbl_powierzchnia = ttk.Label(self, text=f'Powierzchnia ark.\n[m2]')
        self.powierzchnia_str = tk.StringVar()
        self.entry_powierzchnia = EntryValid(self, textvariable=self.powierzchnia_str,
                                             slownik_wyczysc={'clr_dlugosc': self.clr_dlugosc,
                                                              'clr_szerokosc': self.clr_szerokosc,
                                                              'clr_grubosc': self.clr_grubosc})

        self.lbl_pusty_pod_waga_cena = ttk.Label(self, text=' ')

    def umieszczanie_widzetow_glownych(self, wiersz, px, py):

        self.lbl_pusty_gora.grid(column=1, row=0)

        self.omenu_material.grid(column=0, row=wiersz, padx=px, pady=py)
        self.lbl_g_jed.grid(column=1, row=wiersz, padx=px, pady=py)
        self.lbl_szerokosc.grid(column=2, row=wiersz, padx=px, pady=py)
        self.lbl_dlugosc.grid(column=3, row=wiersz, padx=px, pady=py)
        self.lbl_grubosc.grid(column=4, row=wiersz, padx=px, pady=py)


        self.entry_g_jed.grid(column=1, row=wiersz + 1, padx=px, pady=py)
        self.entry_szerokosc.grid(column=2, row=wiersz + 1, padx=px, pady=py)
        self.entry_dlugosc.grid(column=3, row=wiersz + 1, padx=px, pady=py)
        self.entry_grubosc.grid(column=4, row=wiersz + 1, padx=px, pady=py)

        self.lbl_pusty_pod_glownymi.grid(column=1, row=3)

    def umieszczanie_widzetow_waga_cena(self, wiersz, px, py):

        self.lbl_waga_1m2.grid(column=0, row=wiersz, padx=px, pady=py)
        self.lbl_waga_podanego.grid(column=1, row=wiersz, padx=px, pady=py)
        self.lbl_cena_1m2.grid(column=2, row=wiersz, padx=px, pady=py)
        self.lbl_cena_1kg.grid(column=3, row=wiersz, padx=px, pady=py)
        self.lbl_cena_dla_podanego.grid(column=4, row=wiersz, padx=px, pady=py)
        self.lbl_powierzchnia.grid(column=5, row=wiersz, padx=px, pady=py)

        self.entry_waga_1m2.grid(column=0, row=wiersz + 1, padx=px, pady=py)
        self.entry_waga_podanego.grid(column=1, row=wiersz + 1, padx=px, pady=py)
        self.entry_cena_1m2.grid(column=2, row=wiersz + 1, padx=px, pady=py)
        self.entry_cena_1kg.grid(column=3, row=wiersz + 1, padx=px, pady=py)
        self.entry_cena_dla_podanego.grid(column=4, row=wiersz + 1, padx=px, pady=py)

        self.entry_powierzchnia.grid(column=5, row=wiersz + 1, padx=px, pady=py)
        self.entry_powierzchnia.configure(state='disabled')

        self.lbl_pusty_pod_waga_cena.grid(column=1, row=wiersz + 2, padx=px, pady=py)

        self.canvas_obraz_blachy = tk.Canvas(self, width=700, height=150)
        self.canvas_obraz_blachy.place(relx = 0.5,rely = 0.8, anchor='center')
        self.image_blachy = tk.PhotoImage(data=kod_obr.zakodowany_arkusz_img)
        self.canvas_obraz_blachy.create_image(0, 0, anchor="nw", image=self.image_blachy)


    def omenu_materialy_f(self, mater):
        if mater in c.materialy:
            self.waga_1m2_str.set('')
            self.waga_podanego_str.set('')
            self.cena_1m2_str.set('')
            self.cena_1kg_str.set('')
            self.cena_dla_podanego_str.set('')
            g_jedno = c.materialy[mater]['g_jednostkowa']
            self.g_jed_str.set(g_jedno)

    def clr_g_jedn(self):
        self.g_jed_str.set('')
        self.entry_g_jed.delete(0, 'end')

    def clr_szerokosc(self):
        self.szerokosc_str.set('')
        self.entry_szerokosc.delete(0, 'end')

    def clr_powierzchnia(self):
        self.powierzchnia_str.set('')
        self.entry_powierzchnia.delete(0, 'end')

    def clr_grubosc(self):
        self.grubosc_str.set('')
        self.entry_grubosc.delete(0, 'end')

    def clr_dlugosc(self):
        self.dlugosc_str.set('')
        self.entry_dlugosc.delete(0, 'end')

    def clr_waga_1m2(self):
        self.waga_1m2_str.set('')
        self.entry_waga_1m2.delete(0, 'end')

    def clr_waga_podanego(self):
        self.waga_podanego_str.set('')
        self.entry_waga_podanego.delete(0, 'end')

    def clr_cena_1m2(self):
        self.cena_1m2_str.set('')
        self.entry_cena_1m2.delete(0, 'end')

    def clr_cena_1kg(self):
        self.cena_1kg_str.set('')
        self.entry_cena_1kg.delete(0, 'end')

    def clr_cena_dla_podanego(self):
        self.cena_dla_podanego_str.set('')
        self.entry_cena_dla_podanego.delete(0, 'end')

class Tab_powierzchniowe_arkusz_perforowany(ttk.Frame):
    def __init__(self, master=None):
        super().__init__(master)
        self.tworzenie_widzetow_glownych()
        self.tworzenie_widzetow_waga_cena()
        self.btn_przelicz = ttk.Button(self, text='Przelicz', command=self.oblicz_dla_arkusz_perforowany)

        self.umieszczanie_widzetow_glownych(wiersz=1, px=5, py=1)
        self.umieszczanie_widzetow_waga_cena(wiersz=4, px=5, py=1)
        self.btn_przelicz.grid(column=5, row=7)
        for entry_widget in self.winfo_children():
            if isinstance(entry_widget, tk.Entry):
                entry_widget.bind("<Return>", lambda event: self.oblicz_dla_arkusz_perforowany())


    def oblicz_dla_arkusz_perforowany(self):

        if self.g_jed_str.get() and self.g_jed_str.get() != '0':
            g_jednos = float(self.g_jed_str.get().replace(',', '.'))
        else:
            g_jednos = False

        if self.szerokosc_str.get() and self.szerokosc_str.get() != '0':
            szer = float(self.szerokosc_str.get().replace(',', '.')) / 1000
        else:
            szer = False

        if self.dlugosc_str.get() and self.dlugosc_str.get() != '0':
            dlugo = float(self.dlugosc_str.get().replace(',', '.')) / 1000
        else:
            dlugo = False

        if self.grubosc_str.get() and self.grubosc_str.get() != '0':
            grubo = float(self.grubosc_str.get().replace(',', '.')) / 1000
        else:
            grubo = False

        if self.waga_1m2_str.get() and self.waga_1m2_str.get() != '0':
            waga_1m2 = float(self.waga_1m2_str.get().replace(',', '.'))
        else:
            waga_1m2 = False

        if self.waga_podanego_str.get() and self.waga_podanego_str.get() != '0':
            waga_dla_podan = float(self.waga_podanego_str.get().replace(',', '.'))
        else:
            waga_dla_podan = False

        if self.cena_1m2_str.get() and self.cena_1m2_str.get() != '0':
            cena_1m2 = float(self.cena_1m2_str.get().replace(',', '.'))
        else:
            cena_1m2 = False

        if self.cena_1kg_str.get() and self.cena_1kg_str.get() != '0':
            cena_1kg = float(self.cena_1kg_str.get().replace(',', '.'))
        else:
            cena_1kg = False

        if self.cena_dla_podanego_str.get() and self.cena_dla_podanego_str.get() != '0':
            cena_dla_podan = float(self.cena_dla_podanego_str.get().replace(',', '.'))
        else:
            cena_dla_podan = False

        if self.przeswit_str.get() and float(self.przeswit_str.get()) < 100 and self.przeswit_str.get() != '0':
            przesw = float(self.przeswit_str.get().replace(',', '.'))/100
        else:
            przesw = False

        # --------------OBLICZENIA-----------------------

        if dlugo and szer:
            self.powierzchnia_str.set(str(round(dlugo * szer, 2)))

        if not waga_1m2 and not waga_dla_podan and g_jednos and grubo and przesw:
            self.waga_1m2_str.set(str(round(grubo * g_jednos * (1-przesw), 2)))
            waga_1m2 = float(self.waga_1m2_str.get().replace(',', '.'))
            if dlugo and szer:
                self.waga_podanego_str.set(str(round(szer * dlugo * grubo * g_jednos * (1-przesw), 2)))
                waga_dla_podan = float(self.waga_podanego_str.get().replace(',', '.'))

        if waga_1m2 and not waga_dla_podan and dlugo and szer:
            self.waga_podanego_str.set(str(round(waga_1m2 * dlugo * szer, 2)))
            waga_dla_podan = float(self.waga_podanego_str.get().replace(',', '.'))

        if waga_dla_podan and not waga_1m2 and dlugo and szer:
            self.waga_1m2_str.set(str(round(waga_dla_podan / (dlugo * szer), 2)))
            waga_1m2 = float(self.waga_1m2_str.get().replace(',', '.'))

        if not g_jednos and waga_1m2 and grubo:
            self.g_jed_str.set(str(round((waga_1m2 /(1- przesw))/ grubo, 2)))
            g_jednos = float(self.g_jed_str.get().replace(',', '.'))

        if cena_1m2 and not cena_1kg and not cena_dla_podan and waga_1m2:

            self.cena_1kg_str.set(str(round(cena_1m2 / waga_1m2, 2)))
            cena_1kg = float(self.cena_1kg_str.get().replace(',', '.'))

            if dlugo and szer:
                self.cena_dla_podanego_str.set(str(round(cena_1m2 * dlugo * szer, 2)))
                cena_dla_podan = float(self.cena_dla_podanego_str.get().replace(',', '.'))

        if cena_1kg and not cena_1m2 and not cena_dla_podan and waga_1m2:
            self.cena_1m2_str.set(str(round(cena_1kg * waga_1m2, 2)))
            cena_1m2 = float(self.cena_1m2_str.get().replace(',', '.'))

            if dlugo and szer:
                self.cena_dla_podanego_str.set(str(round(dlugo * szer * cena_1m2, 2)))
                cena_dla_podan = float(self.cena_dla_podanego_str.get().replace(',', '.'))

        if cena_dla_podan and not cena_1kg and not cena_1m2 and dlugo and szer:

            self.cena_1m2_str.set(str(round(cena_dla_podan / (dlugo * szer), 2)))
            cena_1m2 = float(self.cena_1m2_str.get().replace(',', '.'))

            if waga_1m2:
                self.cena_1kg_str.set(str(round(cena_1m2 / waga_1m2, 2)))
                cena_1kg = float(self.cena_1kg_str.get().replace(',', '.'))



    def tworzenie_widzetow_glownych(self):

        self.lbl_pusty_gora = ttk.Label(self, text=' ')
        self.material_str = tk.StringVar()
        self.keys_materialow = list(c.materialy.keys())
        self.omenu_material = ttk.OptionMenu(self, self.material_str, self.keys_materialow[0], *self.keys_materialow,
                                             command=self.omenu_materialy_f)

        self.lbl_g_jed = ttk.Label(self, text='Gęstość jedn.\n [kg/m3]')
        self.g_jed_str = tk.StringVar()
        self.entry_g_jed = EntryValid(self, textvariable=self.g_jed_str,
                                      slownik_wyczysc={'clr_waga_1m2': self.clr_waga_1m2,
                                                       'clr_waga_podanego': self.clr_waga_podanego,
                                                       'clr_cena_1kg': self.clr_cena_1kg,
                                                       'clr_cena_1m2': self.clr_cena_1m2,
                                                       'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_szerokosc = ttk.Label(self, text='Szerokość\n [mm]')
        self.szerokosc_str = tk.StringVar()
        self.entry_szerokosc = EntryValid(self, textvariable=self.szerokosc_str,
                                          slownik_wyczysc={'clr_waga_1m2': self.clr_waga_1m2,
                                                           'clr_waga_podanego': self.clr_waga_podanego,
                                                           'clr_cena_1kg': self.clr_cena_1kg,
                                                           'clr_cena_1m2': self.clr_cena_1m2,
                                                           'clr_powierzchnia': self.clr_powierzchnia,
                                                           'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_dlugosc = ttk.Label(self, text='Długość\n [mm]')
        self.dlugosc_str = tk.StringVar()
        self.entry_dlugosc = EntryValid(self, textvariable=self.dlugosc_str,
                                        slownik_wyczysc={'clr_waga_1m2': self.clr_waga_1m2,
                                                         'clr_waga_podanego': self.clr_waga_podanego,
                                                         'clr_cena_1kg': self.clr_cena_1kg,
                                                         'clr_cena_1m2': self.clr_cena_1m2,
                                                         'clr_powierzchnia': self.clr_powierzchnia,
                                                         'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_grubosc = ttk.Label(self, text='Grubość\n [mm]')
        self.grubosc_str = tk.StringVar()
        self.entry_grubosc = EntryValid(self, textvariable=self.grubosc_str,
                                        slownik_wyczysc={'clr_waga_1m2': self.clr_waga_1m2,
                                                         'clr_waga_podanego': self.clr_waga_podanego,
                                                         'clr_cena_1kg': self.clr_cena_1kg,
                                                         'clr_cena_1m2': self.clr_cena_1m2,
                                                         'clr_cena_dla_podanego': self.clr_cena_dla_podanego})


        self.lbl_przeswit = ttk.Label(self, text='Prześwit\n [%]')
        self.przeswit_str = tk.StringVar(value='35')
        self.entry_przeswit = EntryValid(self, textvariable=self.przeswit_str,
                                        slownik_wyczysc={'clr_waga_1m2': self.clr_waga_1m2,
                                                         'clr_waga_podanego': self.clr_waga_podanego,
                                                         'clr_cena_1kg': self.clr_cena_1kg,
                                                         'clr_cena_1m2': self.clr_cena_1m2,
                                                         'clr_cena_dla_podanego': self.clr_cena_dla_podanego})



        self.lbl_pusty_pod_glownymi = ttk.Label(self, text=' ')

    def tworzenie_widzetow_waga_cena(self):

        self.lbl_waga_1m2 = ttk.Label(self, text='Waga 1m2\n[kg]')
        self.waga_1m2_str = tk.StringVar()
        self.entry_waga_1m2 = EntryValid(self, textvariable=self.waga_1m2_str,
                                         slownik_wyczysc={'clr_g_jedn': self.clr_g_jedn,
                                                          'clr_waga_podanego': self.clr_waga_podanego,
                                                          'clr_cena_1kg': self.clr_cena_1kg,
                                                          'clr_cena_1m2': self.clr_cena_1m2,
                                                          'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_waga_podanego = ttk.Label(self, text='Waga dla p. ark\n[kg]')
        self.waga_podanego_str = tk.StringVar()
        self.entry_waga_podanego = EntryValid(self, textvariable=self.waga_podanego_str,
                                              slownik_wyczysc={'clr_g_jedn': self.clr_g_jedn,
                                                               'clr_waga_1m2': self.clr_waga_1m2,
                                                               'clr_cena_1kg': self.clr_cena_1kg,
                                                               'clr_cena_1m2': self.clr_cena_1m2,
                                                               'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_cena_1m2 = ttk.Label(self, text='Cena 1m2\n[zł]')
        self.cena_1m2_str = tk.StringVar()
        self.entry_cena_1m2 = EntryValid(self, textvariable=self.cena_1m2_str,
                                         slownik_wyczysc={'clr_cena_1kg': self.clr_cena_1kg,
                                                          'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_cena_1kg = ttk.Label(self, text='Cena 1kg\n[zł]')
        self.cena_1kg_str = tk.StringVar()
        self.entry_cena_1kg = EntryValid(self, textvariable=self.cena_1kg_str,
                                         slownik_wyczysc={'clr_cena_1m2': self.clr_cena_1m2,
                                                          'clr_cena_dla_podanego': self.clr_cena_dla_podanego})

        self.lbl_cena_dla_podanego = ttk.Label(self, text=f'Cena dla p. ark\n[zł]')
        self.cena_dla_podanego_str = tk.StringVar()
        self.entry_cena_dla_podanego = EntryValid(self, textvariable=self.cena_dla_podanego_str,
                                                  slownik_wyczysc={'clr_cena_1kg': self.clr_cena_1kg,
                                                                   'clr_cena_1m2': self.clr_cena_1m2})

        self.lbl_powierzchnia = ttk.Label(self, text=f'Powierzchnia ark.\n[m2]')
        self.powierzchnia_str = tk.StringVar()
        self.entry_powierzchnia = EntryValid(self, textvariable=self.powierzchnia_str,
                                             slownik_wyczysc={'clr_dlugosc': self.clr_dlugosc,
                                                              'clr_szerokosc': self.clr_szerokosc,
                                                              'clr_grubosc': self.clr_grubosc})

        self.lbl_pusty_pod_waga_cena = ttk.Label(self, text=' ')

    def umieszczanie_widzetow_glownych(self, wiersz, px, py):

        self.lbl_pusty_gora.grid(column=1, row=0)

        self.omenu_material.grid(column=0, row=wiersz, padx=px, pady=py)
        self.lbl_g_jed.grid(column=1, row=wiersz, padx=px, pady=py)
        self.lbl_szerokosc.grid(column=2, row=wiersz, padx=px, pady=py)
        self.lbl_dlugosc.grid(column=3, row=wiersz, padx=px, pady=py)
        self.lbl_grubosc.grid(column=4, row=wiersz, padx=px, pady=py)
        self.lbl_przeswit.grid(column=5, row=wiersz, padx=px, pady=py)


        self.entry_g_jed.grid(column=1, row=wiersz + 1, padx=px, pady=py)
        self.entry_szerokosc.grid(column=2, row=wiersz + 1, padx=px, pady=py)
        self.entry_dlugosc.grid(column=3, row=wiersz + 1, padx=px, pady=py)
        self.entry_grubosc.grid(column=4, row=wiersz + 1, padx=px, pady=py)
        self.entry_przeswit.grid(column=5, row=wiersz + 1, padx=px, pady=py)

        self.lbl_pusty_pod_glownymi.grid(column=1, row=3)

    def umieszczanie_widzetow_waga_cena(self, wiersz, px, py):

        self.lbl_waga_1m2.grid(column=0, row=wiersz, padx=px, pady=py)
        self.lbl_waga_podanego.grid(column=1, row=wiersz, padx=px, pady=py)
        self.lbl_cena_1m2.grid(column=2, row=wiersz, padx=px, pady=py)
        self.lbl_cena_1kg.grid(column=3, row=wiersz, padx=px, pady=py)
        self.lbl_cena_dla_podanego.grid(column=4, row=wiersz, padx=px, pady=py)
        self.lbl_powierzchnia.grid(column=5, row=wiersz, padx=px, pady=py)

        self.entry_waga_1m2.grid(column=0, row=wiersz + 1, padx=px, pady=py)
        self.entry_waga_podanego.grid(column=1, row=wiersz + 1, padx=px, pady=py)
        self.entry_cena_1m2.grid(column=2, row=wiersz + 1, padx=px, pady=py)
        self.entry_cena_1kg.grid(column=3, row=wiersz + 1, padx=px, pady=py)
        self.entry_cena_dla_podanego.grid(column=4, row=wiersz + 1, padx=px, pady=py)

        self.entry_powierzchnia.grid(column=5, row=wiersz + 1, padx=px, pady=py)
        self.entry_powierzchnia.configure(state='disabled')

        self.lbl_pusty_pod_waga_cena.grid(column=1, row=wiersz + 2, padx=px, pady=py)

        self.canvas_obraz_ark_perfo = tk.Canvas(self, width=700, height=150)
        self.canvas_obraz_ark_perfo.place(relx = 0.5,rely = 0.8, anchor='center')
        self.image_ark_perf = tk.PhotoImage(data=kod_obr.zakodowany_arkusz_perforowany_img)
        self.canvas_obraz_ark_perfo.create_image(0, 0, anchor="nw", image=self.image_ark_perf)


    def omenu_materialy_f(self, mater):
        if mater in c.materialy:
            self.waga_1m2_str.set('')
            self.waga_podanego_str.set('')
            self.cena_1m2_str.set('')
            self.cena_1kg_str.set('')
            self.cena_dla_podanego_str.set('')
            g_jedno = c.materialy[mater]['g_jednostkowa']
            self.g_jed_str.set(g_jedno)

    def clr_g_jedn(self):
        self.g_jed_str.set('')
        self.entry_g_jed.delete(0, 'end')

    def clr_szerokosc(self):
        self.szerokosc_str.set('')
        self.entry_szerokosc.delete(0, 'end')

    def clr_powierzchnia(self):
        self.powierzchnia_str.set('')
        self.entry_powierzchnia.delete(0, 'end')

    def clr_grubosc(self):
        self.grubosc_str.set('')
        self.entry_grubosc.delete(0, 'end')

    def clr_dlugosc(self):
        self.dlugosc_str.set('')
        self.entry_dlugosc.delete(0, 'end')

    def clr_waga_1m2(self):
        self.waga_1m2_str.set('')
        self.entry_waga_1m2.delete(0, 'end')

    def clr_waga_podanego(self):
        self.waga_podanego_str.set('')
        self.entry_waga_podanego.delete(0, 'end')

    def clr_cena_1m2(self):
        self.cena_1m2_str.set('')
        self.entry_cena_1m2.delete(0, 'end')

    def clr_cena_1kg(self):
        self.cena_1kg_str.set('')
        self.entry_cena_1kg.delete(0, 'end')

    def clr_cena_dla_podanego(self):
        self.cena_dla_podanego_str.set('')
        self.entry_cena_dla_podanego.delete(0, 'end')

    def clr_przeswit(self):
        self.przeswit_str.set('')
        self.entry_przeswit.delete(0, 'end')

class EntryValid(ttk.Entry):
    def __init__(self, master, textvariable=None, slownik_wyczysc=None):
        super().__init__(master, textvariable=textvariable)

        self.slownik_wyczysc = slownik_wyczysc
        vcmd = self.register(self.validate)
        self.configure(validate="key", validatecommand=(vcmd, '%P'))

    def validate(self, text):
        if text == "":
            if self.slownik_wyczysc is not None:
                keeys = list(self.slownik_wyczysc.keys())
                for kee in keeys:
                    self.wywolanie_f_zew(kee)
            return True
        try:
            float(text.replace(',', '.'))
            if self.slownik_wyczysc is not None:
                keeys = list(self.slownik_wyczysc.keys())
                for kee in keeys:
                    self.wywolanie_f_zew(kee)
            return True
        except ValueError:
            return False

    def wywolanie_f_zew(self, btn):
        if self.slownik_wyczysc is not None:
            if btn in self.slownik_wyczysc:
                self.slownik_wyczysc[btn]()
            else:
                logging.debug('Przycisk nie istnieje w Frame_L0_btns')


class Const:
    materialy = {
        "Stal": {'g_jednostkowa': 7750},
        "Stal nierdzewna": {'g_jednostkowa': 7900},
        "Aluminium": {'g_jednostkowa': 2720},
        "Poliwęglan": {'g_jednostkowa': 1200},
        "POM": {'g_jednostkowa': 1410}
    }

class Kod_obr:
    zakodowany_arkusz_img = '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'

    zakodowana_rura_img = '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'

    zakodowany_pret_img = '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'

    zakodowany_ceownik_img = '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'

    zakodowany_ksztaltownik_img = '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'

    zakodowany_katownik_img = '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'

    zakodowany_arkusz_perforowany_img = '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'

    zakodowany_plaskownik_img = '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'


if __name__ == "__main__":
    c = Const()
    kod_obr = Kod_obr()
    app = Apk()
0

Wymyśliłem sobie nawet takie wyświetlanie ale nadal pozostaje kwestia interakcji i obliczeń
Słownik uklad_widzetow tworzy cały układ gdzie 'le' - to para label-entry, 'l' to label ,a 'btn' to button, '1:1' - to kolumna od której ma zacząć się wstawianie. Nazwy labeli są tworzone automatycznie z tekstu podanego w uklad_widzetow (usuniecie polskich znaków itd)

import tkinter as tk
from tkinter import ttk


class MojaKlasa(ttk.Frame):
    def __init__(self, master=None, uklad=None, padx=2, pady=2, **kwargs):
        super().__init__(master, **kwargs)

        self.padx = padx
        self.pady = pady

        self.lbl = {}
        self.str_var = {}
        self.entry = {}
        self.btn = {}
        self.f_btn = {}

        for ilosc_kompletow, lbl_and_entry in enumerate(uklad):
            ilosc_kompletow *= 2

            poczatkowa_kolumna, _ = lbl_and_entry.popitem()

            for nr_kolumny_widzetow, (widzet_text, typ) in enumerate(lbl_and_entry.items()):
                name_widzetu = self.rename_chars(widzet_text)

                if typ == 'le':
                    label = ttk.Label(self, text=widzet_text)
                    var = tk.StringVar()
                    entry = ttk.Entry(self, textvariable=var, validate='key', validatecommand=(self.register(self.validate_entry), '%P'))

                    label.grid(column=nr_kolumny_widzetow + int(poczatkowa_kolumna), row=ilosc_kompletow, padx=self.padx, pady=self.pady)
                    entry.grid(column=nr_kolumny_widzetow + int(poczatkowa_kolumna), row=ilosc_kompletow + 1,
                               padx=self.padx, pady=self.pady)

                    self.lbl[name_widzetu] = label
                    self.str_var[name_widzetu] = var
                    self.entry[name_widzetu] = entry

                if typ == 'btn':
                    btn_function = lambda widget_text=widzet_text: self.button_callback(widget_text)
                    btn = ttk.Button(self, text=widzet_text, command=btn_function)
                    btn.grid(column=nr_kolumny_widzetow + int(poczatkowa_kolumna), row=ilosc_kompletow + 1,
                             padx=self.padx, pady=self.pady)
                    self.btn[name_widzetu] = btn

                if typ == 'l':
                    label = ttk.Label(self, text=widzet_text)
                    label.grid(column=nr_kolumny_widzetow + int(poczatkowa_kolumna), row=ilosc_kompletow,
                               padx=self.padx, pady=self.pady)
                    self.lbl[name_widzetu] = label

    def button_callback(self, widget_text):
        print(f"Funkcja przypisana do przycisku '{widget_text}' została wywołana.")

    def rename_chars(self, text):
        text = text.lower()
        chars = {'ą': 'a', 'ć': 'c', 'ę': 'e', 'ł': 'l', 'ń': 'n', 'ó': 'o', 'ś': 's', 'ź': 'z', 'ż': 'z', ' ': '_'}
        translation = str.maketrans(chars)
        return text.translate(translation)

    def validate_entry(self, value):
        try:
            if float(value.replace(',','.')) >= 0:
                return True
            else:
                return False
        except ValueError:
            return False


if __name__ == "__main__":
    root = tk.Tk()
    root.title("Przykładowa Aplikacja")

    uklad_widzetow = ({'Długość': 'le', 'Wysokość': 'le', 'Szerokość': 'le', 0: 0},
                      {'waga': 'le', 'waga calosci': 'le', 'waga1m': 'le', 0: 0},
                      {'': 'l', 'oblicz': 'btn', 3: 3})
    frame = MojaKlasa(root, uklad_widzetow, padx=5, pady=5)
    frame.grid(padx=10, pady=10)

    root.mainloop()


0

Co rozumiesz przez: "interakcji i obliczeń" ?

Obliczenia są wykonywane dla wielu pól entry po zmianie w jednym, czasami do obliczenia jakiejś wartości można dojść na kilka sposobów (powinny wtedy wyjść te same wyniki). Dobrze byłoby nie zmieniać wartości wprowadzanych (zaznaczać?) przez użytkownika, jeżeli użytkownik zmienia jedną wartość dobrze by było aby zmianie ulegały wszystkie zależne pola.

To zagmatwanie powoduje, że nie bardzo wiem jak podejść do tego problemu. Zaproponowany wzorzec obserwator chyba nie jest do tego przypadku, bo jedno entry wpływa na wiele innych ale również ono samo jest zmieniane przez wiele innych, przynajmniej tak to rozumiem.

Próbuję teraz coś takiego ale nie wiem jak w klasie En w update() sprawdzić nazwę utworzonej instancji.
Tutaj wersja skrócona:

import tkinter as tk
from tkinter import ttk

    
class En(ttk.Entry):
    def __init__(self, master=None, name=None, **kw):
        self.name = name
        self.value = tk.StringVar()
        super().__init__(master, textvariable=self.value, **kw)
        
        self.lista_subskrybentow = []
        self.bind('<Return>', lambda event: self.notify())
        
    def attach(self, *args):
        for sub in args:
            self.lista_subskrybentow.append(sub)
        
    def deattach(self, *args):
        for sub in args:
            self.lista_subskrybentow.remove(sub)
    
    def notify(self):
        for entry in self.lista_subskrybentow:
            entry.update()
            
    def update(self):
       
        pass
        #if self.__name__? == entra['cal_entry']:
            #wykonaj przeliczenia dla cali
         #elif:
            #itd.

def main():
    root = tk.Tk()
    root.title("Przelicznik cali - cm")

    frame = ttk.Frame(root)
    frame.pack(padx=10, pady=10)
    
    cal_label = ttk.Label(frame, text="Cale:")
    cal_label.grid(row=0, column=0, padx=5, pady=5)

    cal_entry = En(frame)
    cal_entry.grid(row=0, column=1, padx=5, pady=5)

    cm_label = ttk.Label(frame, text="Centymetry:")
    cm_label.grid(row=1, column=0, padx=5, pady=5)

    cm_entry = En(frame)
    cm_entry.grid(row=1, column=1, padx=5, pady=5)
    entra = {'cal_entry' : cal_entry, 'cm_entry': cm_entry}
    cal_entry.attach(cm_entry)

    root.mainloop()

if __name__ == "__main__":
    main()
0

Odpaliłem sobie kod ten długi ( troche wieszał mi sie komputer przy kopiowaniu ☺️ , ok 2500 linii kodu to sporo XD, ale nie taki kod straszny jaki go maluja).

screenshot-20240210143023.png
Tak ogólnie Ja bym przeorganizował interfejs jesli nie masz z góry narzuconego designu . można podzielić na kilka etapów: np tworzenie przekroju i dodanie przekroju do bazy, pożniej wybranie przekroju z dropdown listy. Duży plus bo Istnieje mechanizm logowania zdarzeń. Może coś takiego? To już od Ciebie zależy.

screenshot-20240210152903.png

Poklikałem w poszczególne pola i zauważyłem że jak wpisujemy jakas wartosc w to pole, to ten sam element jest jednocześnie polem wynikowym dla obliczeń z innych pól.

Użycie tego samego pola do wprowadzania danych i wyświetlania wyników może być moim zdaniem mylące dla użytkownika i prowadzić do niejednoznaczności. Dobra praktyka zakłada, że pola przeznaczone są albo do wprowadzania danych, albo do wyświetlania wyników, ale nie powinny pełnić obu funkcji jednocześnie.

Zamiast tego, możesz rozważyć zastosowanie dwóch oddzielnych pól: jednego do wprowadzania danych wejściowych i drugiego do wyświetlania wyników. Na przykład, możesz użyć pola Entry w Tkinter do wprowadzania danych i etykiety Label do wyświetlania wyników.

Kod można spokojnie skrócić, nawet nie używajac jakiś bardzo zaawansowanych rzeczy. Można użyć np StringVar() zamiast obserwatora ( Zamieszcze kod z obserwatorem i <KeyRelease>). Ta funkcja jest pomocna, jeśli chcesz automatycznie aktualizować inne widżety w przypadku pewnych operacji na obiektach zdefiniowanych w Tkinterze. Aby zdefiniować wywołanie zwrotne (callback) na obiekcie StringVar(), możemy użyć metody trace() na obiekcie StringVar(), która przyjmuje 2 parametry naprzykład

import tkinter as tk
 
class GreetingApp(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title('Greeting Application')
        self.geometry("300x300")
 
        self.name_var = tk.StringVar()
        self.name_var.trace('w', self.create_greeting_message)
 
        self.create_widgets()
     
    def create_widgets(self):
        self.description_label = tk.Label(self, text="Enter your name:")
        self.description_label.grid(column=0, row=0)
 
        self.entry = tk.Entry(self, textvariable=self.name_var)
        self.entry.grid(column=1, row=0)
        self.entry.focus()
 
        self.greeting_label = tk.Label(self)
        self.greeting_label.grid(column=0, row=1, columnspan=2)
     
    def create_greeting_message(self, *args):
        name_entered = self.name_var.get()
 
        greeting_message = ""
        if name_entered != "":
            greeting_message = "Hello " + name_entered
         
        self.greeting_label['text'] = greeting_message
 
if __name__ == "__main__":
    app = GreetingApp()
    app.mainloop()

Nie chce Ci mieszać w projekcie (i wywracać go do góry nogami) odniosę się tylko do tego pytania co na poczatku.

Ogólnie w twoim programie operujesz na listach i słownikach i do nich się odnosisz po nazwie to jest Twój taki pojemnik na dane.

Natomiast Tkinker posiada klasę Entry i możesz odniesc sie do tej klasy ( Możesz to jeszcze rozwiazać na inne sposoby i wtedy nie musisz już używać słowników)
Ja odnalazłem w kodzie referencje do utworzonej instancji obiektu (Najszybszy sposób jaki znalazłem wiec nie sugeruj sie jego jakościa)

  age_entry = (
            app.notebook.winfo_children()[0]
            .sub_notebook.winfo_children()[0]
            .winfo_children()[1]
            .entry
        )  # Assuming first tab, first subtab, and second widget is age entry

Jedyna rzecz do dodania to, że podczas korzystania z kart i fielda trzeba jakoś przechować indeks widżetu fielda, aby zawsze móc się do niego odwołać (aby wykonywać działania na konkretnym widżecie fielda) (i mogę powiedzieć, że nie będzie to łatwe). Użyłeś do tego struktury danych Lista (). Ale mi się wydaje że lepiej użyć specjalizowane klasy, które będą odpowiadać za konkretne aspekty aplikacji. Ogólnie można tego tego uniknać wlaśnie rozdzielajac pola na te co chcemy wprowadzać i na te co chcemy wyswietlać. Zeby było jak najprościej

O polach, co jednocześnie wpisujesz w nie dane pisałem wcześniej. Ciężko mi sie było połapać o co chodzi. Możesz jeszcze np rozróżnić pole edytowane od wyświetlanego lub dac jakas mozliwosc wyboru co użytkownik chce aktualnie liczyć.

Zamieszczam przykład kodu poniżej. Mi sie wydaje ze przykład kodu zamieszczonego poniżej jest przesadzony i za bardzo skomplikowany i można zrobić byłoby to dużo prościej i lepiej. Można to zrobić inaczej maksymalnie upraszczajac design.

import tkinter as tk
from tkinter import ttk


class Observable:
    def __init__(self):
        self.observers = []

    def add_observer(self, observer):
        self.observers.append(observer)

    def notify_observers(self):
        for observer in self.observers:
            observer.update()


class Command:
    def execute(self):
        pass


class Observer:
    def update(self):
        pass


class SubmitCommand(Command, Observable):
    def __init__(self):
        super().__init__()
        self.age = ""
        self.email = ""

    @staticmethod
    def validate_age(age):
        try:
            age = int(age)
            if age >= 18:
                return True
            else:
                return False
        except ValueError:
            return False

    def execute(self):
        print("Submit button clicked")
        age_entry = (
            app.notebook.winfo_children()[0]
            .sub_notebook.winfo_children()[0]
            .winfo_children()[1]
            .entry
        )  # Assuming first tab, first subtab, and second widget is age entry
        name_entry = (
            app.notebook.winfo_children()[0]
            .sub_notebook.winfo_children()[0]
            .winfo_children()[0]
            .entry
        )  # Assuming first tab, first subtab, and first widget is name entry
        email_entry = (
            app.notebook.winfo_children()[0]
            .sub_notebook.winfo_children()[0]
            .winfo_children()[2]
            .entry
        )  # Assuming first tab, first subtab, and third widget is email entry

        name = name_entry.get()
        self.email = email_entry.get()
        self.age = age_entry.get()

        if self.validate_age(self.age):
            print("Name:", name)
            print("Email:", self.email)
            print("Age:", self.age)
            print("Age is valid!")
            self.notify_observers()
        else:
            print("Invalid age! Age must be 18 or older.")


class SaveCommand(Command):
    def execute(self):
        print("Save button clicked")


class ClearCommand(Command):
    def execute(self):
        print("Clear button clicked")


class LabeledEntry(tk.Frame, Observer):
    def __init__(self, master=None, label_text="", row=0, column=0, **kwargs):
        super().__init__(master, **kwargs)

        self.label = tk.Label(self, text=label_text)
        self.entry = tk.Entry(self)

        self.label.grid(row=row, column=column, sticky=tk.E)
        self.entry.grid(row=row + 1, column=column, sticky=tk.W)
        self.entry.bind('<KeyRelease>', self.key_released)  # bind event to key release

    def key_released(self, event):
        print("funkcja zauktalizujaca pole gestosc")
        print("wykonaj funkcje aktualizujaca pole długosc")
        # lub funkcja przeliczajaca wszystkie pola

    def update(self):
        self.entry.delete(0, tk.END)
        self.entry.insert(0, "")


class LabeledButton(tk.Frame):
    def __init__(
        self,
        master=None,
        label_text="",
        button_text="",
        row=0,
        column=0,
        command=None,
        **kwargs,
    ):
        super().__init__(master, **kwargs)

        self.label = tk.Label(self, text=label_text)
        self.button = tk.Button(self, text=button_text, command=command.execute)

        self.label.grid(row=row, column=column, sticky=tk.E)
        self.button.grid(row=row + 4, column=column, sticky=tk.W)


class SubTab(ttk.Frame):
    def __init__(self, master=None, labels=[], buttons=[], **kwargs):
        super().__init__(master, **kwargs)

        for label_info in labels:
            label_text, row, column = label_info
            labeled_entry = LabeledEntry(
                self, label_text=label_text, row=row, column=column
            )
            labeled_entry.grid_configure(row=row, column=column, pady=5, padx=5)

        for button_info in buttons:
            button_text, row, column, command = button_info
            labeled_button = LabeledButton(
                self,
                label_text="",
                button_text=button_text,
                row=row,
                column=column,
                command=command,
            )
            labeled_button.grid_configure(row=row, column=column, pady=5, padx=5)


class Tab(ttk.Frame):
    def __init__(self, master=None, tab_name="", subtabs=[], **kwargs):
        super().__init__(master, **kwargs)
        self.sub_notebook = ttk.Notebook(self)
        self.sub_notebook.pack(expand=1, fill="both")
        self.add_subtabs(subtabs)
        self.master.add(self, text=tab_name)

    def add_subtabs(self, subtabs):
        for i, subtab_info in enumerate(subtabs):
            subtab = SubTab(
                self.sub_notebook,
                labels=subtab_info.get("labels", []),
                buttons=subtab_info.get("buttons", []),
            )
            self.sub_notebook.add(subtab, text=f"Subtab {i+1}")


class MultiTabApp(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Multi-tab Example")
        self.minsize(850, 450)

        self.notebook = ttk.Notebook(self)
        self.notebook.pack(expand=1, fill="both")

    def add_outside_button(self, button_text, command):
        outside_button = tk.Button(self, text=button_text, command=command.execute)
        outside_button.pack()

    def add_tab(self, tab_name, subtabs):
        tab = Tab(self.notebook, tab_name=tab_name, subtabs=subtabs)
        self.notebook.add(tab)


# Example usage
if __name__ == "__main__":
    app = MultiTabApp()

    submit_command = SubmitCommand()
    save_command = SaveCommand()
    clear_command = ClearCommand()

    labels_tab1 = [
        {
            "labels": [("Name:", 0, 0), ("Age:", 0, 2), ("Email:", 1, 0)],
            "buttons": [("Submit", 2, 0, submit_command)],
        }
    ]

    labels_tab2 = [
        {
            "labels": [("Address:", 0, 0), ("Phone:", 1, 2), ("Gęstość:", 0, 4)],
            "buttons": [("Save", 2, 2, save_command)],
        },
        {
            "labels": [("Street:", 1, 0), ("Zip Code:", 1, 2), ("Country:", 2, 4)],
            "buttons": [("Clear", 3, 3, clear_command)],
        },
        {
            "labels": [
                ("Gętość jednoskowa:", 1, 0),
                ("Średnica:", 1, 2),
                ("Długość:", 1, 4),
                ("Waga 1mb:", 1, 6),
                ("Waga dla p. długości:", 1, 8),
            ],
            "buttons": [("Clear", 3, 4, clear_command)],
        },
    ]

    app.add_tab("Tab 1", subtabs=labels_tab1)
    app.add_tab("Tab 2", subtabs=labels_tab2)
    app.add_outside_button("Outside Button", submit_command)

    app.mainloop()

Mam nadzieje że cos to pomoże w tworzeniu Twojej Aplikacji.

0

Dziękuję. Ponieważ mam małe doświadczenie, właściwie zerowe to napisałem ten program tak jak umiałem plus to co podpowiedział Chatgpt.
Postaram się jak najwięcej wyciągnąć z tego co napisałeś ale pewnie nie wszystko ogarnę.
Właściwie to powinienem zacząć od założeń i po co ta aplikacja.

Bliska mi osoba zaczęła pracę w firmie gdzie zajmuje się zamówieniami. Chciałbym ułatwić jej pracę z tymi wszystkimi przeliczeniami (firma nie zapewnia takich narzedzi).
To w jaki sposób dostarczane są informacje od dostawców to pierwszy horror.
Np. Jeden dostawca poda cenę za m2 blachy, drugi za kg, trzeci za podaną ilość, czwarty za arkusz, jeden w tonach drugi w kilogramach.

Drugi horror to ilość rodzajów rur, prętów itd. Dla przykładu same rury mogą być calowe, metryczne, plastikowe, metalowe, ocynkowane, nierdzewne, mierzone wg din lub ISO itd. itp.

Dlatego staram się używać ogólnych wymiarów i materiałów bo tego wszystkiego jest za dużo, dlatego też używam gęstości jednostkowej bo zmieniając ją można 'tworzyć' nowe materiały.

Najważniejsze dla mnie jest aby aplikacja działała, nie była taka długa i trudna w utrzymaniu

0

Czasem projektowanie zajmuje więcej czasu niż pisanie kodu... Ogólnie rzecz biorąc, im więcej piszesz kodu i się uczysz, tym więcej rzeczy nabiera sensu. Nie oznacza to jednak, że wiesz już wszystko, bo technologie stale się zmieniają. Ja też musze się jeszcze wiele nauczyć.

Polecam kurs CS50 "Introduction to Computer Science" oraz CS50's "Introduction to Programming with Python". Chociaż to jest już inny oddzielny temat. Istnieje też wiele innych materiałów edukacyjnych (np. dokumentacje, ksiażki, Youtube, Streamy, artykuły na blogach itp.), i zawsze możesz wybrać te które najbardziej Ci odpowiadaja.

Zapoznanie się z kluczowymi pojęciami i źródłami wiedzy pozwoli Ci lepiej zadawać pytania chatbotowi. Pozwoli to też na rozbijanie problemów na mniejsze, łatwiejsze do rozwiązania części. Czasem przydaje się też ogólny pogląd na aplikację, aby uzyskać pełny obraz zagadnień. (Możesz skorzystać i przetestować chat Gemini, Copilot od microsoftu, Youchat, Github copilot, czy Amazon CodeWhisperer).
Dobrze jest również zrobić sobie jakiś plan nauki, liste zadań, priorytety. Bo nie jest do końca tak, że wszystko podczas nauki jest ważne. Nie wszystkie zagadnienia będą Ci potrzebne. Trzeba zastanowić się, czy faktycznie dobre będzie dla nas teraz zgłębienie jakiegoś dodatkowego zagadnienia czy może lepiej skupić się na poznaniu zaawansowanego aspektu tego, co już znamy. No i przede wszystkim warto skupić się na rozwiązaniu jednego problemu zamiast próbować ogarnąć wszystko naraz. Nie zniechęcaj się też początkowymi trudnościami i cierpliwie zgłębiaj tajniki tej dziedziny :-).

Co do Twojego projektu można się jeszcze zapytać te osobe o takie rzeczy jak:

  • Jakie rodzaje obliczeń najczęściej wykonuje w swojej pracy?
  • Jakie funkcje byłyby dla Niej najbardziej przydatne w aplikacji?
  • Jakie są Jej preferencje dotyczące interfejsu użytkownika?
    To pozwoli na jeszcze dokładniesze rozeznanie problemu. Taka aplikacja co piszesz wydaje się dość skomplikowana. Można też rozważyć jakiś podział na etapy.

Twój projekt wydaje się ambitny, ale z odpowiednim planem i wytrwałością z pewnością uda Ci się go zrealizować. Z czasem nabierzesz wprawy i doświadczenia, a satysfakcja z tworzenia własnych aplikacji będzie warta każdego wysiłku!

Powodzenia!

0

Nie chce Ci mieszać w projekcie (i wywracać go do góry nogami)

Właśnie takie wywrócenie by mi się bardzo przydało.

Dobra praktyka zakłada, że pola przeznaczone są albo do wprowadzania danych, albo do wyświetlania wyników, ale nie powinny pełnić obu funkcji jednocześnie

Zrobię po dwa pola entry dla jednej danej, jedno do wprowadzania, drugie do obliczeń.
Tutaj właśnie jest najtrudniejsza część bo czasami jedna wartość jest daną, a za chwilę wartością do obliczenia

Co do Twojego projektu można się jeszcze zapytać te osobe o takie rzeczy jak:

Jakie rodzaje obliczeń najczęściej wykonuje w swojej pracy?
Jakie funkcje byłyby dla Niej najbardziej przydatne w aplikacji?
Jakie są Jej preferencje dotyczące interfejsu użytkownika?

Ważne jest aby obliczyć z uzyskanych danych wszystko co możliwe (tak jak w tym długim kodzie), wygląd bez znaczenia

0

Ulepszyłem program ale przydałoby się jeszcze kilka poprawek. Już 'tylko' 600 linii kodu 🙃
Chciałbym aby cały układ zakładek utworzył się automatycznie (z zachowaniem możliwości dodania zakładki niestandardowej Tab_armatura) np. podając

C.uklad_zakladek = {'Materiały powierzchniowe': {'Arkusz':C.uklad_dla_arkusz,'Arkusz preforowany':C.uklad_dla_arkusz_perforowany},
                  'Materiały długościowe': {Pręt: C.uklad_dla_pret .....itd}}

jak dotychczas w mojej aplikacji z zachowaniem czcionki i paddy dla napisów zakładek.
Nie wiem czy przy takim tworzeniu nie będzie problemu z trace() bo dla każdej zakładki byłaby taka sama nazwa metody wywoływanej.
Chciałbym również aby wszystko to co jest w C.uklad_dla_... było zachowane czyli wyświetlanie widżetów, obrazów, sprawdzanie danych,ograniczeń, blokad i obliczenia. Tylko tam musiałbym coś ewentualnie zmieniać.

Aktualnie nadal tworzone są klasy dla każdej zakładki.
Klasa WstawWidzety tworzy widżety i ich listy oraz je umieszcza na frame.
Klasy typu Tab_powierzchniowe_arkusz (tylko ta jest cała zaimplementowana) wyświetlają frame z widżetami, tworzą między innymi self.wartości_podane w którym są sprawdzone wartości z pól entry, tworzą trace() dla StringVar powiązanych z entrami. Obliczenia wyświetlane są w labelach.
Klasa Obliczenia_wartosci_wg_wzorow na podstawie self.wartości_podane i C.uklad_dla_... liczy wszystkie możliwe wartości dla podanych wzorów w C.uklad_dla_... i je zwraca.
Klasa C zawiera nazwy i układ widżetów, wzory do obliczeń, blokady wpisywania danych (entry(state=)), ograniczenie max wartości dla wpisywanych danych

import tkinter as tk
from tkinter import ttk
import logging
import ast


class WstawWidzety(ttk.Frame):
    def __init__(self, master, uklad, obraz=None):
        super().__init__(master)
        self.labels = {}
        self.entries = {}
        self.blokady = {}
        self.str_var_entries = {}
        self.str_var_labels = {}
        self.ograniczenia_dla_wart_pod = {}

        for rodzaj_widzetu, dane in uklad.items():
            if rodzaj_widzetu == 'label':
                for nazwa, tekst, col, r, _ in dane:
                    varl = tk.StringVar()
                    lbl = ttk.Label(self, text=tekst, textvariable=varl)
                    lbl.grid(row=r, column=col, padx=5, pady=5, sticky='news')
                    self.labels[nazwa] = lbl
                    self.str_var_labels[nazwa] = varl

            if rodzaj_widzetu == 'label_opisowy':
                for tekst, col, r in dane:

                    lbl = tk.Label(self, text=tekst, bg='lightgrey')
                    lbl.grid(row=r, column=col, padx=5, pady=5, columnspan=3, sticky='news')
                    self.columnconfigure(index=(0,2,3,4,6),uniform='a')
            if rodzaj_widzetu == 'entry':
                for nazwa, tekst, col, r in dane:
                    var = tk.StringVar()
                    entry = ttk.Entry(self, textvariable=var)
                    entry.grid(row=r, column=col, padx=5, pady=5)
                    self.entries[nazwa] = entry
                    self.str_var_entries[nazwa] = var

            if rodzaj_widzetu == 'blokady':
                for nazwa, blokowane in dane:
                    self.blokady[nazwa] = blokowane

            if rodzaj_widzetu == 'ograniczenie_max_dla_wartosci_podawanej':
                for nazwa, max_val in dane:
                    self.ograniczenia_dla_wart_pod[nazwa]=max_val



        if obraz is not None:
            self.canvas_obraz_blachy = tk.Canvas(self, width=400, height=150)
            self.canvas_obraz_blachy.place(relx=0.5, rely=0.95, anchor='center')
            self.image_blachy = tk.PhotoImage(data=obraz)
            self.image_blachy = self.image_blachy.subsample(2, 2)
            self.canvas_obraz_blachy.create_image(0, 0, anchor="nw", image=self.image_blachy)


class Apk(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Materiały")
        self.geometry('704x600')
        self.minsize(704, 600)

        logging.basicConfig(level=logging.DEBUG,  # filename="Materialy_log.log",
                            format='%(asctime)s - %(levelname)s - %(message)s')
        logging.debug("-------------Rozpoczęcie programu------------------")  # debug,info,warning,critical

        style = ttk.Style()

        style.configure("TNotebook.Tab", padding=(10, 5), font=("Helvetica", 10))

        self.zakladki_r_materialu = ttk.Notebook(self)
        self.tab_dlugosciowe = Tab_dlugosciowe()
        self.zakladki_r_materialu.add(self.tab_dlugosciowe, text="Materiały długościowe")

        self.tab_powierzchniowe = Tab_powierzchniowe()
        self.zakladki_r_materialu.add(self.tab_powierzchniowe, text="Materiały powierzchniowe")

        self.tab_armatura = Tab_armatura()
        self.zakladki_r_materialu.add(self.tab_armatura, text="Armatura")

        self.zakladki_r_materialu.place(relx=0, rely=0, relwidth=1, relheight=1)
        self.mainloop()


class Tab_armatura(ttk.Frame):
    def __init__(self, master=None):
        super().__init__(master)

        self.frame_iso = tk.Frame(self)
        rows = [
            ["ISO", '10', '13,5', '17,2', '21,3', '26,9', '33,7', '42,4', '48,3', '60,3', '76,1', '88,9', '114,3'],
            ["Cale", '1/8"', '1/3"', '3/8"', '1/2"', '3/4"', '1"', '1 1/4"', '1 1/2"', '2"', '2 1/2"', '3"', '4"']
        ]

        for row, data_row in enumerate(rows):
            for col, value in enumerate(data_row):
                label = tk.Label(self.frame_iso, text=value, borderwidth=1, relief="solid", width=7)
                label.grid(row=row, column=col)
                if col % 2 == 0:
                    label.configure(bg='yellow')
                else:
                    label.configure(bg="#EFEF00")

        self.frame_iso.grid(column=0, row=0, padx=10, pady=10)


class Tab_dlugosciowe(ttk.Frame):
    def __init__(self, master=None):
        super().__init__(master)

        self.zakladki_dlugosciowe = ttk.Notebook(self)

        self.tab_dlu_rura = Tab_dlu_rura()
        self.zakladki_dlugosciowe.add(self.tab_dlu_rura, text="Rura")

        self.tab_dlu_pret = Tab_dlu_pret()
        self.zakladki_dlugosciowe.add(self.tab_dlu_pret, text="Pret")

        self.tab_dlu_plaskownik = Tab_dlu_plaskownik()
        self.zakladki_dlugosciowe.add(self.tab_dlu_plaskownik, text="Płaskownik")

        self.tab_dlu_ksztaltownik = Tab_dlu_ksztaltownik()
        self.zakladki_dlugosciowe.add(self.tab_dlu_ksztaltownik, text="Kształtownik")

        self.tab_dlu_katownik = Tab_dlu_katownik()
        self.zakladki_dlugosciowe.add(self.tab_dlu_katownik, text="Kątownik")

        self.tab_dlu_ceownik = Tab_dlu_ceownik()
        self.zakladki_dlugosciowe.add(self.tab_dlu_ceownik, text="Ceownik")

        self.zakladki_dlugosciowe.place(relx=0, rely=0, relwidth=1, relheight=1)


class Tab_dlu_rura(ttk.Frame):
    def __init__(self, master=None):
        super().__init__(master)


class Tab_dlu_pret(ttk.Frame):
    def __init__(self, master=None):
        super().__init__(master)


class Tab_dlu_plaskownik(ttk.Frame):
    def __init__(self, master=None):
        super().__init__(master)


class Tab_dlu_ksztaltownik(ttk.Frame):
    def __init__(self, master=None):
        super().__init__(master)


class Tab_dlu_katownik(ttk.Frame):
    def __init__(self, master=None):
        super().__init__(master)


class Tab_dlu_ceownik(ttk.Frame):
    def __init__(self, master=None):
        super().__init__(master)


class Tab_powierzchniowe(ttk.Frame):
    def __init__(self, master=None):
        super().__init__(master)

        self.zakladki_powierzchniowe = ttk.Notebook(self)

        self.tab_pow_arkusz = Tab_powierzchniowe_arkusz()
        self.zakladki_powierzchniowe.add(self.tab_pow_arkusz, text="Arkusz")

        self.tab_pow_arkusz_perf = Tab_powierzchniowe_arkusz_perforowany()
        self.zakladki_powierzchniowe.add(self.tab_pow_arkusz_perf, text="Arkusz perforowany")

        self.zakladki_powierzchniowe.place(relx=0, rely=0, relwidth=1, relheight=1)


class Tab_powierzchniowe_arkusz(ttk.Frame):
    def __init__(self, master=None):
        super().__init__(master)
        self.wartosci_podane = {}
        self.labels_name = []
        self.widzety = WstawWidzety(self, C.uklad_dla_arkusz,obraz=Kodowane_obrazy.zakodowany_arkusz_img)
        self.widzety.place(x=0, y=0, relwidth=1, relheight=1)
        for name, var in self.widzety.str_var_entries.items():
            var.trace('w', self.trace_dla_str_var_entry_arkusz)
            self.wartosci_podane[name] = ''
            self.labels_name.append(name)
        self.obliczenia_wartosci_wg_wzorow = Obliczenia_wartosci_wg_wzorow()

    def trace_dla_str_var_entry_arkusz(self, *args):


        for name in self.labels_name:
            self.wartosci_podane[name] = ''
            self.widzety.str_var_labels[name].set('')
            self.widzety.entries[name].configure(state='normal')


        for name,blokady in self.widzety.blokady.items():
            for blokada in blokady:
                if self.widzety.entries[name].get() != '':
                    self.widzety.entries[blokada].configure(state='disabled')

        for name,str_var in self.widzety.str_var_entries.items():

            try:
                war = float(str_var.get().replace(',', '.').strip())
                if name in self.widzety.ograniczenia_dla_wart_pod.keys():
                    try:
                        war = float(str_var.get().replace(',', '.').strip())
                        if war > self.widzety.ograniczenia_dla_wart_pod[name]:
                            war = self.widzety.ograniczenia_dla_wart_pod[name]
                    except:
                        war = -1.0
            except:
                war = -1.0

            if war > 0.1:
                self.wartosci_podane[name] = str(war)
                self.widzety.str_var_labels[name].set(str(war))
            else:
                self.wartosci_podane[name] = ''
                self.widzety.str_var_labels[name].set('')

        do_wyswietlenia = self.obliczenia_wartosci_wg_wzorow(wartosci_pod=self.wartosci_podane, uklad=C.uklad_dla_arkusz)

        for name,value in do_wyswietlenia.items():
            self.widzety.str_var_labels[name].set(value)


class Tab_powierzchniowe_arkusz_perforowany(ttk.Frame):
    def __init__(self, master=None):
        super().__init__(master)
        self.wartosci_podane = {}
        self.labels_name = []
        self.widzety = WstawWidzety(self, C.uklad_dla_arkusz_perforowany,obraz=Kodowane_obrazy.zakodowany_arkusz_perforowany_img)
        self.widzety.place(x=0, y=0, relwidth=1, relheight=1)
        for name, var in self.widzety.str_var_entries.items():
            var.trace('w', self.trace_dla_str_var_entry_arkusz_perforowany)
            self.wartosci_podane[name] = ''
            self.labels_name.append(name)
        self.obliczenia_wartosci_wg_wzorow = Obliczenia_wartosci_wg_wzorow()

    def trace_dla_str_var_entry_arkusz_perforowany(self, *args):


        for name in self.labels_name:
            self.wartosci_podane[name] = ''
            self.widzety.str_var_labels[name].set('')
            self.widzety.entries[name].configure(state='normal')


        for name,blokady in self.widzety.blokady.items():
            for blokada in blokady:
                if self.widzety.entries[name].get() != '':
                    self.widzety.entries[blokada].configure(state='disabled')

        for name,str_var in self.widzety.str_var_entries.items():

            try:
                war = float(str_var.get().replace(',', '.').strip())
                if name in self.widzety.ograniczenia_dla_wart_pod.keys():
                    try:
                        war = float(str_var.get().replace(',', '.').strip())
                        if war > self.widzety.ograniczenia_dla_wart_pod[name]:
                            war = self.widzety.ograniczenia_dla_wart_pod[name]
                    except:
                         war = -1.0
            except:
                war = -1.0

            if war > 0.1:
                self.wartosci_podane[name] = str(war)
                self.widzety.str_var_labels[name].set(str(war))
            else:
                self.wartosci_podane[name] = ''
                self.widzety.str_var_labels[name].set('')

        do_wyswietlenia = self.obliczenia_wartosci_wg_wzorow(wartosci_pod=self.wartosci_podane, uklad=C.uklad_dla_arkusz_perforowany)

        for name,value in do_wyswietlenia.items():
            self.widzety.str_var_labels[name].set(value)

# --------------------------------------------------------------------------------------------------------

class Obliczenia_wartosci_wg_wzorow:
    def __call__(self, wartosci_pod, uklad):


        self.wartosci_pod = wartosci_pod
        self.uklad = uklad
        self.nazwy_labeli = []
        self.labele_i_ich_wzory = {}


        for rodzaj_widzetu, dane in uklad.items():
            if rodzaj_widzetu == 'label':
                for nazwa, tekst, col, r, wzor in dane:
                    self.nazwy_labeli.append(nazwa)
                    self.labele_i_ich_wzory[nazwa] = wzor


        for nazwa, wzory in self.labele_i_ich_wzory.items():
            if self.wartosci_pod[nazwa] == '':
                if len(self.labele_i_ich_wzory[nazwa])>1:
                    self.obliczenia_dla_kilku_wzorow(nazwa)
                else:
                    self.obliczenia_dla_jednego_wzoru(nazwa)

        return self.przygotuj_do_wyswietlenia(self.wartosci_pod)



    def obliczenia_dla_jednego_wzoru(self,co):
        lista_slow = self.slowa_w_stringu(*self.labele_i_ich_wzory[co])
        #logging.debug(f'{lista_slow=}')
        kontynuuj = False
        for slowo in lista_slow:
            if self.wartosci_pod[slowo] == '':
                kontynuuj = False
                break
            else:
                kontynuuj = True

        if kontynuuj:

            #logging.debug(f'{co=}, {self.wartosci_pod}, wzor = {self.labele_i_ich_wzory[co]}')
            wartosci_pod_float = self.wartosci_na_float(self.wartosci_pod)
            self.wartosci_pod[co] = str(self.oblicz_wyrazenie(*self.labele_i_ich_wzory[co], wartosci_pod_float))


    def obliczenia_dla_kilku_wzorow(self, co):
        lista_wynikow =[]
        self.lista_wzorow = self.labele_i_ich_wzory[co]

        for wzor in self.lista_wzorow:
            lista_slow = self.slowa_w_stringu(wzor)
            #logging.debug(f'{lista_slow=}')
            kontynuuj = False
            for slowo in lista_slow:
                if self.wartosci_pod[slowo] == '':
                    kontynuuj = False
                    break
                else:
                    kontynuuj = True

            if kontynuuj:
                lista_wynikow.append(self.oblicz_wyrazenie(wzor, self.wartosci_na_float(self.wartosci_pod)))

        if len(lista_wynikow) >1:
            wynikk = self.czy_wyniki_roznia_sie_miedzy_soba(lista_wynikow)
            self.wartosci_pod[co] = wynikk
        elif len(lista_wynikow) ==1:
            self.wartosci_pod[co] = lista_wynikow[0]

    def czy_wyniki_roznia_sie_miedzy_soba(self,lista_float):

        srednia = (sum(lista_float))/(len(lista_float))
        delta = srednia*0.05
        min_val = srednia-delta
        max_val = srednia+delta
        kon = False

        for wart in lista_float:
            if wart > max_val or wart < min_val:
                return '-999'

        return str(srednia)

    def przygotuj_do_wyswietlenia(self, slownik):
        for klucz, wart in slownik.items():
            if wart == '':
                pass
            elif isinstance(wart, str):
                try:
                    slownik[klucz] = str(round(float(wart), 4))
                except ValueError:
                    slownik[klucz] = ''
            elif isinstance(wart, float):
                slownik[klucz] = str(round(wart, 4))
        return slownik

    def wartosci_na_float(self,slownik):

        for klucz, wartosc in slownik.items():
            if wartosc == '':
                pass
            else:
                slownik[klucz] = float(wartosc)
        return slownik

    def slowa_w_stringu(self, wzor_string):
        lista = []
        for slowo in self.nazwy_labeli:
            if slowo in wzor_string:
                lista.append(slowo)
        return lista


    def oblicz_wyrazenie(self, wyrazenie222, wartosci222):
        drzewo = ast.parse(wyrazenie222, mode='eval')

        def odwiedz(node):
            if isinstance(node, ast.Name):
                return wartosci222[node.id]
            elif isinstance(node, ast.Constant):
                return node.value
            elif isinstance(node, ast.BinOp):
                left = odwiedz(node.left)
                right = odwiedz(node.right)
                if isinstance(node.op, ast.Add):
                    return left + right
                elif isinstance(node.op, ast.Sub):
                    return left - right
                elif isinstance(node.op, ast.Mult):
                    return left * right
                elif isinstance(node.op, ast.Div):
                    return left / right
            else:
                raise ValueError("Nieobsługiwany typ węzła")

        return odwiedz(drzewo.body)

class C:
    uklad_dla_arkusz = {
        'label_opisowy': [
            ('Długość [mm]', 0, 0),
            ('Szerokość [mm]', 0, 2),
            ('Grubość [mm]', 0, 4),
            ('Powierzchnia [m2]', 0, 6),
            ('Gęstość jednostkowa [kg/m3]', 0, 8),
            ('Masa 1m2 [kg]', 4, 0),
            ('Masa dla podanych wymiarów [kg]', 4, 2),
            ('Cena za 1m2 [zł]', 4, 4),
            ('Cena za 1kg [zł]', 4, 6),
            ('Cena dla podanych wymiarów [zł]', 4, 8)
        ],
        'entry': [

            ('dlugosc', '0', 0, 1),
            ('szerokosc', '0', 0, 3),
            ('grubosc', '0', 0, 5),
            ('powierzchnia', '0', 0, 7),
            ('g_jednostkowa', '0', 0, 9),
            ('masa_1m2', '0', 4, 1),
            ('masa_pod', '0', 4, 3),
            ('cena_1m2', '0', 4, 5),
            ('cena_1kg', '0', 4, 7),
            ('cena_pod', '0', 4, 9)
        ],
        'label': [
            ('dlugosc', '', 2, 1, ["powierzchnia/(szerokosc/1000)"]),
            ('szerokosc', '', 2, 3, ["powierzchnia/(dlugosc/1000)"]),
            ('grubosc', '', 2, 5, ["masa_1m2*(dlugosc/1000)"]),
            ('powierzchnia', '', 2, 7, ["(dlugosc*szerokosc)/1000000"]),
            ('g_jednostkowa', '', 2, 9,["masa_1m2/(grubosc/1000)", "(masa_pod/((dlugosc/1000)*(szerokosc/1000)))/(grubosc/1000)"]),
            ('masa_1m2', '', 6, 1, ["masa_pod/((dlugosc/1000)*(szerokosc/1000))","(grubosc/1000)*g_jednostkowa"]),
            ('masa_pod', '', 6, 3, ["masa_1m2*(dlugosc/1000)*(szerokosc/1000)","(dlugosc/1000)*(szerokosc/1000)*(grubosc/1000)*g_jednostkowa"]),
            ('cena_1m2', '', 6, 5, ["masa_1m2*cena_1kg","cena_pod/powierzchnia"]),
            ('cena_1kg', '', 6, 7, ["cena_1m2/masa_1m2", "cena_pod/masa_pod"]),
            ('cena_pod', '', 6, 9, ["cena_1m2*powierzchnia","cena_1kg*masa_pod"])
        ],
        'blokady': [
            ('g_jednostkowa',['masa_1m2','masa_pod']),
            ('masa_1m2',['masa_pod','g_jednostkowa']),
            ('masa_pod',['masa_1m2','g_jednostkowa']),
            ('cena_1m2',['cena_1kg','cena_pod']),
            ('cena_1kg',['cena_1m2','cena_pod']),
            ('dlugosc', ['powierzchnia']),
            ('szerokosc', ['powierzchnia']),
            ('cena_pod',['cena_1m2', 'cena_1kg'])
        ],
        'ograniczenie_max_dla_wartosci_podawanej': [
            #('cena_pod',15)
        ]
    }

    uklad_dla_arkusz_perforowany = {
        'label_opisowy': [
            ('Długość [mm]', 0, 0),
            ('Szerokość [mm]', 0, 2),
            ('Grubość [mm]', 0, 4),
            ('Prześwit [%]', 0, 6),
            ('Powierzchnia z otworami [m2]', 0, 8),
            ('Gęstość jednostkowa [kg/m3]', 0, 10),
            ('Masa 1m2 [kg]', 4, 0),
            ('Masa dla podanych wymiarów [kg]', 4, 2),
            ('Cena za 1m2 [zł]', 4, 4),
            ('Cena za 1kg [zł]', 4, 6),
            ('Cena dla podanych wymiarów [zł]', 4, 8)
        ],
        'entry': [

            ('dlugosc', '0', 0, 1),
            ('szerokosc', '0', 0, 3),
            ('grubosc', '0', 0, 5),
            ('przeswit', '0', 0, 7),
            ('powierzchnia', '0', 0, 9),
            ('g_jednostkowa', '0', 0, 11),
            ('masa_1m2', '0', 4, 1),
            ('masa_pod', '0', 4, 3),
            ('cena_1m2', '0', 4, 5),
            ('cena_1kg', '0', 4, 7),
            ('cena_pod', '0', 4, 9)
        ],
        'label': [
            ('dlugosc', '', 2, 1, ["powierzchnia/(szerokosc/1000)"]),
            ('szerokosc', '', 2, 3, ["powierzchnia/(dlugosc/1000)"]),
            ('grubosc', '', 2, 5, ["masa_1m2*(dlugosc/1000)"]),
            ('przeswit','',2,7,[""]),
            ('powierzchnia', '', 2, 9, ["(dlugosc*szerokosc)/1000000"]),
            ('g_jednostkowa', '', 2, 11,["masa_1m2/(grubosc/1000)", "(masa_pod/((dlugosc/1000)*(szerokosc/1000)))/(grubosc/1000)"]),
            ('masa_1m2', '', 6, 1, ["masa_pod/((dlugosc/1000)*(szerokosc/1000))","(grubosc/1000)*g_jednostkowa"]),
            ('masa_pod', '', 6, 3, ["masa_1m2*(dlugosc/1000)*(szerokosc/1000)","(dlugosc/1000)*(szerokosc/1000)*(grubosc/1000)*g_jednostkowa"]),
            ('cena_1m2', '', 6, 5, ["masa_1m2*cena_1kg","cena_pod/powierzchnia"]),
            ('cena_1kg', '', 6, 7, ["cena_1m2/masa_1m2", "cena_pod/masa_pod"]),
            ('cena_pod', '', 6, 9, ["cena_1m2*powierzchnia","cena_1kg*masa_pod"])
        ],
        'blokady': [
            ('g_jednostkowa',['masa_1m2','masa_pod']),
            ('masa_1m2',['masa_pod','g_jednostkowa']),
            ('masa_pod',['masa_1m2','g_jednostkowa']),
            ('cena_1m2',['cena_1kg','cena_pod']),
            ('cena_1kg',['cena_1m2','cena_pod']),
            ('dlugosc', ['powierzchnia']),
            ('szerokosc', ['powierzchnia']),
            ('cena_pod',['cena_1m2', 'cena_1kg'])
        ],
        'ograniczenie_max_dla_wartosci_podawanej': [
            ('przeswit', 99)

        ]
    }
class Kodowane_obrazy:

    zakodowany_arkusz_img = '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'

    zakodowana_rura_img = 'iVBORw0KGgoAAAANSUhEUgAAAssAAACoCAYAAAAW96MGAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAAhRSURBVHhe7d3NkdRIEIBRWAvGATzABUzizHWunDEJF/AAB9oDQLut2NlepVql36qs9yIIdKFpiOmIr3JSmve32+3XOwAA4H/+uv8OAAA8EMsAABAQywAAEBDLAAAQEMsAABAQywAAEBDLAAAQEMsAABAQywAAEBDLAAAQEMsAABAQywAAEBDLAAAQEMsAABAQywAAEBDLAAAQEMsAABAQywAAEHh/u91+3a+Z8fLycr8CAFjuT2vdr2iRWJ4hkAGAvYjmNonlBwIZADiSaG6LWL4TyQDAmURzG7q/wW+IZKEMAGz18/uPv38tpT/a0O1k+cwv0JIPDgCQy4dPH+9X00yY69ZlLJeE8lzoPvvif0swA0C/BHO7uovlJaG8JmyXhLNgBoC+ieb2dBXLz0J5j5h99iEQzADQt7lWEMv16SaW50L5iIAVzQBARDC3o4unYZwdygMxDABE5jqh5N4qjpc+lq8I5dHc6z+bPAMAuQnmNqSO5StDeSSYAYCIYK5f2p3lvUI5CtrS2J4L47PCHQCoU9QJ9pevlzKWt4Zy6cR3aewKZgAgIpjr1FUsPwvS0kh+tCXExTIAIJjrky6W14Ty1kh+tDbKBTMA9E0s1yfVDX41hPLg2WtG7+eI9wIAtCNqhLkVU46VarJcGstL4vT185f71X+9fvt6v4qtifS5PwMA9CHqBBPm86WJ5b1DOYrkR8+iWTADAKXEcj1Sx/KaUF4ayY/molkwAwClBHMdUuwsl+zxHBHKg7k/O/d3AgBQr7Q/wa90MrsllEdrXmPN9BsAyM93mevQfCzvMVXeI5RH0WuJXwBgDyXtw3YpJ8tTJ7EzQnlUGsxOjgDAFI1wvaZjueaT1R4TZtNoAGCK6fJ50k2Wr54qr+XkCABM0QjXajaWl56orgxl02UA4Cimy+dINVmu8eRVEuVOjgDAFI1wnSZjuYWp8jOmywAA9UszWa75xGW6DAAcwSrG8dLd4PdMDVNlAIBSBmrXaC6Wt65g1MQqBgBA3VJMlpeetK6cKlvFAABoT8o1jJamsCbGAMBSUwM1e8vH6mZnuYZdZfvSAABtaSqWezo5TZ0cTaEBAM7V/GT5MSpbDEoRDABsYRXjOF2sYdS0/mAVAwDYwoMAztVMLDsx/cMUGgDgPE1PljOdrKYi2MkRAOBaqdYwpoKzxrUHqxgAwBZTAzXfhT9GFzvLAACwRhOx3PNJaerkaG8ZAOAczU6WHyMyQ0CKYACAuqRew6h5N9jeMgBA/ewsAwBAQCwDADTIEzHOIZYBACAgli80tbe89IeTuBkQAOB41cfy1LcTljwJww10AABsZbIMAAABsQwAAAGxDAAAAbEMAAABsQwA0CjPWj5eylhu6UkYSx8fBwDA+ZqP5V7C0rOWAQDO11wsT0UjAAAcoepYtnMDAMCV3OAHAAABsQwAAAGxDAAAAbEMAAABsQwAAAGxDAAAAbEMAAABsQwAAAGxDAAAAbEMAAABsQwAAAGxDAAAAbEMAAABsQwAAAGxDACQyO12u1+xB7EMANCoD58+3q84StWxPHUyevyi+Pn9x/2qPz3/2wEAzpBysvz67ev9qn5T73Uqgp0cAQDOZw0DAAACYhkAAAJiGQAAAmIZAAACYhkAAAIpYnnq6REtPREDAKDU1JOy/ECS/TUZy1keo7b0sXEAAFyj+lh2Qpo+HIhqAIDj2VkGAICAWAYAgEDqWK75Jj83IAIA1C9NLGfY4bWHDAAs4UkY52k2lrM8EQMAgHo1Ecs9n5Q8CQMA4Drpb/CrcTfYvjIAsJbvrp8rVSy3PHE1LQYA1rKvfJymYzn7ycrJEQDgWs3E8pYTU01rD1vfiwk0AMB50u0stxiTAhgAWGLqu85WMI6V/gY/AABYq6lYnjo5Ld3rrWEVo+Q9TP27TKABAM6VcrLcUlQKYABgCTf+X6OrNYwrp8s13WQIAORgX/l4KWK51ZWF6D06OQIA1KG5WO71BGVdAwD6ZZB2na7WMAZXrENYwQAA9mYF4xxpYrlkFaOGeLWCAQAsoQ2u1WQst3SS2iPMrWAAAG+ZKp8n1RpGbdPl6O8wVQYAltAG12s2lktOVC1PZk2VAQCuk+4Gv5IT2JHTZVNlAGCLqA2sYJyr6VjeY7p8RDCXhjIAAHVKN1kelE5p9wzmNa8VvV9xDQB9MlWuR/OxvNfu8h7BPPcawhcAoD0pJ8uDNdPaLcG8NpRNlQGAt0yV6/L+z3/8r/t1015eXu5X/1oTqaPXz1/uV/OeBfaz6BXLAMBIKNcndSwPtgTzIIrmJVNooQwAlBDL9UkTy4OjgnkNoQwAlBDKdUq7s7zUEXEqeAGAEkK5Xqkmy4M10+XR1inz0kg2VQYARnP9IZavly6WB1uCeVAazSWRK5QBgLeiNhDKdegqlgd7hO2oNHDnXk8sA0B/hHL9UsbyYK9g3pOpMgAwmBugCeW6pL3Br7YvNKEMAAzmQpn6pJ0sj66eMM99IIQyAPTlWSibKtcn/aPj5r7ojj7ZOTkCAIOhCYRym9JPlgdz0+XBERPeZx8IU2UAyG/J4Ewk162LWB6dEc1LPhRCGQDyWtICI6Fcv65iefAsmAdrYlYkA0C/SgJ5JJTb0F0sD5YE82gucEs+GEIZANqxJn6XEslt6TKWByXBDACwB6Hcnm5jeSSaAYAjCeS2dR/LA8EMAOxJIOchlh8IZwBgC6Gci1ieIZwBoF6ilDOIZQAACKT/cdcAALCWWAYAgIBYBgCAgFgGAICAWAYAgIBYBgCAgFgGAICAWAYAgIBYBgCAgFgGAICAWAYAgIBYBgCAgFgGAICAWAYAgIBYBgCASe/e/QZGhVA21Yoj8AAAAABJRU5ErkJggg=='

    zakodowany_pret_img = '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'

    zakodowany_ceownik_img = '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'

    zakodowany_ksztaltownik_img = 'iVBORw0KGgoAAAANSUhEUgAAAssAAACoCAYAAAAW96MGAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAAiZSURBVHhe7d3NbaO3FoDhSSowkHJuKXeZCrJKDVmlgixTSsoJ4A5yQ1w5o8yQI30Uefj3PMCBCXhhwyLk1wcW9N37+/tfnwDgAG9vb7cTO/m7ZW4naE8sA7AdUXwWsUxPYhmAJQliPohlehLLAExNFPOIWKYnsQzAcIKYV4hlehLLAISZIYr//OP324mZ/PCf/95O14llehLLADQliPmWV6K4RCzTk1gGoIoo5lt6RHGJWKYnsQxAkSDmkcgoLhHL9CSWARDFPDQyiu/vRu77EMv0JJYBDiGIecaoKH72bohloollgM2IYp4xexSXiGWiiWWABQlinjEqiJNe90MsE00sA0xMFPOMHaO4RCwTTSwDDCaIedZJUVwilokmlgGCiGKeJYrLxDLRxDJAQ4KYK0TxdWKZaGIZoIIo5gpR3I5YJppYBigQxFwlivsTy0QTy8DxRDFXieJxxDLRxDJwBEFMDVE8H7FMNLEMbEUUU0MUr0MsE00sA0saHcUCZ02joth9aUcsE00sA9OyJaaWKN6XWCaaWAaGsyWmxqggTtyZccQy0cQyEMKWmFqimHtimWhiGWjKlphaophniGWiiWXgMltiXiGKeYVYJppYBopsiXmFKKYHsUw0sQyHsyXmVaKYSGKZaGIZDmFLzKtEMTMQy0QTy7ARW2JaEMXMTCwTTSzDgmyJaUEUsyKxTDSxDJOyJaYVUcxOxDLRxDIMZktMK6KYE4hloollCGBLTEujotgdYgZimWhiGRqyJaYlUQxfE8tEE8twkS0xLY0K4sQ9YkVimWhiGQpEMS2JYmhDLBNNLHM0QUxrohj6EstEE8scQRTTmiiGMcQy0cQy2xDE9CCKYS5imWhimeWIYnoQxbAGsUw0scyUBDG9iGJYm1gmmlhmKFFML6IY9iSWiSaW6U4Q05MohrOIZaKJZZoRxfQkioFELBNNLHOJIKa3UVHsXsEaxDLRxDJZopjeRDFQQywTTSwfTBDT26ggTtwt2JNYJppYPoAopjdRDEQRy0QTy5sQxEQQxcBoYploYnkxopgIohiYlVgmmliekCAmiigGViOWiSaWBxLFRBHFwC7EMtHEcmeCmEiiGNidWCaaWG5EFBNJFAOnEstEE8sVRoaxUDmLKAb4N7FMNLF8UVQoC5WziGKA54hloonli1rGskg5z6godteAXYhloonli2b432Tm9RGlohigD7FMNLFcQTAzmigGTiWWiSaWK4hloohigH8Ty0QTyxXEMq2JYoDniGWiieUKYplaohjgNWKZaGK5Qi6WRdB5ck/YH9wHgD7EMtG+v30EGkiRLJQBYB82yxUebZa/tXFkbY8eZ6EM0JfNMtFslgEAoEAsAwBAgVgGAIACsQwAAAVe4Feh5gV+v/784+3EKn765bfb6TMv8AMYywv8iGazDAAABWIZAAAKxDIAABSIZQAAKBDLAABQIJYBAKBALAMAQIFYBgCAArEMAAAFYhkAmFZ6x777gWhiGQAY7sso/hgYTSwDAKFEMSsRywBAF7koTgMrEcsAwMuio/j9/f2fgZ7EMgDwtFwUp+npPowFMtHEMgDwlVwQp+kpF8VpYCSxDACHE8VQJpYB4BC5KE7TkyhmdWIZADY0QxSngdWJZQBYWC6K0/QkijmJWAaABeSCOE1PuShOAycRywAwGVEM8xDLADBILorT9CSK4RqxDAABZojiNMA1YhkAGspFcZqeRDH0I5YBoNIMUZwG6EcsA8ADuShO00suiNMA8cQyANzkgjhNT6IY5iaWATjSDFGcBpibWAZga7koTtOTKIZ9iGUAtjFDFKcB9iGWAVhOLorT9CSK4UxiGYBp5YI4TU+5KE4DnEksAzAFUQzMSCwDECoXxWl6EsVALbEMQDczRHEagFpiGYCX5aI4TU+iGIgglgG4ZIYoTgMQQSwDkJWL4jS95II4DcBIYhngcLkgTtOTKAZWIZYBDjJDFKcBWIVYBthQLorT9CSKgR2JZYDFzRDFaQB29N3fT3B/3c486e3t7Xb67M8/fr+d/v+L60u//vzj7cTsfvrlt9vpa48e5/vPQ2u9IzhHBAOnE8sVxPIevhXFJWKZCKIYYB5iuYJYXktNFJeIZVqLDmNRDHCNWK4glufUMopLxDK1oqM4EcYArxPLFcTyWBFRXCKWeUZ0GItigH7EcgWxHGNUFH88VrmvL5a5Fx3FiTAGiCWWK4jl9kaE8aPHRCxzLzqMRTHAHMRyBbFcb8YoLhHLZxLFANwTyxXE8mMrRXGJWN5bdBQnwhhgPWK5glj+bEQUJxE/T7G8j+gwFsUA+xDLFU6M5Z2juEQsryc6ihNhDLA3sVxh51g+MYpLxPLcosNYFAOcSSxX2CGWRfFjYnkO0VGcCGMAPojlCqvF8ogwXimKS8RyLFEMwIzEcoVZY1kUtyWW+4kOY1EMQC2xXGF0LI+I4mTnMM4Ry6+LjuJEGAPQkliuEBXLongssXxNdBiLYgAiiOUKrWNZFM9JLOdFR3EijAEYRSxXqI1lUbyW02NZFAOAWK5SE8sRRHFbJ8Vy9J0VxQCsQixXmDWW6W/1WB5xN4UxACv7/vYR2EwK4y+npxTFuQGAldksV7BZPteMm+UR900EA3AKm2VYyMeG+H56ut8Q3w8AnMJmuYLN8rmiNsvRd0gAA0CeWK7wKJY5Q4tYHvGHlTAGgOeJ5QpimeRqLNsWA8B6xHIFsUxSimXbYgDYh1iukItliCCKASCWWK4glokgjAFgPLFcQSzTkigGgHmJ5QpimRqiGADWI5YriGUeEcYAsAexDAAABd7uGgAACsQyAAAUiGUAACgQywAAUCCWAQCgQCwDAECBWAYAgAKxDAAABWIZAAAKxDIAABSIZQAAKBDLAABQIJYBAKBALAMAQIFYBgCAArEMAAAFYhkAAArEMgAAZH369D+6jNJmaNuhQAAAAABJRU5ErkJggg=='

    zakodowany_katownik_img = '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'

    zakodowany_arkusz_perforowany_img = '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'

    zakodowany_plaskownik_img = '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'


if __name__ == "__main__":
    app = Apk()

0

Udało mi się stworzyć program zachowując wszystko co wypisałem post wyżej.
Co jeszcze można poprawić?


import tkinter as tk
from tkinter import ttk
import ast
import logging
class SubTab(ttk.Frame):
    def __init__(self, master=None, name_zakladki = None, dane_dla_zakladki=None, **kwargs):
        super().__init__(master, **kwargs)
        self.dane_dla_zakladki = dane_dla_zakladki
        self.name_zakladki = name_zakladki
        self.obrazek =None

        if self.name_zakladki in KodowaneObrazy.img:
            self.obrazek = KodowaneObrazy.img[self.name_zakladki]
        else:
            self.obrazek = None
        if self.name_zakladki == 'Armatura':
            self.tab_armatura = Tab_armatura(self)
            self.tab_armatura.place(x=0, y=0, relwidth=1, relheight=1)
        else:
            self.widzety = WstawWidzety(self, self.dane_dla_zakladki, obraz=self.obrazek)
            self.widzety.place(x=0, y=0, relwidth=1, relheight=1)
            self.wartosci_podane = {}
            self.labels_name = []

            for name, var in self.widzety.str_var_entries.items():
                var.trace('w', self.trace_dla_str_var_entry)
                self.wartosci_podane[name] = ''
                self.labels_name.append(name)
            self.obliczenia_wartosci_wg_wzorow = Obliczenia_wartosci_wg_wzorow()

    def trace_dla_str_var_entry(self, *args):

        for name in self.labels_name:
            self.wartosci_podane[name] = ''
            self.widzety.str_var_labels[name].set('')
            self.widzety.entries[name].configure(state='normal')

        for name, blokady in self.widzety.blokady.items():
            for blokada in blokady:
                if self.widzety.entries[name].get() != '':
                    self.widzety.entries[blokada].configure(state='disabled')

        for name, str_var in self.widzety.str_var_entries.items():

            try:
                war = float(str_var.get().replace(',', '.').strip())
                if name in self.widzety.ograniczenia_dla_wart_pod.keys():
                    try:
                        war = float(str_var.get().replace(',', '.').strip())
                        if war > self.widzety.ograniczenia_dla_wart_pod[name]:
                            war = self.widzety.ograniczenia_dla_wart_pod[name]
                    except:
                        war = -1.0
            except:
                war = -1.0

            if war > 0.1:
                self.wartosci_podane[name] = str(war)
                self.widzety.str_var_labels[name].set(str(war))
            else:
                self.wartosci_podane[name] = ''
                self.widzety.str_var_labels[name].set('')

        do_wyswietlenia = self.obliczenia_wartosci_wg_wzorow(wartosci_pod=self.wartosci_podane,
                                                             uklad=self.dane_dla_zakladki)

        for name, value in do_wyswietlenia.items():
            self.widzety.str_var_labels[name].set(value)
class Tab(ttk.Frame):
    def __init__(self, master=None, tab_name="", subtabs={}, **kwargs):
        super().__init__(master, **kwargs)
        self.sub_notebook = ttk.Notebook(self)
        self.sub_notebook.pack(expand=1, fill="both")
        self.add_subtabs(subtabs)
        self.master.add(self, text=tab_name)

    def add_subtabs(self, subtabs):
        for subtab_name, subtab_value in subtabs.items():
            subtab = SubTab(self.sub_notebook,name_zakladki=subtab_name, dane_dla_zakladki=subtab_value)
            self.sub_notebook.add(subtab, text=subtab_name)

class Obliczenia_wartosci_wg_wzorow:
    def __call__(self, wartosci_pod, uklad):


        self.wartosci_pod = wartosci_pod
        self.uklad = uklad
        self.nazwy_labeli = []
        self.labele_i_ich_wzory = {}


        for rodzaj_widzetu, dane in uklad.items():
            if rodzaj_widzetu == 'label':
                for nazwa, tekst, col, r, wzor in dane:
                    self.nazwy_labeli.append(nazwa)
                    self.labele_i_ich_wzory[nazwa] = wzor


        for nazwa, wzory in self.labele_i_ich_wzory.items():
            if self.wartosci_pod[nazwa] == '':
                if len(self.labele_i_ich_wzory[nazwa])>1:
                    self.obliczenia_dla_kilku_wzorow(nazwa)
                else:
                    self.obliczenia_dla_jednego_wzoru(nazwa)

        return self.przygotuj_do_wyswietlenia(self.wartosci_pod)



    def obliczenia_dla_jednego_wzoru(self,co):
        lista_slow = self.slowa_w_stringu(*self.labele_i_ich_wzory[co])
        #logging.debug(f'{lista_slow=}')
        kontynuuj = False
        for slowo in lista_slow:
            if self.wartosci_pod[slowo] == '':
                kontynuuj = False
                break
            else:
                kontynuuj = True

        if kontynuuj:

            #logging.debug(f'{co=}, {self.wartosci_pod}, wzor = {self.labele_i_ich_wzory[co]}')
            wartosci_pod_float = self.wartosci_na_float(self.wartosci_pod)
            self.wartosci_pod[co] = str(self.oblicz_wyrazenie(*self.labele_i_ich_wzory[co], wartosci_pod_float))


    def obliczenia_dla_kilku_wzorow(self, co):
        lista_wynikow =[]
        self.lista_wzorow = self.labele_i_ich_wzory[co]

        for wzor in self.lista_wzorow:
            lista_slow = self.slowa_w_stringu(wzor)
            #logging.debug(f'{lista_slow=}')
            kontynuuj = False
            for slowo in lista_slow:
                if self.wartosci_pod[slowo] == '':
                    kontynuuj = False
                    break
                else:
                    kontynuuj = True

            if kontynuuj:
                lista_wynikow.append(self.oblicz_wyrazenie(wzor, self.wartosci_na_float(self.wartosci_pod)))

        if len(lista_wynikow) >1:
            wynikk = self.czy_wyniki_roznia_sie_miedzy_soba(lista_wynikow)
            self.wartosci_pod[co] = wynikk
        elif len(lista_wynikow) ==1:
            self.wartosci_pod[co] = lista_wynikow[0]

    def czy_wyniki_roznia_sie_miedzy_soba(self,lista_float):

        srednia = (sum(lista_float))/(len(lista_float))
        delta = srednia*0.05
        min_val = srednia-delta
        max_val = srednia+delta

        for wart in lista_float:
            if wart > max_val or wart < min_val:
                return '-999'

        return str(srednia)

    def przygotuj_do_wyswietlenia(self, slownik):
        for klucz, wart in slownik.items():
            if wart == '':
                pass
            elif isinstance(wart, str):
                try:
                    slownik[klucz] = str(round(float(wart), 4))
                except ValueError:
                    slownik[klucz] = ''
            elif isinstance(wart, float):
                slownik[klucz] = str(round(wart, 4))
        return slownik

    def wartosci_na_float(self,slownik):

        for klucz, wartosc in slownik.items():
            if wartosc == '':
                pass
            else:
                slownik[klucz] = float(wartosc)
        return slownik

    def slowa_w_stringu(self, wzor_string):
        lista = []
        for slowo in self.nazwy_labeli:
            if slowo in wzor_string:
                lista.append(slowo)
        return lista


    def oblicz_wyrazenie(self, wyrazenie222, wartosci222):
        drzewo = ast.parse(wyrazenie222, mode='eval')

        def odwiedz(node):
            if isinstance(node, ast.Name):
                return wartosci222[node.id]
            elif isinstance(node, ast.Constant):
                return node.value
            elif isinstance(node, ast.BinOp):
                left = odwiedz(node.left)
                right = odwiedz(node.right)
                if isinstance(node.op, ast.Add):
                    return left + right
                elif isinstance(node.op, ast.Sub):
                    return left - right
                elif isinstance(node.op, ast.Mult):
                    return left * right
                elif isinstance(node.op, ast.Div):
                    return left / right
            else:
                raise ValueError("Nieobsługiwany typ węzła")

        return odwiedz(drzewo.body)

class Tab_armatura(ttk.Frame):
    def __init__(self, master=None):
        super().__init__(master)

        self.frame_iso = tk.Frame(self)
        rows = [
            ["ISO", '10', '13,5', '17,2', '21,3', '26,9', '33,7', '42,4', '48,3', '60,3', '76,1', '88,9', '114,3'],
            ["Cale", '1/8"', '1/3"', '3/8"', '1/2"', '3/4"', '1"', '1 1/4"', '1 1/2"', '2"', '2 1/2"', '3"', '4"']
        ]

        for row, data_row in enumerate(rows):
            for col, value in enumerate(data_row):
                label = tk.Label(self.frame_iso, text=value, borderwidth=1, relief="solid", width=7)
                label.grid(row=row, column=col)
                if col % 2 == 0:
                    label.configure(bg='yellow')
                else:
                    label.configure(bg="#EFEF00")

        self.frame_iso.grid(column=0, row=0, padx=10, pady=10)


class App(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Materialy")
        self.minsize(705, 550)

        logging.basicConfig(level=logging.DEBUG,  # filename="Materialy_log.log",
                            format='%(asctime)s - %(levelname)s - %(message)s')
        logging.debug("-------------Rozpoczęcie programu------------------")  # debug,info,warning,critical

        self.notebook = ttk.Notebook(self)
        self.notebook.pack(expand=1, fill="both")

        self.style = ttk.Style()
        self.style.configure("TNotebook.Tab", padding=(10, 5), font=("Helvetica", 10))

    def add_tab(self, tab_name, subtabs):
        tab = Tab(self.notebook, tab_name=tab_name, subtabs=subtabs)
        self.notebook.add(tab)

    def run(self, uklad_zakladek):
        for tab_name, subtabs in uklad_zakladek.items():
            self.add_tab(tab_name, subtabs)
        self.mainloop()

class WstawWidzety(ttk.Frame):
    def __init__(self, master, uklad, obraz=None):
        super().__init__(master)
        self.obraz=obraz
        self.labels = {}
        self.entries = {}
        self.blokady = {}
        self.str_var_entries = {}
        self.str_var_labels = {}
        self.ograniczenia_dla_wart_pod = {}

        for rodzaj_widzetu, dane in uklad.items():
            if rodzaj_widzetu == 'label':
                for nazwa, tekst, col, r, _ in dane:
                    varl = tk.StringVar()
                    lbl = ttk.Label(self, text=tekst, textvariable=varl)
                    lbl.grid(row=r, column=col, padx=5, pady=5, sticky='news')
                    self.labels[nazwa] = lbl
                    self.str_var_labels[nazwa] = varl

            if rodzaj_widzetu == 'label_opisowy':
                for tekst, col, r in dane:
                    lbl = tk.Label(self, text=tekst, bg='lightgrey')
                    lbl.grid(row=r, column=col, padx=5, pady=5, columnspan=3, sticky='news')
                    self.columnconfigure(index=(0,2,3,4,6),uniform='a')

            if rodzaj_widzetu == 'entry':
                for nazwa, tekst, col, r in dane:
                    var = tk.StringVar()
                    entry = ttk.Entry(self, textvariable=var)
                    entry.grid(row=r, column=col, padx=5, pady=5)
                    self.entries[nazwa] = entry
                    self.str_var_entries[nazwa] = var

            if rodzaj_widzetu == 'blokady':
                for nazwa, blokowane in dane:
                    self.blokady[nazwa] = blokowane

            if rodzaj_widzetu == 'ograniczenie_max_dla_wartosci_podawanej':
                for nazwa, max_val in dane:
                    self.ograniczenia_dla_wart_pod[nazwa]=max_val

            if obraz is not None:
                self.canvas_obraz = tk.Canvas(self, width=400, height=150)
                self.canvas_obraz.place(relx=0.5, rely=0.95, anchor='center')
                self.image_blachy = tk.PhotoImage(data=self.obraz)
                self.image_blachy = self.image_blachy.subsample(2, 2)
                self.canvas_obraz.create_image(0, 0, anchor="nw", image=self.image_blachy)

class C:
    uklad_dla_arkusz = {
        'label_opisowy': [
            ('Długość [mm]', 0, 0),
            ('Szerokość [mm]', 0, 2),
            ('Grubość [mm]', 0, 4),
            ('Powierzchnia [m2]', 0, 6),
            ('Gęstość jednostkowa [kg/m3]', 0, 8),
            ('Masa 1m2 [kg]', 4, 0),
            ('Masa dla podanych wymiarów [kg]', 4, 2),
            ('Cena za 1m2 [zł]', 4, 4),
            ('Cena za 1kg [zł]', 4, 6),
            ('Cena dla podanych wymiarów [zł]', 4, 8)
        ],
        'entry': [
            ('dlugosc', '0', 0, 1),
            ('szerokosc', '0', 0, 3),
            ('grubosc', '0', 0, 5),
            ('powierzchnia', '0', 0, 7),
            ('g_jednostkowa', '0', 0, 9),
            ('masa_1m2', '0', 4, 1),
            ('masa_pod', '0', 4, 3),
            ('cena_1m2', '0', 4, 5),
            ('cena_1kg', '0', 4, 7),
            ('cena_pod', '0', 4, 9)
        ],
        'label': [
            ('dlugosc', '', 2, 1, ["powierzchnia/(szerokosc/1000)"]),
            ('szerokosc', '', 2, 3, ["powierzchnia/(dlugosc/1000)"]),
            ('grubosc', '', 2, 5, ["masa_1m2*(dlugosc/1000)"]),
            ('powierzchnia', '', 2, 7, ["(dlugosc*szerokosc)/1000000"]),
            ('g_jednostkowa', '', 2, 9,["masa_1m2/(grubosc/1000)", "(masa_pod/((dlugosc/1000)*(szerokosc/1000)))/(grubosc/1000)"]),
            ('masa_1m2', '', 6, 1, ["masa_pod/((dlugosc/1000)*(szerokosc/1000))","(grubosc/1000)*g_jednostkowa"]),
            ('masa_pod', '', 6, 3, ["masa_1m2*(dlugosc/1000)*(szerokosc/1000)","(dlugosc/1000)*(szerokosc/1000)*(grubosc/1000)*g_jednostkowa"]),
            ('cena_1m2', '', 6, 5, ["masa_1m2*cena_1kg","cena_pod/powierzchnia"]),
            ('cena_1kg', '', 6, 7, ["cena_1m2/masa_1m2", "cena_pod/masa_pod"]),
            ('cena_pod', '', 6, 9, ["cena_1m2*powierzchnia","cena_1kg*masa_pod"])
        ],
        'blokady': [
            ('g_jednostkowa',['masa_1m2','masa_pod']),
            ('masa_1m2',['masa_pod','g_jednostkowa']),
            ('masa_pod',['masa_1m2','g_jednostkowa']),
            ('cena_1m2',['cena_1kg','cena_pod']),
            ('cena_1kg',['cena_1m2','cena_pod']),
            ('dlugosc', ['powierzchnia']),
            ('szerokosc', ['powierzchnia']),
            ('cena_pod',['cena_1m2', 'cena_1kg'])
        ],
        'ograniczenie_max_dla_wartosci_podawanej': [
            #('cena_pod',15)
        ]
    }

    uklad_dla_arkusz_perforowany = {
        'label_opisowy': [
            ('Długość [mm]', 0, 0),
            ('Szerokość [mm]', 0, 2),
            ('Grubość [mm]', 0, 4),
            ('Prześwit [%]', 0, 6),
            ('Powierzchnia z otworami [m2]', 0, 8),
            ('Gęstość jednostkowa [kg/m3]', 0, 10),
            ('Masa 1m2 [kg]', 4, 0),
            ('Masa dla podanych wymiarów [kg]', 4, 2),
            ('Cena za 1m2 [zł]', 4, 4),
            ('Cena za 1kg [zł]', 4, 6),
            ('Cena dla podanych wymiarów [zł]', 4, 8)
        ],
        'entry': [

            ('dlugosc', '0', 0, 1),
            ('szerokosc', '0', 0, 3),
            ('grubosc', '0', 0, 5),
            ('przeswit', '0', 0, 7),
            ('powierzchnia', '0', 0, 9),
            ('g_jednostkowa', '0', 0, 11),
            ('masa_1m2', '0', 4, 1),
            ('masa_pod', '0', 4, 3),
            ('cena_1m2', '0', 4, 5),
            ('cena_1kg', '0', 4, 7),
            ('cena_pod', '0', 4, 9)
        ],
        'label': [
            ('dlugosc', '', 2, 1, ["powierzchnia/(szerokosc/1000)"]),
            ('szerokosc', '', 2, 3, ["powierzchnia/(dlugosc/1000)"]),
            ('grubosc', '', 2, 5, ["masa_1m2*(dlugosc/1000)"]),
            ('przeswit','',2,7,[""]),
            ('powierzchnia', '', 2, 9, ["(dlugosc*szerokosc)/1000000"]),
            ('g_jednostkowa', '', 2, 11,["masa_1m2/(grubosc/1000)", "(masa_pod/((dlugosc/1000)*(szerokosc/1000)))/(grubosc/1000)"]),
            ('masa_1m2', '', 6, 1, ["masa_pod/((dlugosc/1000)*(szerokosc/1000))","(grubosc/1000)*g_jednostkowa"]),
            ('masa_pod', '', 6, 3, ["masa_1m2*(dlugosc/1000)*(szerokosc/1000)","(dlugosc/1000)*(szerokosc/1000)*(grubosc/1000)*g_jednostkowa"]),
            ('cena_1m2', '', 6, 5, ["masa_1m2*cena_1kg","cena_pod/powierzchnia"]),
            ('cena_1kg', '', 6, 7, ["cena_1m2/masa_1m2", "cena_pod/masa_pod"]),
            ('cena_pod', '', 6, 9, ["cena_1m2*powierzchnia","cena_1kg*masa_pod"])
        ],
        'blokady': [
            ('g_jednostkowa',['masa_1m2','masa_pod']),
            ('masa_1m2',['masa_pod','g_jednostkowa']),
            ('masa_pod',['masa_1m2','g_jednostkowa']),
            ('cena_1m2',['cena_1kg','cena_pod']),
            ('cena_1kg',['cena_1m2','cena_pod']),
            ('dlugosc', ['powierzchnia']),
            ('szerokosc', ['powierzchnia']),
            ('cena_pod',['cena_1m2', 'cena_1kg'])
        ],
        'ograniczenie_max_dla_wartosci_podawanej': [
            ('przeswit', 99)

        ]
    }

class Uklad_zakladek:
    uklad_zakladek = {
        'Materiały długościowe': {
            'Pręt': C.uklad_dla_arkusz,
            'Rura': C.uklad_dla_arkusz,
            'Płaskownik': C.uklad_dla_arkusz,
            'Kształtownik': C.uklad_dla_arkusz,
            'Kątownik': C.uklad_dla_arkusz,
            'Ceownik': C.uklad_dla_arkusz
        },
        'Materiały powierzchniowe': {
            'Arkusz': C.uklad_dla_arkusz,
            'Arkusz perforowany': C.uklad_dla_arkusz_perforowany
        },
        'Inne': {
            'Armatura': C.uklad_dla_arkusz
        }
    }

class KodowaneObrazy:
    img ={
    'Arkusz' : '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',

    'Rura' : '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',

    'Pręt' : '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',

    'Ceownik' : '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',

    'Kształtownik' : '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',

    'Kątownik' : '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',

    'Arkusz perforowany' : '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',

    'Płaskownik' : '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'
    }

if __name__ == "__main__":
    app = App()
    app.run(Uklad_zakladek.uklad_zakladek)

0

To jest bardzo ogólne pytanie xD nie chce mi sie troche wszystkiego pisać , ale np w piewszej wersji masz zakładkę pret i tam jest field średnica natomiast w ostatniej wersji nie masz jej i brakuje tego fielda. Ja nie czuję się na tyle doświadczony w GUI aplikacjach aby Ci wypisać wszystko. Nie przerobiłem też dużej ilości przypadków, aby wyłapać wszystkie "code smells" do poprawy i żeby było jak najmniej frustracji związanej z kodem, gdy wrócimy do niego za rok i dodamy nowy feature xD. Z drugiej strony fajnie byłoby dodadać gdzieś swieżutka liste comprehention, albo jakiś dekorator (oczywiście tam gdzie to pasuje wstawić ^^).

Ogólnie rzecz biorąc, poprawa jest zauważalna. Z 2500 linii kodu zostało teraz tylko 500. Jeśli aplikacja działa tak, jak założyłeś, to jest to już sukces. Ciężko jest mi napisać coś konkretnego dotyczącego poprawy, ponieważ zależy to również od Twoich wymagań dotyczących projektu, na przykład, czy chcesz dodawać jakieś funkcje typu wydrukuj raport, badz export do excela albo csv, czy tylko ty będziesz edytować kod. Każde z rozwiązań mają swoje wady i zalety, a od nas zależy, które z nich wybierzemy.

Refaktoryzacja i "code smells" fajnie to tłumaczy na kanale "arjancodes" na YouTube. Są też inne materiały, ale ten mi się rzucił w oczy. Są też polskie napisy na tym kanale.

Już nie wnikałem w ten kod, ponieważ to sporo czasu zajmie, aby rozłożyć to wszystko na czynniki,przeanalizować rozwiazanie , a potem zaproponować jakieś rozwiązania oraz sprawdzić, czy kod jest dobrze rozplanowany. Jak już kod masz skrócony to możesz jeszcze poeksperymentować.

Zastanawiam się, czy wrzucić zrefaktorowany przykład (jak bede miał czas to wrzucę na github), ale mi się wydaje, że najlepiej zrobić coś takiego jak pair programming, bo będziesz miał wtedy orientację, dlaczego to jest tak napisane. Może wtedy byś wpadł na jakis bardzo dobry pomysł. Czasem krok po kroku dochodzi się do rozwiązania. i wtedy dobrze byłoby też rozwiazanie skonsultować np. bo widze że oprócz obliczeń ze wzorów liczysz średnia, a nie bardzo wiem dlaczego. Z drugiej strony to nie jest jakiś program do ksiegowosci, tylko jakis rozszerzony kalkulator, wiec pewnie po przeanalizowaniu kodu by było wiadomo o co chodzi.

W skrócie możesz wykorzystać:

  • pair programming,
  • może jakiś mentor,
  • może jakiś Discord, no i forum (ale nie wiem czy to jest odpowiedni dział do tego XD)
  • jakieś narzędzia
  • oczywiscie chat

wymienię tylko przykładowe z narzedzi co moga ci pomóc (ale nie musisz korzystać z nich) to np. pylint, sonarint, ruff (napisany w ruscie) lub flake8 (framework do implementowania własnych kontroli w Pythonie przy użyciu ast ), mypy, pyright / pylance lub pyre, black i isort (automatyczne formatowanie), autoflake (automatyczne usuwanie nieużywanych importów lub zmiennych) i mase innych xD

Tak na szybko np dla wiekszej czytelności możesz rozbić metode trace_dla_str_var_entry na odzielne metody
to samo z klassa obliczenia_wartosci_wg_wzorow.

Na sam koniec wrzuce to co udało mi sie naskrobać i przerobić z pierwszego przykładu. To jest tylko kod dla widoku no i bez widoku dla zakładki armatura. To jest bez obliczeń i eventów Nigdzie nie znalazłem przykładu z podzakładkami, więc wrzuce swój. Może jeszcze da się inaczej i bardziej dopasować do Twoich potrzeb ale myśle że analizujac go bedziesz wiedział o co mi chodziło. Ja zrobiłem coś podobnego do "class based view". Może to Cie nakieruje i wtedy masz zachowane wszystkie zakładki i fieldy jakie chcesz, możesz tez je dodawać. Można jeszcze to pewnie zrefaktorować używajac factory paternu i jakiś innych rzeczy, ale nie wiem czy jest sens to robić. Ogólnie to co wczesniej najlepiej to na klasa zrobić.

Nie udało mi sie wstawić świeżutkiej list comprehension... No ale daje to co mam.

screenshot-20240303194853.png


from enum import Enum
from tkinter import CENTER, ttk, Frame
import tkinter as tk


class ImageType(Enum):
    ARKUSZ = "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"
    RURA = "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"
    PRET = "iVBORw0KGgoAAAANSUhEUgAAAssAAACoCAYAAAAW96MGAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAABHtSURBVHhe7d0JcFVVnsfxH2Rjl33fURTiQFiUDuDQIDsI4wIIyCKLyrQKIiCItLQoiIjSiBv7ItI43ch0EIVR9j0IGEC2CARJaAKBACHs0O/edwKk8dRMOULeu/l+qqjc/z9lpazwuL933rn/kyM1NfWaAAAAANwip/kKAAAA4F8QlgEAAAALwjIAAABgQVgGAAAALAjLAAAAgAVhGQAAALAgLAMAAAAWhGUAAADAgrAMAAAAWBCWAQAAAAvCMgAAAGBBWAYAAAAsCMsAAACABWEZAAAAsCAsAwAAABaEZQAAAMCCsAwAAABYEJYBAAAAC8IyAAAAYEFYBgAAACwIywAAAIAFYRkAAACwICwDAAAAFoRlAAAAwIKwDAAAAFgQlgEAAAALwjIAAABgQVgGAAAALAjLAAAAgAVhGQAAALAgLAMAAAAWhGUAAADAgrAMAAAAWBCWAQAAAAvCMgAAAGBBWAYAAAAsCMsAAACABWEZAAAAsCAsAwAAABaEZQAAAMCCsAwAAABYEJYBAAAAC8IyAAAAYEFYBgAAACwIywAAAIAFYRkAAACwICwDAAAAFoRlAAAAwIKwDAAAAFgQlgEAAAALwjIAAABgQVgGAAAALAjLAAAAgAVhGQAAALDIkZqaes1cwwMuX76s9PR093rRokU6fPiwTp48qfnz57s9AACyuz59+qhChQpq27atcufOrfDwcPMd4FaEZQ84cOCATp8+rcmTJ7vheOXKleY7AABkX2GhoYqsXFkpp07p56NHTTezqKgoRUZG6oknnlCjRo2UMycfuiMzwnKQOup70U+dOlXr1q3Tzp075fs9mu9k1uJ30cqTK5epbvhm/Xqdu3DeVLeqUqasBnTuosgqVUwHAIDgEhEWrgfvv19HU45r76FDpiu9//lcLVqzWteuZY5ATZs21cCBAxUdHa0cOXKYLrI7wnKQuXjxot5++23NmjVLKSkppiuFhoSoyF13qWur1qp9731qUDPK7ZcuWlQhvu/9qyPHj+vylSvan3hYX61do+Wxsdqx/yd3G0fGX4j8efLqscaN9VrvvipbvLj7Dh0AgGB35epVJR07pp2++96b06cpdsd2XTHBOSIiQkV9984BAwaod+/erDSDsBwsjvle1J999pnGjx+vtLQ005WKFy6snm0f0bCevXzhNo/p/nozF8Vo1LQpSjhyxHT8IsLD9eP8v6pCqVKmAwCANyzduF5vTpumDdvjdPWm1eaHH35YQ4YM0QMPPEBozsYIywHu+PHjmj17tqZPn+7uR85QvFBh9WrfXs8++rjKlShhur+NtPR0zV78lSb913ztTUgwXSmfL4x3b91Wz3fsqKrlK5guAADesHDlcr3ju+fG7txx/VNWR4cOHfTpp58SmLMpwnIAO3jwoFq1aqUjN63yOi/UoT2e1nOPPa7SxYqZ7u1x4vRpffE/SzVm5nQlHjtmulLhAgX00SvD9MTDTU0HAABvSD9/Xks2rNfoGdO1dc9utxcaGqr69etr8ODBatiwIfuZs5mQoUOHjjTXCCDvvvuuunfv7k65yND3Px7V4gkfqE2DhsqfN6/p3j65IyJUt3p1vdDpSRUvVEhfr1/n9s9duKAvVyzXbl+Yb1qvnnIxcgcA4BHO8znVKlZStUqV3C2JSceSdenyZSUkJCguLk4lS5ZUuXLlFBYWZv4LeB1hOQCNHTtWEyZM0AVfKHWUKV5cL3XuosHduqtYwUJu705yVrNrV6vmPuS3PzFRx1JPuk8QOw9G/Lh/v+4pX16li97eVW4AAO6kCiVLqXubtjqQlKTt8fHufc95fmjBggXubOaaNWsynzmbYBtGgHnvvffcPxkP8Tn7kd9+/kV1atbcrbPalt271e/t0fp+9y7TkRuiZ7z+JzWuU9d0AADwju4j/6h5S77JNGrOGd1avXp1U8HL2KkeIC5duqSJEye6Y+EygnLRggU1NoCCsqP2ffdpwsBBvq/VTEc6nJysCfPmuvu8AADwmkmDX1HPNo9k2qvcrFkz98wDeB/bMALAeV/IdA4YGTFihK5cueL2QnLm1NxRb+nRxk3cOpA4q9017rlH6+LidNwchrLv0CE3NDesGfWLh6AAABCsnPGp9SLv18kzZ7Rt71635yxyffHFF2revLk7lxneRVjOYs5HOlOmTNHw4cNNx++L0WPVvlEjUwUeZ+tFo9p19Lfvvru+ohy3b59Onz2rB33/oOTNndvtAQDgBc741AcjI/WP48fdQ7wcZ333vL2+8NypUycmZHgY2zCyWHp6ul599VVT+c17c7TaBXBQzuCct79p1hxT+U3+coG27dlzyxGiAAAEuxKFi6hLy1aqWq686UgbNmzQyJEjue95GGE5izVo0MBc+XVu0VL1a9Z0t2EEg1JFi2pE776m8ms14AX3OG0AALymRXR9tfhdtHJFRLj1xYsXdejQIaWkpLg1vIewnIViY2PdleWb1a9RU2WKFTdV4AsNCXGP265b7cYDf47lm2PNFQAA3vLewJd1d7lyppIWLlyoefPmsbrsUYTlLDRmzBglJyebSr7Q2U5dW7YyVfCoUKqUXune01R+/caOMVcAAHhPlxYt3QWjDM7Y1+XLlxOYPYiwnEUGDRqkZcuWmUqqXrmKerRpqwJ34GS+28GZjtH2oYdM5T8utPZTXUwFAIC3DOnWQ5XKlDGVdPLkSR08eNCdkgFvISxngcOHDyspKclUfpVKl9ZDtWqZKvhUKVvOfZddutiNk/zS0tPdU48AAPCiJRM/dE+5zTBw4EDFc9/zHMJyFoiJidHixYtNJVUsXUYfDBpiquDVsWlztYyubyppf1KiRk2bYioAAIDgQ1gOABFhYSpfsqSpAABAMCiYP796PdIu04zljz/+mK0YHkNYvsNSU1OVkJBgKsl5eUVVvddfeMAzjz6mahUrmUratHOH/rJ0iakAAPAO5zmjTs1bZArLc+bMuX4aL7yBsHyHbdy4UZ988ompfL8A91jrN00V/OpWq65ihQqZSu4R2HHx+0wFAAAQXAjLAAAAv5IzPi7jgJIMaWlp5gpeQFjGb+7usuUUFhpqKin5xAmdOHXKVAAAeMdDUbU0vv9LynnTVozGjRvr6tWrpkKwIyzfQc47zU2bNpnKb84bo8yVd0we/lqmrRgzF8Vo4coVpgIAAAgehOU76MiRIxo/fryp/B6oHmmuAAAAEGgIywAAAIAFYRkAAACwICwDAAAAFoRlAAAAwIKwDAAAAFgQlgEAAH6lI8ePa/32OF0ztWPu3LnuCb3wBn6Td1CVKlU0Y8YMU/nV7f6UufKOGTF/15mzZ00l9e/cRU+1bmMqAAC8Y3fCQX329WJdu3YjLletWtVcwQsIy3eQ8y4zT548pvJLS083V94xZ/FXOnPT/1dEWJjCbzrRDwAAIFgQlgEAAAALwvIdFhISorCwMFPJ/dhm6sIvTRX8Ll66lOk8/JCcORXGqjIAwIMSk5PVefiwTPe9mJgYRUREmApeQFi+w5o2bao33njDVNJVX1h+f97npgp+z48bqzU/bDOV1L7R7/WnZ54zFQAA3nHFF5JPnD5tKr8iRYooR44cpoIXEJYBAAB+hRXff+98RGwqqVatWsqXL5+p4BWE5SxQo0YNRUZGmkran3hYz4x5y1TB6/vdu7Rz/35TSUULFlTrBg1MBQCAt/zhnTHuJ8QZXn75ZZUrV85U8ArCchZo4AuQ0dHRppIuXb6sA4mJSjl1ynSCz9lz5/TX777Vxh3bTUcqXbSYerZtZyoAALwj6qnOOnfhgqmk1q1buwthbMHwHsJyFunVq5e7wpxh+eZYjZ4x3VTBZ+mG9Ro3Z7appIjwcE0YOMhUAAB4R1z8Pp1NP2cqqXTp0urQoYMqVqxoOvASwnIWqV69ujp37qz8+fObjrTjp3j9eOCAqYKH83DDt7GbTOXXuXkL/Xvt2qYCAMA7Rk2ZooNHkkwlNW/eXO3bt2dV2aMIy1moX79+7lOzGb7zBc6Y1avc8WvBwhl9F7dvrz5d8DfT8Xvj2X7mCgAA7xjxyUeKWbPq+ol9lSpVUps2bQjKHkZYzmJjxowxV37DP5qkVVu3mCrwnb94UU3/kDkYj+jdV4UKFDAVAADesGxzrBauWK7LV664dXh4uJo1a+aOhSUsexdhOYu1aNFCrVq1MpXfi++O05Fjx0wV2DoMHWKu/Ordf786NWuu3AxkBwB4yJZdu/Ts6De16+BB05F69OihsWPHEpQ9LkdqauqNmSfIEikpKRo8eLAWLFhgOv6xa/Ff/rfy5c5jOoHFeQK406tD9c36dddPLoquUVN/HjhIte+7z60BAPCCPQkJatDnaaWeOWM6Ut68efXTTz8pV65cpgOvYmU5ADj7lkeNGqXHH3/cdKTjqamK6tpZB5ISTSdwJJ84oW6vj9DitWuuB+W78uVTh4ebEpQBAJ6yJ+Gg6nTvmikoV6hQQatXryYoZxOE5QBRpkwZNzA7DwlkOJiU5J45vz0+3nSyXtKxYxrywZ/dPVsZCviC8rCeT+vFTk+aDgAAwW/Tju1q3f9Fnb9pnrIzzWrq1Knug33IHtiGEWB8vw9169ZNa9asuf6k7UO1amn8gIGqVfXeLN0X9Y+UFL364STNXrzIdKRc4eEa9dx/6qUuXU0HAIDgdvXaVY2ZNVNjZ85Q+vnzbs+5/3bs2FHjxo1TAR5iz1YIywGqXbt2WrVqlan8pr72R3Vt2UphoaGmc+fsOnBA/9a5o6n8ypYooY0zZqlE4Rvj7wAACFbOlIvV27bqrenTtHLL99cXrQoWLKhJkyYxIi6bIiwHKOcFOnv2bPXv3990/H5fp65G9n1WDaOiTOf22rl/vybOn6e5Xy92x8RlcLZcvNa7rwrz7hoA4BF/WbpE3V8foasmJDvq1aunYcOGqVGjRgTlbIqwHMAu+sKps7rsfOSzceNG05XCw8L09CPt9OGQoaZze2zbu0f93x2ntXE/mI5UuUwZDevZS481buI+1AcAQDDbuH273po5TfE/H9a+nw9dX012vPPOO+54uAjGoWZrhOUg4EycWLFihTtezhlT43De3YaGhLgrzc4hIA9GRrr1/9fPR49q5ORP9fmSr92fe8VMu3B+XpO6D2jxhIkK+Q1+DgAAWeFoSopOnDmjmYv+rh3x8fo2dpOumENGnPtbyZIl3Yf4hgwZojp16ihnTmYhZHeE5SCyfv16JScna8KECdq6davp+rWIjlbZ4sXVtWVr39cS7grw/0XKqVR3q8XyzbHa4QviztxkZ4ZyhnvKl1epIkXVp/2j6tKypekCABD41v6wzV30ybjPOavGyzZv1qm0G2PgMkRFRWno0KHuYWFst8DNCMtB6IIvzC5dulTvv/++tmy59Wjs4oUKqXSxYu51z7btlD/vrQebzIiJUVr6Wd8/GGk6kJRkupk5M5OfbN5CRe66y3QAAMhaScnHtGDFskzbJWzi9sW7ky1s7r77br3wwguqVauWqlatytxk/CLCchBz9jSfP39eixYtco/bPHPmjNtL8wVgAADg5+w5btKkiRuKHX369FFoaKjCw8MJyPhfEZY9JjExUWvXrnWvY2Ji3BoAgKzUq1cvN5hmlcqVK7v7j9legV+DsAwAAABY8IgnAAAAYEFYBgAAACwIywAAAIAFYRkAAACwICwDAAAAFoRlAAAAwIKwDAAAAFgQlgEAAAALwjIAAABgQVgGAAAALAjLAAAAgAVhGQAAALAgLAMAAAAWhGUAAADAgrAMAAAAWBCWAQAAAAvCMgAAAGBBWAYAAAAsCMsAAACABWEZAAAAsCAsAwAAABaEZQAAAMCCsAwAAABYEJYBAAAAC8IyAAAAYEFYBgAAACwIywAAAIAFYRkAAACwICwDAAAAFoRlAAAAwIKwDAAAAFgQlgEAAAALwjIAAABgQVgGAAAALAjLAAAAgAVhGQAAALAgLAMAAAAWhGUAAADAgrAMAAAAWBCWAQAAAAvCMgAAAGBBWAYAAAAsCMsAAACABWEZAAAAsCAsAwAAABaEZQAAAMCCsAwAAABYEJYBAAAAC8IyAAAAYEFYBgAAACwIywAAAIAFYRkAAACwICwDAAAAFoRlAAAA4BdJ/wRTcSDE1KFzYwAAAABJRU5ErkJggg=="
    CEOWNIK = "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"
    KSZTALTOWNIK = "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"
    KATOWNIK = "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"
    ARKUSZ_PERFOROWANY = "iVBORw0KGgoAAAANSUhEUgAAAssAAACoCAYAAAAW96MGAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAAxYSURBVHhe7ds9lty4FYDR0aROtAqHdub9x87s0KvoxLFGPOo6oigCVUUSxHvAvYkqbBJ/X6FbXz4+Pr79AQAA/ObPz38BAIANsQwAAAViGQAACsQyAAAUiGUAACgQywAAUCCWAQCgQCwDAECBWAYAgAKxDAAABWIZAAAKxDIAABSIZQAAKBDLAABQIJYBAKBALAMAQIFYBgCAArEMAAAFYhkAAArEMgAAFIhlAAAoEMsAAFDw5ePj49vnZwA6+fr16+en333fpz8/AXA3sQxwg1oMnyWmAdoRywAXaRnERwlpgHPEMsCLIsbwWWIaoE4sA6yMGMRHCWkAsQxMJmoM//d/5a34H3//8vkpFjENzEAsA8PJGMRHCWmAtsQykM5MMXyWmAY4RywDIQni9oQ0wHNiGehCDMcnpgHEMtCQIB6XkAZmIZaBw8QwJWIaGIVYBqoiBrEYzk1IA5mIZZic22GiEdNAJGIZJuB2uKxFmAn9doQ0cDexDANwO1xXC6x//+f/n5+u869//u3z0++EdFtiGriaWIYk3A6/Zx1NLYL4qHVIt35/bs1/JaSBI8QyBOF2+DpLFEUK5JIlnM++31oAujV/j5gG9ohluJHb4fayhPLDkWBeR92st+Z3E9IwL7EMF3I7HEOWYD4ayrPcmmcipmFcYhneIIbz2MZLlMA8c/uaJZQfZgvmEiENuYll2BDEYyoFS4v4XAfx1tlxzBLMvUK5RZi2fg4xDbGJZaYjhlkbIa5GuDV/R23Msn35eUZIQ39imSEJYmZSCqqRwnH9jJFu1u/6glAipqE9sUxKM8Zwi0NRvI9tlDmzPIc/PXmfkIZriGXCEsS/Gu3Xy/CKLKH8EC2Ya8Q0vEYs040/lfhhfWD59TL8LkswZwrlZ4Q0/CSWaUoQ14kAeM023qKsm1m/VIppZiKWOUUMH5cllB8EM5GUYq3FmloH8ZY18TshzWjEMk8J4nayBPPVodziMBUtLMyt+MQ02YhlxHBn24NjlF8v1w5Et3/AHiFNRGJ5EoI4j9JhkSEw1z97pBvzs+H/ihaHvPXBVUaZn2KaHsTyIMTw+KIfdsvPN/qflNTGwG05vc0+P4U0rYjlRAQxUWUJ5Yd3gnl9AM92W0585ufrxDRHieVAxDCZZQnmd0N5tGe6WosAsee8xvy8jpCmRizfLGIQj3owOcTvt33nUQ7yI7dcWULkoWWQ1NZSi3e0Hq8ta/AH8/NeLc6TK4jpe4jli7kdvpdDPLbS+GQZmyxB0iJE1mMX6R2sx3n2NTfz/Iykdg71JKSvI5YPcDvcl0M8vxaHS6t3vv1Zo8y5lvNNhJVFm7szzs9sWsyZK4jp14nlHW6H43KI01vp4GsxL9fBsdVqfmVZYw8t1lotbqKP8+jzczS1udaTkP7VtLHsdjgfhziRtTj0es2fLGvtyjW2Hr9Iz74O0jPPOtL8nEmLcbvCbDE9bCy7HR7TjIc49LA9pKOsu6vicc2+QkZC+j6pY9nt8JxmOsQhitLB3GL9rdfS1tVrK0soPwjma7QIzWjjIqavEzqW3Q7zilEP8TNmOAiIYYS5tjyDm+Xx1ObmzOfDosW6vULUkO4ay2KYlkYPRgcBXGe7nqLE83rdWWfPrccx0hegbOMopn/VPJZnCeLRw4wYHARwj9Ke7otoXMuYRdoXS5bxzjyuM4b06Vie6Xa4NkFsoLTmIID+WoSC9XJelv3xYeR9csSYfiuWo4XxHRNtPeiRFuI6pG2043MQANRl2Sdn3h+jhfSrAR06lntPJguPSMzHfS02X+sJfpVlnW1/zih7pguu17SYZzVpYjnqpMkSJg+CeQ6zHgS1DbTFO1g/z9Zd66zFoWGPoGbEdVZ6plH3jZG12BPdLF9gGZgMwSyU5zXyQbB+tkjrcP0ezj53bfN3mHOHGdbZntraO8oaOq/FuNQMEcs1d03K7cBF2UxabyQ1Npn4so/R8vNHOrhLlnX47ntZj81McUI8I68z4mpxPh01fCw/02phlQa5xYazPry2Wm8ctck82rMSS5YD/OGdg1ycEMXI64y+av0QzW2xXJu8UV9YiwXX4lnv3hjWzxBpE12HtM1yDlkO8hFD+eHOOBlh/8xoxHXGPVqs2SvU5snezxwilp/J+LJHZdMkmu3+EGV+nvnyNvM6q+33Ld7Jepy27CE/jbjOOK+2Xns6Mxf2nilFLD8TcbBGXLTLe85wgD8I5jmV9oNsobV9jpHjZP2skfYYIVY2yjrjudJY99Zq7Peed4hYrpltkFtb3meGYI4Qyi3mnoPhuOzjUfr5s8eJPWUs9r18WozZFXqN+977GD6Wn4k4SaJvDNt3FuWg63ELVJs/bli4Q4s97M71kyGUHwQzWUVsnUXE9bT3rqaP5RqT6zWl9zRqLK6fN9JB3+PLApy1rKcMwXxHKLc4c+wFc9Ar19l7l2L5hIiTM9J7HnHjX57JwQ7X2u4VUdZYiy+gtX1x1AsGrhGxORajzaO99yyWGzGpx7OMaYZQfhDMZFXaP7PG5Pp5Iu0hLb4McJxuiGFvHMRyJxEXhTF6bhm3DMEslBlRi32z9TqxZ7AW8exfGPuf9sZILAdkMcW2HZ8oB6FbIoglSyg/CObznN/5ieVBWIyxlMajxSG5DuKtXu+/xXy0XzCKZX24WR6LM3hse+MrlgdjEccxUkTWnmWWLwVw1Hb9+G1UbM7Rue2Nv1iejE2AV63nSqSbMQc82ZX2YV887+MspEQsU2Xz4GGZC351DPdqsQfPuj6cZxwlljnF5jOHLKH8IJhhTs4kWhDLNGPTGkuWYBbKMC7nCj10jeU9Jtw8bHr5bMcsSjz3/pvlFnM52jyc4RmJwdlANHtzsmssl5ikc7FZ5lAapxH/U1JtTo7yvDM8I/3Z3+ntijkolgnPZhtbi/Hp8W7XzxHpT1CuvEmf4Rm5nz2ayK6YnyFjecuEp8QmzRWWeRQpHkuWqDw6t2Z4Rtqwz5JFq7maIpZrLBZqbPI8kyUiH47E5AzPyDn2SrLoMVfTx3KNRUaNw4GHLDHpZpmj7HdkEmm+vhrKi7dieStKPG9ZpNQ4XOayHe8oYbnE48PZsZ/hGWdmzyKLqHP1nTDecyqWa4Q0GTmUxlca4xaBuY7FrZZjOsMzjsS+QyajBnFNs1h+RkyTkUNtXC3GNtq4zPCMUdk7yGLGGH6mWyw/EzGmbSo8E3GTMW+hPTFMJoL4PWFjucatNBk5TCE3a5gsxPC1UsbyM26lySji5mbeMhMxTCaC+D5DxnKNW2kycojDNawlshDDcUwXy8+4lSajiJuqeUsPYphMBHEOYvkNbqXJSDwwGnOaLMTwGMTyhdxKk1HEzdy8nZsYJhNBPD6xfBO30mQkWmjF3CILMYxYDkJMk5HgocTcIBNBTI1YTkBIk5FYGp8xJgsxzBlieQBimoyEVnzGiEwEMa2I5cEJaTISaffxrslCDNOLWJ6cmCYjgfc674pMBDERiWWKhDQZzRiHgpgsxDAZiWUOE9NklDEsxTCZCGJGI5ZpQkiTUdRDvidrhi0xzGzEMl2IaTIaMabNefYIYvhJLBOOkCajyCFt7rIlhuF1Ypl0xDQZtYwTc489ghiuIZYZipAmo1eixhxiSwzDPcQyUxHTRLYXP+bG3AQx9CeW4ZOQpjexPB8xDPGJZXiRmKY1sTwmQQy5iWW4SMSYFlq5iOWcxDCMTSzDDdxK8wqxHJcghnmJZQjArTQLsdyPGAZKxDIE51Z6HmK5LUEMHCGWITm30uMQy+eIYaAFsQwDcyudi1h+ThADdxPLMDG30rGIZTEMxCOWgV1upe83SywLYiATsQwcIqavN0osi2FgJGIZuJyQPiZTLAtiYBZiGbidmN4XKZbFMMAPYhkIZeaQvjuWBTHAc2IZSGXkmL46lsUwwHliGRhG9pA+EsuCGKAtsQxMI3pMRw3fPWIYmIVYBvguakj3JIgBxDLAS0aMaTEM8JxYBjgpckgLYoBzxDJAYy1jWgwDtCWWATp6JaQFMUA/YhkAAAr+/PwXAADYEMsAAFAglgEAoEAsAwBAgVgGAIACsQwAAAViGQAACsQyAAAUiGUAACgQywAAUCCWAQCgQCwDAECBWAYAgAKxDAAABWIZAAAKxDIAABSIZQAAKBDLAABQIJYBAKBALAMAQIFYBgCAArEMAAAFYhkAAAq+fPvu8zNASl+++/wIABf644+/ADk2ChKK/jZmAAAAAElFTkSuQmCC"
    PLASKOWNIK = "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"


class BaseTab(Frame):
 def __init__(self, parent):
        super().__init__(parent)
        # Make tab resizable
        self.grid_rowconfigure(0, weight=1)
        self.grid_columnconfigure(0, weight=1)


class Tab1(BaseTab):
    def __init__(self, parent):
        super().__init__(parent)

        # Create an inner notebook for subtabs
        self.subnotebook = ttk.Notebook(self)
        self.subnotebook.grid(row=0, column=0, sticky="nsew")

        # Add subtabs
        subtab1 = SubTab1(self.subnotebook)
        self.subnotebook.add(subtab1, text="Rura")

        subtab2 = SubTab2(self.subnotebook)
        self.subnotebook.add(subtab2, text="Pręt")

        subtab3 = SubTab3(self.subnotebook)
        self.subnotebook.add(subtab3, text="Płaskownik")

        subtab4 = SubTab4(self.subnotebook)
        self.subnotebook.add(subtab4, text="Kształtownik")

        subtab5 = SubTab5(self.subnotebook)
        self.subnotebook.add(subtab5, text="Katownik")

        subtab6 = SubTab6(self.subnotebook)
        self.subnotebook.add(subtab6, text="Ceownik")


class Tab2(BaseTab):
    def __init__(self, parent):
        super().__init__(parent)
        # Create an inner notebook for subtabs
        self.subnotebook = ttk.Notebook(self)
        self.subnotebook.grid(row=0, column=0, sticky="nsew")

        # Add subtabs
        subtab1 = SubTab7(self.subnotebook)
        self.subnotebook.add(subtab1, text="Arkusz")

        subtab2 = SubTab8(self.subnotebook)
        self.subnotebook.add(subtab2, text="Arkusz Perforowany")


class Tab3(BaseTab):
    def __init__(self, parent):
        super().__init__(parent)  
        label = ttk.Label(self, text="Armatura")
        label.grid(row=0, column=0, sticky="nsew")


class BaseSubTab(Frame):
    """Base class for tabs."""

    def __init__(self, parent):
        super().__init__(parent)
        # make window resizeable
        self.grid_rowconfigure(0, weight=1)
        self.grid_columnconfigure(0, weight=1)

        self.left_frame = tk.Frame(self)
        self.right_frame = tk.Frame(self)
        self.footer_frame = tk.Frame(self)

        self.left_frame.grid(row=0, column=0, sticky="nsew")
        self.right_frame.grid(row=0, column=1, sticky="nsew")
        self.footer_frame.grid(row=1, columnspan=2, padx=10, pady=10)

        self.create_widgets()

    def create_cell(self, frame, text, row=0):
        """
        Creates a label, an entry field, and another label in a given frame.

        Args:
            frame: The frame in which the widgets will be placed.
            text (str): The text to be displayed on the first label.
            row (int): The row number at which the widgets will be placed.

        Returns:
            None
        """
        nested_frame = tk.Frame(frame)
        nested_frame.grid(row=row, column=0, padx=10, pady=10, sticky="nsew")
        frame = nested_frame

        label = ttk.Label(frame, text=text)
        label.grid(row=row, column=0, sticky=tk.W)

        var = tk.StringVar()
        entry = ttk.Entry(frame, textvariable=var)
        entry.grid(row=row + 1, column=0, padx=5, pady=5, sticky=tk.W)

        varl = tk.StringVar()
        lbl = ttk.Label(
            frame, text="wynik", textvariable=varl, background="grey", width=10
        )
        lbl.grid(row=row + 1, column=1, padx=5, pady=5, sticky=tk.W)

    def insert_image(self, image):

        nested_frame = tk.Frame(self.footer_frame)
        nested_frame.grid(row=0, columnspan=2, padx=10, pady=10)

        self.canvas_obraz = tk.Canvas(nested_frame, width=400, height=150)
        self.image_blachy = tk.PhotoImage(data=image)
        self.image_blachy = self.image_blachy.subsample(2, 2)
        self.labeled_image = ttk.Label(
            nested_frame, image=self.image_blachy, compound=CENTER, text="element"
        )
        self.labeled_image.grid(row=0, columnspan=2, padx=10, pady=10)
        # self.canvas_obraz.create_image(0, 0, anchor="nw", image=self.image_blachy)
    
    def create_widgets(self):
        # labele sa tworzowe w kolejnoswci tworzenia inaczej trzeba ustawic grid
        # to sa wspolne labele dla wszystkich zakładek

        self.create_cell(self.left_frame, "Gestość (kg/m^3)", row=0)
        self.create_cell(self.left_frame, "Długość (mm)", row=1)

        self.create_cell(self.right_frame, "Waga 1mb (kg)", row=0)
        self.create_cell(self.right_frame, "Waga dla p. długości (kg)", row=1)
        self.create_cell(self.right_frame, "Cena 1m", row=2)
        self.create_cell(self.right_frame, "Cena za 1kg", row=3)
        self.create_cell(self.right_frame, "Cena dla p. długości", row=4)


class SubTab1(BaseSubTab):
    def __init__(self, parent):
        super().__init__(parent)
        self.create_cell(self.left_frame, "Średnica (mm)", row=3)
        self.create_cell(self.left_frame, "Grubość ścianki (mm)", row=4)
        self.insert_image(ImageType.RURA.value)


class SubTab2(BaseSubTab):
    def __init__(self, parent):
        super().__init__(parent)
        self.create_cell(self.left_frame, "Średnica (mm)", row=3)
        self.insert_image(ImageType.PRET.value)


class SubTab3(BaseSubTab):
    def __init__(self, parent):
        super().__init__(parent)
        self.create_cell(self.left_frame, "Szerokość (mm)", row=3)
        self.create_cell(self.left_frame, "Grubość (mm)", row=4)
        self.insert_image(ImageType.PLASKOWNIK.value)


class SubTab4(BaseSubTab):
    def __init__(self, parent):
        super().__init__(parent)
        self.create_cell(self.left_frame, "Wysokość (mm)", row=3)
        self.create_cell(self.left_frame, "Szerokość (mm)", row=4)
        self.create_cell(self.left_frame, "Grubość ścianki (mm)", row=5)
        self.insert_image(ImageType.KSZTALTOWNIK.value)


class SubTab5(BaseSubTab):
    def __init__(self, parent):
        super().__init__(parent)
        self.create_cell(self.left_frame, "Wysokość (mm)", row=3)
        self.create_cell(self.left_frame, "Szerokość (mm)", row=4)
        self.create_cell(self.left_frame, "Grubość ścianki (mm)", row=5)
        self.insert_image(ImageType.KATOWNIK.value)


class SubTab6(BaseSubTab):
    def __init__(self, parent):
        super().__init__(parent)
        self.create_cell(self.left_frame, "Wysokość (mm)", row=3)
        self.create_cell(self.left_frame, "Szerokość (mm)", row=4)
        self.create_cell(self.left_frame, "Grubość ścianki (mm)", row=5)
        self.insert_image(ImageType.CEOWNIK.value)

class SubTab7(BaseSubTab):
    def __init__(self, parent):
        super().__init__(parent)
        self.create_cell(self.left_frame, "Szerokość (mm)", row=3)
        self.create_cell(self.left_frame, "Grubość ścianki (mm)", row=4)
        self.create_cell(self.left_frame, "Powierzchnia (m^2)", row=5)
        self.insert_image(ImageType.ARKUSZ.value)


class SubTab8(BaseSubTab):
    def __init__(self, parent):
        super().__init__(parent)
        self.create_cell(self.left_frame, "Szerokość (mm)", row=3)
        self.create_cell(self.left_frame, "Grubość ścianki (mm)", row=4)
        self.create_cell(self.left_frame, "Powierzchnia (m2)", row=5)
        self.create_cell(self.left_frame, "Prześwit (%)", row=6)
        self.insert_image(ImageType.ARKUSZ_PERFOROWANY.value)



class MainWindow(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Multiple Tabs")
        self.rowconfigure(0, weight=1)
        self.columnconfigure(0, weight=1)

        # Create the notebook
        self.notebook = ttk.Notebook(self)
        self.notebook.grid(row=0, column=0, sticky="nsew")
        self.notebook.rowconfigure(0, weight=1)

        # Create and add tabs
        tab1 = Tab1(self.notebook)
        self.notebook.add(tab1, text="Materiały długościowe")

        tab2 = Tab2(self.notebook)
        self.notebook.add(tab2, text="Materiały powierzchniowe")

        tab3 = Tab3(self.notebook)
        self.notebook.add(tab3, text="Armatura")

# Run the main loop
if __name__ == "__main__":
    window = MainWindow()
    window.mainloop()


0

Zostanę przy wczytywaniu układu ze słownika czyli ostatnio podana przeze mnie wersja i do niej tutaj się odnoszę. Dla mnie jest to bardzo wygodne. Zastanowię się nad zapisywaniem do pliku.

Został mi jeszcze jeden problem do rozwiązania.


class Obliczenia_wartosci_wg_wzorow:
    def __call__(self, wartosci_pod, uklad):
    ...

        for nazwa, wzory in self.labele_i_ich_wzory.items():
            if self.wartosci_pod[nazwa] == '':
                if len(self.labele_i_ich_wzory[nazwa])>1:
                    self.obliczenia_dla_kilku_wzorow(nazwa)
                else:
                    self.obliczenia_dla_jednego_wzoru(nazwa) # powinno być zlikwidowane/połączone z obliczenia_dla_kilku_wzorow() ale jeszcze tego nie rozgryzłem

    ...

    def obliczenia_dla_kilku_wzorow(self, co)->None:
        # co - np. masa_1m2,cena_1kg itd
        lista_wynikow =[]
        self.lista_wzorow = self.labele_i_ich_wzory[co]

        for wzor in self.lista_wzorow:
            lista_slow = self.slowa_w_stringu(wzor)
            #logging.debug(f'{lista_slow=}')
            kontynuuj = False
            for slowo in lista_slow:
                if self.wartosci_pod[slowo] == '':
                    kontynuuj = False
                    break
                else:
                    kontynuuj = True

            if kontynuuj:
                lista_wynikow.append(self.oblicz_wyrazenie(wzor, self.wartosci_na_float(self.wartosci_pod)))
        logging.debug(f'2:{lista_wynikow=}')
        if len(lista_wynikow) >1:

            wynikk = self.czy_wyniki_roznia_sie_miedzy_soba(lista_wynikow)
            self.wartosci_pod[co] = wynikk
        elif len(lista_wynikow) ==1:
            self.wartosci_pod[co] = lista_wynikow[0]

W obliczenia_dla_kilku_wzorow() iteruję po wzorach dla danej wartości (czasami coś można obliczyć na kilka sposobów, for wzor in self.lista_wzorow: ), następnie sprawdzam czy wszystkie wartości potrzebne do obliczeń są podane for slowo in lista_slow: . Jeżeli są to robię obliczenia oblicz_wyrazenie() i porównuję wyniki między sobą czy_wyniki_roznia_sie_miedzy_soba() jeżeli wyników (z różnych wzorów) jest więcej. Wynik zapisuję w liście z wartościami podanymi self.wartosci_pod.

Problem jest taki, że jeżeli coś już zostało sprawdzone, że nie da się tego obliczyć za pomocą obliczenia_dla_kilku_wzorow() bo brakuje np masa_1m2 to ta wartość już nie zostanie obliczona mimo, że w dalszej części programu (a właściwie pętli for nazwa, wzory in self.labele_i_ich_wzory.items():) wartość masa_1m2 zostanie obliczona.

Prawdopodobnie wynika to z pętli for nazwa, wzory in self.labele_i_ich_wzory.items(): w klasie Obliczenia_wartosci_wg_wzorow:. Kiedy ta pętla już coś sprawdzi to nie wraca do poprzednich wartości mimo, że da się je już policzyć. Jak to zmienić?

0

rozumiem ze z dwóch funkcji / metody chcesz zrobić jedna

To jest u mnie działajacy kod z dwoma metodami:



class Obliczenia_wartosci_wg_wzorow:
    def __call__(self, wartosci_pod, uklad):

        self.wartosci_pod = wartosci_pod
        self.uklad = uklad
        self.nazwy_labeli = []
        self.labele_i_ich_wzory = {}

        for rodzaj_widzetu, dane in uklad.items():
            if rodzaj_widzetu == "label":
                for nazwa, tekst, col, r, wzor in dane:
                    self.nazwy_labeli.append(nazwa)
                    self.labele_i_ich_wzory[nazwa] = wzor

        for nazwa, wzory in self.labele_i_ich_wzory.items():
            if self.wartosci_pod[nazwa] == "":
                if len(self.labele_i_ich_wzory[nazwa]) > 1:
                    self.obliczenia_dla_kilku_wzorow(nazwa)
                else:
                    self.obliczenia_dla_jednego_wzoru(nazwa)

        return self.przygotuj_do_wyswietlenia(self.wartosci_pod)

    def obliczenia_dla_jednego_wzoru(self, co):
        lista_slow = self.slowa_w_stringu(*self.labele_i_ich_wzory[co])
        # logging.debug(f'{lista_slow=}')
        kontynuuj = False
        for slowo in lista_slow:
            if self.wartosci_pod[slowo] == "":
                kontynuuj = False
                break
            else:
                kontynuuj = True

        if kontynuuj:

            # logging.debug(f'{co=}, {self.wartosci_pod}, wzor = {self.labele_i_ich_wzory[co]}')
            wartosci_pod_float = self.wartosci_na_float(self.wartosci_pod)
            self.wartosci_pod[co] = str(
                self.oblicz_wyrazenie(*self.labele_i_ich_wzory[co], wartosci_pod_float)
            )

    def obliczenia_dla_kilku_wzorow(self, co):
        lista_wynikow = []
        self.lista_wzorow = self.labele_i_ich_wzory[co]

        for wzor in self.lista_wzorow:
            lista_slow = self.slowa_w_stringu(wzor)
            # logging.debug(f'{lista_slow=}')
            kontynuuj = False
            for slowo in lista_slow:
                if self.wartosci_pod[slowo] == "":
                    kontynuuj = False
                    break
                else:
                    kontynuuj = True

            if kontynuuj:
                lista_wynikow.append(
                    self.oblicz_wyrazenie(
                        wzor, self.wartosci_na_float(self.wartosci_pod)
                    )
                )

        if len(lista_wynikow) > 1:
            wynikk = self.czy_wyniki_roznia_sie_miedzy_soba(lista_wynikow)
            self.wartosci_pod[co] = wynikk
        elif len(lista_wynikow) == 1:
            self.wartosci_pod[co] = lista_wynikow[0]



A to działajacy zrefaktorowany kod z jedna funkcja metoda


class Obliczenia_wartosci_wg_wzorow:
    def __call__(self, wartosci_pod, uklad):
        self.wartosci_pod = wartosci_pod
        self.uklad = uklad
        self.nazwy_labeli = []
        self.labele_i_ich_wzory = {}

        for rodzaj_widzetu, dane in uklad.items():
            if rodzaj_widzetu == "label":
                for nazwa, tekst, col, r, wzor in dane:
                    self.nazwy_labeli.append(nazwa)
                    self.labele_i_ich_wzory[nazwa] = wzor

        for nazwa, wzory in self.labele_i_ich_wzory.items():
            if self.wartosci_pod[nazwa] == "":
                self.obliczenia_dla_wzoru(nazwa, wzory)

        return self.przygotuj_do_wyswietlenia(self.wartosci_pod)

    def obliczenia_dla_wzoru(self, co, wzory):
        lista_wynikow = []

        for wzor in wzory:
            lista_slow = self.slowa_w_stringu(wzor)
            kontynuuj = all(self.wartosci_pod[slowo] != "" for slowo in lista_slow)

            if kontynuuj:
                lista_wynikow.append(
                    self.oblicz_wyrazenie(
                        wzor, self.wartosci_na_float(self.wartosci_pod)
                    )
                )

        if len(lista_wynikow) > 1:
            wynik = self.czy_wyniki_roznia_sie_miedzy_soba(lista_wynikow)
            self.wartosci_pod[co] = wynik
        elif len(lista_wynikow) == 1:
            self.wartosci_pod[co] = lista_wynikow[0]



0

Dziękuję, połączenie tych dwóch metod nie było najważniejsze, ale skorzystam z tego rozwiązania.

Jeżeli chodzi o problem z tym, że nie wszystkie wartości były aktualizowane ChatGPT podpowiedział, że można skorzystać z iteratora dynamicznego który będzie zaczynał pętle for nazwa, wzory in self.labele_i_ich_wzory.items(): od nowa, kiedy self.wartosci_pod ulegnie zmianie. Czy to dobre rozwiązanie?

0

To jest strasznie nieczytelne. Nie mogę się połapać. Już nie chce mi się tego rozgryzać, bo to za dużo czasu zajmie, a widzę tu sporo nieścisłości. Już nie bedę pisał całego kodu bo to najpierw moim zdaniem trzeba by było przeanalizować założenia.

Po przeanalizowaniu fragmentu kodu

        for nazwa, wzory in self.labele_i_ich_wzory.items():
            if self.wartosci_pod[nazwa] == "":
                print("PP ",nazwa, "ooo ",wzory)

dostaje

PP  masa_pod ooo  ['masa_1m2*(dlugosc/1000)*(szerokosc/1000)', '(dlugosc/1000)*(szerokosc/1000)*(grubosc/1000)*g_jednostkowa']

Dla przypadku użycia gdy najpierw wpisujesz powierzchnie i grubość to nie policzy ci tego (masa na podstawie wymiarów) bo wzor liczy tylko na podstawie długosci i szerokosci która jest nie wpisana i wynosi zero a wzór powinien liczyć na podstawie powierzchni (powinny być dwa różne wzory)

czyli jak wpisujesz tylko powierzchnie i grubość to nie policzy ze wzoru bo wzór jest zły, we wzorze zamiast (dlugosc/1000)*(szerokosc/1000) powinna być powierzchnia.

czyli zgaduje za tak :

['masa_1m2*powierzchnia', '(dlugosc/1000)*(szerokosc/1000)*(grubosc/1000)*g_jednostkowa']

no i w tym fragmecie tak

(
                "masa_pod",
                "",
                6,
                3,
                [
                    "masa_1m2*powierzchnia",
                    "(dlugosc/1000)*(szerokosc/1000)*(grubosc/1000)*g_jednostkowa",
                ],
            ),

No i teraz jak wpiszesz powierzchnia grubosc i wybrana cena to sie policzy to

W skrócie, realizujesz wiele scenariuszy i przypadków użycia dla tych samych pól entry. Na przykład, gdy wpisujesz powierzchnię i grubość, to nic nie liczyło, bo i tak trzeba podawać szerokosc i wysokosc. Jest to dziwne, ponieważ w powierzchni powinny być już zawarte wszystkie wymiary (dlugosc, szerokosc , dlugosc). Zgaduję, że skorzystanie z iteratora i tak nie pomoże, bo chodzi o relacje między polami, które wpisujesz. Ogólnie realizujesz tylko jeden przypadek, gdzie użytkownik wpisuje po kolei wszystkie dane: najpierw długość, szerokość, grubość, gęstość i wybraną cenę. Natomiast te pola są ze sobą powiązane, niektóre mogą być nawet pominięte. Jeżeli najpierw wpisujesz tylko powierzchnię, gęstość i cenę, to coś się sypie.

Aby to jakoś ogarnąć, trzeba by rozpisać wszystkie powiązania pól i przypadki użycia (co i kiedy które pola powinny się aktualizować na podstawie jakich wartości, uwzględnić wszystkie warunki brzegowe, np. puste pole i błędne wartości). Można również zrobić testy jednostkowe, żeby wiedzieć, które się zrobiło, i przy każdym kolejnym rozwiązaniu przypadku sprawdzać, czy coś się po drodze nie wysypało, a pożniej przy zmianach jest znacznie szybciej. (Ale to tez dłużej się pisze i jest więcej kodu, wiec wszystko ma swoje plusy i minusy, tutaj to jest tylko opcjonalne, bo pewnie i tak bez tego dało by sie to wszystko ogarnac). Nie wiem też po co tutaj porównywać wyniki, skoro powierzchnię liczy się na podstawie tych samych danych. W kodzie i tak cena czy masa liczy się i tak oddzielnie na podstawie powierzchni i oddzielnie dla szerokości i wysokości, skoro to wynika jednego z drugiego.

Co do iteratora, no w sumie możesz spróbować to tak zrobić, ale musisz pamiętać też o sprawdzeniu stanu innych pól. Na przykład, gdy szerokość i wysokość entry field będą puste, a podana tylko powierzchnia, to wtedy policzy (bo jednego wzoru nie będzie się dało policzyć). A jak będzie wpisana tylko wysokość, to już znowu się wysypie, bo pola nie będą zablokowane (to jest przypadek, gdzie najpierw wpisujemy powierzchnię, a
potem wymiary, np. wysokość).

Mam nadzieje ze to pomoże

0

Ogólnie realizujesz tylko jeden przypadek, gdzie użytkownik wpisuje po kolei wszystkie dane: najpierw długość, szerokość, grubość, gęstość i wybraną cenę

Iterator dynamiczny rozwiązał ten problem, tylko zastanawia mnie jak to lepiej napisać jako całość ?

Aby to jakoś ogarnąć, trzeba by rozpisać wszystkie powiązania pól i przypadki użycia (co i kiedy które pola powinny się aktualizować na podstawie jakich wartości, uwzględnić wszystkie warunki brzegowe, np. puste pole i błędne wartości).

Rozpatrywanie wszystkich tych przypadków zajęłoby mi wieczność

Nie wiem też po co tutaj porównywać wyniki, skoro powierzchnię liczy się na podstawie tych samych danych.

Porównanie to tylko tak dla mnie abym widział czy gdzieś czegoś nie pomyliłem

0

Hmm, najlepiej jak sobie na początku trochę pobródzisz sobie ręcę ^^ (jeśli masz czas) Spróbuj dodać jakiś feature lub sprawdzić, czy kod działa na różnych wersjach Pythona, np. na wersji 3.13.

Jeśli chodzi o przypadki, zawsze można realizować tylko ścieżkę krytyczną(), a resztę dać na "TODO:" 🙃. Raczej chodziło mi o to, co może Ci się przydać, jeśli przeanalizujesz przypadki do zrobienia. Mając jakiś ogólny pogląd, możesz wtedy dobrać rozwiązanie.

Nie wiem, czego używasz do programowania, ale powinno być tam jakaś opcja debugowania. Tam możesz sobie ustawiać "break point" i "watch". "Break points" to miejsca, w których chcesz, aby program się zatrzymał, a "watch" to elementy, które chcesz śledzić. Dodajesz wtedy dwa elementy i możesz sprawdzić, czy są takie same. Zamiast dodatkowego kodu sprawdzającego to może lepiej napisać test, bo w kodzie, jak się to nie przyda, to lepiej nie dodawać, a testy się przydają jak wprowadzasz zmiany w kodzie ( tylko musisz dłużej pisać kod bo dochodzi napisanie testu... 😐).

1 użytkowników online, w tym zalogowanych: 0, gości: 1