Tkinter entry widget

Fragen zu Tkinter.
Antworten
mureed.niazie
User
Beiträge: 18
Registriert: Dienstag 22. März 2022, 14:40

Hallo everyone. :)

I am new here in the python forum and I try to write a program which I can do some calculations with.
programm run but i cant make the button alive like if its clicked, the entry widget will be inactive and when i click back again the entry widget get back to active mode.
and the plt.show() window is opened out of tkinter window. i need it in tkinter window and everytime i change the values the i must receive the updated window

thankyou so much for your response




the code is


from tkinter import *
from PIL import ImageTk, Image
import scipy as sc
import scipy.special as scs
import scipy.optimize as sco
import matplotlib.pyplot as plt
import numpy as np
root = Tk()
root.title("Coax TE Mode")
root.geometry("1400x1000")
root.config(background="#145")

var = IntVar()

# generate the window
title = Label(root, text="Coax TE Mode", font=('Helvetica', 22), bg="#145", fg="white")
title.grid(row=0, column=3, padx=20, pady=20)
leer = Label(root, text="", bg="#145", fg="#145") #abstand zwischen title und andere funktionen
leer.grid(row=1, column=1)
leer = Label(root, text="", bg="#145", fg="#145")
leer.grid(row=2, column=1)

# Impedanz = zl (in die gleichung als (z) gezeichnet)

impedanz_Label = Label(root, text="Impedanz", font=12, bg="#145", fg="white")
impedanz_Label.grid(row=6, column=0, padx=10, pady=10)
impedanz_Var = IntVar()
impedanz_Entry = Entry(root, textvariable=impedanz_Var, width=32, borderwidth=5, )
impedanz_Entry.grid(row=6, column=1, columnspan=4, padx=10, pady=10)

# Innenleiter = in_d (in die gleichung als (in_d) gezeigt)

innenleiter_Label = Label(root, text="Innenleiter", font=12, bg="#145", fg="white")
innenleiter_Label.grid(row=4, column=0, padx=10, pady=10)
innenleiter_Var = IntVar()
innenleiter_Entry = Entry(root, textvariable=innenleiter_Var, width=32, borderwidth=5)
innenleiter_Entry.grid(row=4, column=1, columnspan=4, padx=10, pady=10)

# Aussenleiter = aus_d (in die gleichung als (aus_d) gezeigt)
aussenleiter_Label = Label(root, text="Außenleiter", font=12, bg="#145", fg="white")
aussenleiter_Label.grid(row=5, column=0, padx=10, pady=10)
aussenleiter_Var = IntVar()
aussenleiter_Entry = Entry(root, textvariable=aussenleiter_Var, width=32, borderwidth=5)
aussenleiter_Entry.grid(row=5, column=1, columnspan=4, padx=10, pady=10)

# eps_r = in die gleichung als (eps_r) gezeigt

eps_r_Label = Label(root, text="eps_r", font=12, bg="#145", fg="white")
eps_r_Label.grid(row=7, column=0, padx=10, pady=10)
eps_r_Var = IntVar()
eps_r_Entry = Entry(root, textvariable=eps_r_Var, width=32, borderwidth=5)
eps_r_Entry.grid(row=7, column=1, columnspan=4, padx=10, pady=10)


def result_btn_function():
zl = impedanz_Var.get()
eps_r = eps_r_Var.get()
aus_d = aussenleiter_Var.get()
in_d = innenleiter_Var.get()
in_d = aus_d / (np.e ** (zl * 2 * np.pi * np.sqrt(eps_r) / z0))

r1 = np.sqrt(eps_r) * aus_d / 2
r = np.sqrt(eps_r) * in_d / 2
a = r1 / r
z = z0 / (2 * np.pi * np.sqrt(eps_r)) * np.log(aus_d / in_d)
f_g = etsi * (a + 1) / (2 * np.pi * np.sqrt(m0 * e0) * (r1 + r) * 1e-3) / 1e9

result = round(f_g, 2)
result1 = round(z, 2)
result2 = round(in_d, 2)

Result_label.config(text='f_g : ' + str(result))
Result_label1.config(text='Impedanz (Z) : ' + str(result1))
Result_label2.config(text='In.leiter D/O : ' + str(result2))


c0 = 299792458 # lichtgeschwindigkei
m0 = 4 * np.pi * 1e-7 # magnetische feldkonstante
e0 = 1 / (m0 * c0 ** 2) # elektrische feldkonstante
z0 = np.sqrt(m0 / e0) # frei raum wellen widerstan


zl = 30 # Impedanz
eps_r = 1 # Permitivity dry air 1.000594
aus_d = 4 # Aussenleiter
in_d = aus_d / (np.e ** (zl * 2 * np.pi * np.sqrt(eps_r) / z0))
# in_d = 0.11176 # Inneleiter

r1 = np.sqrt(eps_r) * aus_d / 2
r = np.sqrt(eps_r) * in_d / 2
a = r1 / r
z = z0 / (2 * np.pi * np.sqrt(eps_r)) * np.log(aus_d / in_d)


def wav_num(x):
return ((scs.jn(0, x * a) - scs.jn(2, x * a)) * (scs.yn(0, x) - scs.yn(2, x))
- (scs.yn(0, x * a) - scs.yn(2, x * a)) * (scs.jn(0, x) - scs.jn(2, x)))

x = np.arange(0.1, 1.0, 0.01)
test = wav_num(x)
etsi = sco.brentq(wav_num, 0.1, 0.8)
f_g = etsi * (a + 1) / (2 * np.pi * np.sqrt(m0 * e0) * (r1 + r) * 1e-3) / 1e9


plt.figure(1)
plt.plot(x, test)
plt.grid(True)
plt.show()
plt.savefig("result.png", dpi=199)

# Result btn
Result_btn = Button(root, command=result_btn_function, text="Result", bg="#145", fg="white", font=12)
Result_btn.grid(row=8, column=2, padx=10, pady=10)

# Show Result tkinter root window
Result_label = Label(root, text="", bg="#145", fg="white", font=14)
Result_label.grid(row=10, column=2, columnspan=20, padx=2, pady=2)

Result_label1 = Label(root, text="", bg="#145", fg="white", font=14)
Result_label1.grid(row=11, column=2, columnspan=20, padx=2, pady=2)

Result_label2 = Label(root, text="", bg="#145", fg="white", font=14)
Result_label2.grid(row=12, column=2, columnspan=20, padx=2, pady=2)


# clear btn soll entry fields räumen
clear_btn = Button(root, text="Clear", bg="#145", fg="white", font=12) #
clear_btn.grid(row=8, column=3, padx=10, pady=10)

'''
frage 2.

Radio btn muss Innenleiter field aktiv oder deaktivieren kann.

heißt wenn Radiobottun ausgeschaltet wird ( nur Innenleiter field deatktiviert werden muss )

'''

# Innenleiter btn muss Innenleiter field aktiv und deaktivieren
Radiobutton = Radiobutton(root, text="", variable=var,
font=12, bg="#145", fg="white", value=1) #command= ?
Radiobutton.grid(row=4, column=4, columnspan=4, padx=10, pady=10)


# Exit
exit_btn = Button(root, text="Exit", bg="#145", fg="white", font=12, command=root.quit)
exit_btn.grid(row=8, column=4, padx=10, pady=10)

print("TE11 cut-off f_g =", "%8.2f" % f_g, "GHz")
print("Die Impedanz Z =", "%8.2f" % z, "Ohm")
print("Innenleiter D/O =", "%8.2f" % in_d, "mm")

root = mainloop()
Benutzeravatar
Dennis89
User
Beiträge: 1123
Registriert: Freitag 11. Dezember 2020, 15:13

Hallo,

da auch deine Kommentare und dein Code teilweise auf deutsch ist, antworte ich auch mal in deutsch.

Nur mal ein paar grobe Sachen.

Programmiert wird nicht auf Modulebene von oben nach unten. Auf Modulebene (alles ohne Einrückungen) steht kein ausführbarer Code. Hier werden nur Konstanten definiert.
Das Programm wird aus einer Funktion mit dem Name 'main' gesteuert. Hieraus werden dann weitere Funktionen aufgerufen, Argumente übergeben und eventuell Rückgaben entgegen genommen.

Verwende keine *-Importe. Das bringt noch mehr Chaos ins Chaos. Weil jetzt hast du in deinem Code noch alle Namen importiert die es in 'tkinter' gibt. Das kann zum einen zu Namenskollisionen führen und zum anderen weis man gar nicht wo was herkommt.

Wenn du einen Namen nicht benötigst, dann brauchst du den auch nicht. Zum Beispiel deine Überschrift in deinem GUI. Die erstellst du zu Beginn, wirst sie aber im Programmablauf nicht ändern. Dann kannst du das Label auch so erstellen und musst es nicht an einen Namen binden.

Allgemein solltest du sprechende Namen verwenden. 'leer' sagt eigentlich nichts aus genauso wenig wie Result1, 2, 3 etc.. Dann bindest du 'leer' an ein Label und danach bindest du 'leer' wieder an das nächste Label. Da sind wir wieder beim Thema, wenn du Namen überschreiben kannst ohne das es im Programm auffällt, dann brauchst du die vielleicht gar nicht.

Strings puzzelt man auch nicht mit '+' zusammen, hier würden sich 'f'-Strings anbieten.

Versuche für jede Aufgabe einzelne kleine Funktionen zu schreiben. Das macht das alles viiiiiiel übersichtlicher. Dann benenne die Funktion noch nach dem was sie tun.

Ein GUI reagiert auf Ereignisse, da läuft also eine Schleife und wenn etwas passiert, zum Beispiel ein Druck auf einen Button, dann wird etwas ausgeführt. Der Aufruf dieser Schleife fehlt bei dir. In 'tkinter' nennt sich das 'mainloop'.

Also würde dein Grundgerüst etwa so aussehen:

Code: Alles auswählen

import tkinter as tk
from functools import partial
from random import randint


def get_number(result):
    result.config(text=randint(5, 893))


def main():
    root = tk.Tk()
    root.title("Coax TE Mode")
    root.config(background="#145")
    tk.Label(
        root, text="Coax TE Mode", font=("Helvetica", 16), bg="#145", fg="white"
    ).grid(row=0, column=1)
    result = tk.Label(root, text="---", font=12, bg="#145", fg="white")
    result.grid(row=1, column=1)
    start = tk.Button(
        root,
        command=partial(get_number, result),
        text="Result",
        bg="#145",
        fg="white",
        font=12,
    )
    start.grid(row=8, column=1)
    root.mainloop()


if __name__ == "__main__":
    main()
Damit stoßt man aber relativ schnell an seine Grenzen. Etwas anspruchsvollere GUI's benötigen objektorientierte Programmierung. Das heißt du musst dich mit Klassen vertraut machen.

Bevor man jetzt genauer auf deine Fragen eingeht, muss erst das Grundgerüst stehen und verstanden sein. Schau dich mal im Forum um, hier gibt es sehr viele Beispiele für 'tkinter'-GUI's.
Das arbeiten mit Funktionen und Klassen muss man bei soetwas beherrschen. Die Grundlagen lernst du hier:
https://docs.python.org/3/tutorial/

Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Antworten