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

Jeśli chodzi o wywołanie funkcji po naciśnięciu klawisza Enter dla przycisku na aktywnej zakładce, możesz spróbować przypisać funkcję do zdarzenia obsługi klawisza Enter w polu tekstowym lub polu wprowadzania danych. Na przykład w przypadku aplikacji desktopowej w języku Python i bibliotece Tkinter, mógłbyś użyć metody bind do powiązania zdarzenia <Return> z funkcją dla aktualnie aktywnej zakładki.

Jeśli chodzi o obsługę wielu pól wprowadzania danych i zapobieganie błędom podczas przeliczeń, stosowanie podejścia obiektowego to dobry krok. Możesz utworzyć klasy lub obiekty, które reprezentują różne typy danych lub elementy interfejsu użytkownika, a następnie stosować odpowiednie metody do przeliczeń i aktualizacji wartości w odpowiednich polach.
. Możesz również użyć mechanizmów walidacji danych, aby upewnić się, że użytkownik wprowadza poprawne informacje.

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

1 użytkowników online, w tym zalogowanych: 0, gości: 1