Python Tkinter, How to pass Variable into mutltiple Functions - python

EDIT: Thanks to #Osadhi Virochana Jayasinghe Si! Using global "vars" inside the buildwindow() function, makes them readable in the called button function. I also had to fix how to get the Values of the Checkbox and text Widget.
Full Fixed code:
import tkinter as tk
import tkinter.scrolledtext as tkst
from PyQt5.QtWidgets import QApplication # need to install PyQt5 or remove center() Function
def main_window():
window = tk.Tk()
window.title("New Entry")
build_window(window)
center(window) # https://stackoverflow.com/questions/3352918/how-to-center-a-window-on-the-screen-in-tkinter
window.mainloop() # Main Loop, nothing runs after here on Gui
def center(toplevel):
toplevel.update_idletasks()
app = QApplication([])
screen_width = app.desktop().screenGeometry().width()
screen_height = app.desktop().screenGeometry().height()
size = tuple(int(_) for _ in toplevel.geometry().split('+')[0].split('x'))
x = screen_width/2 - size[0]/2
y = screen_height/2 - size[1]/2
toplevel.geometry("+%d+%d" % (x, y))
def build_window(window):
global entry_name, entry_link, entry_xpath, chbox_active, entry_comment, box_var
label_title = tk.Label(window, text="NEW ENTRY")
label_name = tk.Label(window, text="Name:")
entry_name = tk.Entry(window)
label_link = tk.Label(window, text="Link:")
entry_link = tk.Entry(window)
label_xpath = tk.Label(window, text="XPath:")
entry_xpath = tk.Entry(window)
label_active = tk.Label(window, text="Active:")
box_var = tk.IntVar()
chbox_active = tk.Checkbutton(window, variable=box_var, text="Active")
label_comment = tk.Label(window, text="Comment:")
entry_comment = tkst.ScrolledText(window, width=40, height=4, font=("roboto", 8))
botton_cancel = tk.Button(window, text="Done", command=lambda: close_window(window))
button_go = tk.Button(window, text="Run", command=lambda: write_dict(window))
label_title.grid (row=0, column=1, sticky="nwse", padx=2, pady=2)
label_name.grid (row=1, column=0, sticky="e", padx=2, pady=2)
entry_name.grid (row=1, column=1, sticky="nwse", padx=2, pady=2)
label_link.grid (row=2, column=0, sticky="e", padx=2, pady=2)
entry_link.grid (row=2, column=1, sticky="nwse", padx=2, pady=2)
label_xpath.grid (row=3, column=0, sticky="e", padx=2, pady=2)
entry_xpath.grid (row=3, column=1, sticky="nwse", padx=2, pady=2)
label_active.grid (row=4, column=0, sticky="e", padx=2, pady=2)
chbox_active.grid (row=4, column=1, sticky="w", padx=2, pady=2)
label_comment.grid (row=5, column=0, sticky="e", padx=2, pady=2)
entry_comment.grid (row=5, column=1, sticky="w", padx=2, pady=2)
window.grid_rowconfigure(6, minsize=20) # Empty?
botton_cancel.grid(row=7, column=0, sticky="w", padx=2, pady=2) # Cancel Button
button_go.grid(row=7, column=1, sticky="e", padx=2, pady=2) # Write Dict Button
def close_window(window):
window.destroy()
def write_dict(window):
i_dict = {}
i_dict["name"] = entry_name.get()
i_dict["link"] = entry_link.get()
i_dict["xpath"] = entry_xpath.get()
i_dict["active"] = box_var.get()
i_dict["comment"] = entry_comment.get('1.0', tk.END)
print(i_dict)
pass
main_window()
I am trying to make a simple GUI do enter Data into a Dictionary. Most things i find online write the Tkinter straight into the .py, but i want to use a Function to Draw the Window, and another Function to do its stuff once a Button is pressed.
Shorted code:
def main_window():
window = tk.Tk()
build_window(window)
window.mainloop()
def build_window(window):
entry_name = tk.Entry(window)
button_go = tk.Button(window, text="Run", command=lambda: write_dict())
button_go.grid(row=7, column=1, sticky="e", padx=2, pady=2)
def write_dict():
i_dict = {}
i_dict["name"] = entry_name.get()
main_window()
And i am getting AttributeError: module 'tkinter' has no attribute 'entry_name'. I tried various ways to get window into write_dict(), but i could never use .get() to read the values inside the Entry Box.
how would i do this?
Full code:
import tkinter as tk
import tkinter.scrolledtext as tkst
from PyQt5.QtWidgets import QApplication
d_list = []
def main_window():
window = tk.Tk()
window.title("New Entry")
build_window(window)
window.mainloop() # Main Loop, nothing runs after here on Gui
def build_window(window):
label_title = tk.Label(window, text="NEW ENTRY")
label_name = tk.Label(window, text="Name:")
entry_name = tk.Entry(window)
label_link = tk.Label(window, text="Link:")
entry_link = tk.Entry(window)
label_xpath = tk.Label(window, text="XPath:")
entry_xpath = tk.Entry(window)
label_active = tk.Label(window, text="Active:")
chbox_active = tk.Checkbutton(window, variable=1, text="Active")
label_comment = tk.Label(window, text="Comment:")
entry_comment = tkst.ScrolledText(window, width=40, height=4, font=("roboto", 8))
botton_cancel = tk.Button(window, text="Done", command=lambda: close_window(window))
button_go = tk.Button(window, text="Run", command=lambda: write_dict())
label_title.grid (row=0, column=1, sticky="nwse", padx=2, pady=2)
label_name.grid (row=1, column=0, sticky="e", padx=2, pady=2)
entry_name.grid (row=1, column=1, sticky="nwse", padx=2, pady=2)
label_link.grid (row=2, column=0, sticky="e", padx=2, pady=2)
entry_link.grid (row=2, column=1, sticky="nwse", padx=2, pady=2)
label_xpath.grid (row=3, column=0, sticky="e", padx=2, pady=2)
entry_xpath.grid (row=3, column=1, sticky="nwse", padx=2, pady=2)
label_active.grid (row=4, column=0, sticky="e", padx=2, pady=2)
chbox_active.grid (row=4, column=1, sticky="w", padx=2, pady=2)
label_comment.grid (row=5, column=0, sticky="e", padx=2, pady=2)
entry_comment.grid (row=5, column=1, sticky="w", padx=2, pady=2)
window.grid_rowconfigure(6, minsize=20) # Empty?
botton_cancel.grid(row=7, column=0, sticky="w", padx=2, pady=2) # Cancel Button
button_go.grid(row=7, column=1, sticky="e", padx=2, pady=2) # Write Dict Button
def close_window(window):
window.destroy()
def write_dict():
global d_list
i_dict = {}
i_dict["name"] = entry_name.get()
i_dict["link"] = entry_link.get()
i_dict["xpath"] = entry_xpath.get()
i_dict["active"] = chbox_active.get()
i_dict["comment"] = entry_comment.get()
print(i_dict)
pass
main_window()
EDIT:
The Full Errors are these 2, the first one is with the currently posted code, the second is with passing ´window´ into the button.
Traceback (most recent call last):
File "C:\Python\Python38\lib\tkinter\__init__.py", line 1883, in __call__
return self.func(*args)
File "C:/Users/Chris/Google Drive/Python/html_new_entry.py", line 50, in <lambda>
button_go = tk.Button(window, text="Run", command=lambda: write_dict())
File "C:/Users/Chris/Google Drive/Python/html_new_entry.py", line 78, in write_dict
i_dict["name"] = entry_name.get()
NameError: name 'entry_name' is not defined
Traceback (most recent call last):
File "C:\Python\Python38\lib\tkinter\__init__.py", line 1883, in __call__
return self.func(*args)
File "C:/Users/Chris/Google Drive/Python/html_new_entry.py", line 50, in <lambda>
button_go = tk.Button(window, text="Run", command=lambda: write_dict(window))
File "C:/Users/Chris/Google Drive/Python/html_new_entry.py", line 78, in write_dict
i_dict["name"] = window.entry_name.get()
File "C:\Python\Python38\lib\tkinter\__init__.py", line 2345, in __getattr__
return getattr(self.tk, attr)
AttributeError: '_tkinter.tkapp' object has no attribute 'entry_name'

Add global entry_name,entry_link,entry_xpath,chbox_active,entry_comment under the def build_window(window): It will fix Variable error.
And I fixed all of the issues
Here is the Code:
import tkinter as tk
import tkinter.scrolledtext as tkst
#from PyQt5.QtWidgets import QApplication
d_list = []
def main_window():
window = tk.Tk()
window.title("New Entry")
build_window(window)
window.mainloop() # Main Loop, nothing runs after here on Gui
def build_window(window):
global entry_name,entry_link,entry_xpath,chbox_active,entry_comment,var
var = tk.IntVar()
label_title = tk.Label(window, text="NEW ENTRY")
label_name = tk.Label(window, text="Name:")
entry_name = tk.Entry(window)
label_link = tk.Label(window, text="Link:")
entry_link = tk.Entry(window)
label_xpath = tk.Label(window, text="XPath:")
entry_xpath = tk.Entry(window)
label_active = tk.Label(window, text="Active:")
chbox_active = tk.Checkbutton(window, variable=var, text="Active")
label_comment = tk.Label(window, text="Comment:")
entry_comment = tkst.ScrolledText(window, width=40, height=4, font=("roboto", 8))
botton_cancel = tk.Button(window, text="Done", command=lambda: close_window(window))
button_go = tk.Button(window, text="Run", command=lambda: write_dict())
label_title.grid (row=0, column=1, sticky="nwse", padx=2, pady=2)
label_name.grid (row=1, column=0, sticky="e", padx=2, pady=2)
entry_name.grid (row=1, column=1, sticky="nwse", padx=2, pady=2)
label_link.grid (row=2, column=0, sticky="e", padx=2, pady=2)
entry_link.grid (row=2, column=1, sticky="nwse", padx=2, pady=2)
label_xpath.grid (row=3, column=0, sticky="e", padx=2, pady=2)
entry_xpath.grid (row=3, column=1, sticky="nwse", padx=2, pady=2)
label_active.grid (row=4, column=0, sticky="e", padx=2, pady=2)
chbox_active.grid (row=4, column=1, sticky="w", padx=2, pady=2)
label_comment.grid (row=5, column=0, sticky="e", padx=2, pady=2)
entry_comment.grid (row=5, column=1, sticky="w", padx=2, pady=2)
window.grid_rowconfigure(6, minsize=20) # Empty?
botton_cancel.grid(row=7, column=0, sticky="w", padx=2, pady=2) # Cancel Button
button_go.grid(row=7, column=1, sticky="e", padx=2, pady=2) # Write Dict Button
def close_window(window):
window.destroy()
def write_dict():
global d_list
i_dict = {}
v = ""
i_dict["name"] = entry_name.get()
i_dict["link"] = entry_link.get()
i_dict["xpath"] = entry_xpath.get()
i_dict["active"] = var.get()
i_dict["comment"] = entry_comment.get('1.0', 'end-1c')
print(i_dict)
pass
main_window()
Now you can get checkbox status and comment box status too.

Related

tkinter callback event to retrieve value from Entry and write to text file

*First of all, i am trying to create a register system saved into textfile(not real system, i know its not safe to write into textfiles) Created the GUI and then i defined multiple functions which is Menu, register and submit. Submit function is nested and inside register function. The problem is when i nested the functions it doesn't write into textfiles, but when i delete the register function, it works.
When i press register and write something in the Entry box, it didnt record to the text files, i have been scratching my head as to find what the error in my code is.
Edit: I now have put a picture to get better understanding. the blue window is main menu and its the mainloop and the yellow window is appearing when i click register button.*
picture of what should be my app
from tkinter import *
def Register():
def Submit():
elev = open("bruker.txt","a", encoding="utf-8")
elev.write(brukeridinc.get()+"\n")
elev.write(fornavn.get()+"\n")
elev.write(etternavn.get()+"\n")
register = Tk()
register.geometry("500x500")
register.configure(bg="yellow")
register.title("Bibliotekapp Login")
label_brukerid = Label(register, text="Brukerid:", bg="white", font=("Arial", 25))
label_brukerid.grid(row=1, column=0, padx=5, pady=5, sticky=E)
label_fornavn = Label(register, text="Fornavn:", bg="white", font=("Arial", 25))
label_fornavn.grid(row=2, column=0, padx=5, pady=5, sticky=E)
label_etternavn = Label(register, text="Etternavn:", bg="white", font=("Arial", 25))
label_etternavn.grid(row=3, column=0, padx=5, pady=5, sticky=E)
brukeridinc= StringVar()
entry_brukerid= Entry(register, width=10, textvariable=brukeridinc, font=("Arial", 25))
entry_brukerid.grid(row=1, column=1, padx=5, pady=5, sticky=W)
fornavn= StringVar()
entry_fornavn= Entry(register, width=10, textvariable=fornavn, font=("Arial", 25))
entry_fornavn.grid(row=2, column=1, padx=5, pady=5, sticky=W)
etternavn= StringVar()
entry_etternavn= Entry(register, width=10, textvariable=etternavn, font=("Arial", 25))
entry_etternavn.grid(row=3, column=1, padx=5, pady=5, sticky=W)
button_resultat= Button(register, text="Enter", command=Submit, height=2, width=15)
button_resultat.grid(row=4, column=1, padx=5, pady=5, sticky=W)
informasjon= StringVar()
entry_informasjon= Entry(register, width=24, textvariable=informasjon, state="readonly", font=("Arial", 25))
entry_informasjon.grid(row=5, column=1, padx=5, pady=5, sticky=W)
#GUI
start = Tk()
start.geometry("500x500")
start.configure(bg="lightblue")
start.title("Bibliotekapp")
button_register = Button(start, text="Register", bg="white", font=("Arial", 25), command=Register)
button_register.grid(row=5, column=5, padx=5, pady=5, sticky=E)
start.mainloop()
I do not understand how you write code. You are using too many duplicates. I will not going to explain to you. In line 51 and 54 , I changed command to None. You can replace it.
Here is code:
from tkinter import *
start = Tk()
start.geometry("800x500")
start.configure(bg="lightblue")
start.title("Bibliotekapp")
def menu():
start.geometry("500x500")
start.title("Bibliotekapp")
start.configure(bg="red")
def Register():
start.geometry("800x800")
start.configure(bg="yellow")
start.title("Bibliotekapp Login")
def Submit():
elev = open("bruker.txt", "r")
sjekk = elev.read()
if brukeridinc.get() in sjekk:
informasjon.set("User already exists")
else:
elev.close()
elev = open("bruker.txt", "a")
elev.write(brukeridinc.get() + "")
elev.write(fornavn.get() + "")
elev.write(etternavn.get() + "\n")
elev.close()
informasjon.set("You are started")
####### GUI ############
label_brukerid = Label(start, text="Brukerid:", bg="white", font=("Arial", 25))
label_brukerid.grid(row=1, column=0, padx=5, pady=5, sticky=E)
label_fornavn = Label(start, text="Fornavn:", bg="white", font=("Arial", 25))
label_fornavn.grid(row=2, column=0, padx=5, pady=5, sticky=E)
label_etternavn = Label(start, text="Etternavn:", bg="white", font=("Arial", 25))
label_etternavn.grid(row=3, column=0, padx=5, pady=5, sticky=E)
brukeridinc= StringVar()
entry_brukerid= Entry(start, width=10, textvariable=brukeridinc, font=("Arial", 25))
entry_brukerid.grid(row=1, column=1, padx=5, pady=5, sticky=W)
fornavn= StringVar()
entry_fornavn= Entry(start, width=10, textvariable=fornavn, font=("Arial", 25))
entry_fornavn.grid(row=2, column=1, padx=5, pady=5, sticky=W)
etternavn= StringVar()
entry_etternavn= Entry(start, width=10, textvariable=etternavn, font=("Arial", 25))
entry_etternavn.grid(row=3, column=1, padx=5, pady=5, sticky=W)
button_start = Button(start, text="start", bg="white", font=("Arial", 25), command=Submit)
button_start.grid(row=5, column=5, padx=5, pady=5, sticky=E)
button_login = Button(start, text="Login", bg="white", font=("Arial", 25), command=menu)
button_login.grid(row=6, column=5, padx=5, pady=5, sticky=E)
button_lån = Button(start, text="Lån", bg="white", font=("Arial", 25), command=Register)
button_lån.grid(row=7, column=5, padx=5, pady=5, sticky=E)
informasjon= StringVar()
entry_informasjon= Entry(start, width=24, textvariable=informasjon, state="readonly", font=("Arial", 25))
entry_informasjon.grid(row=5, column=1, padx=5, pady=5, sticky=W)
start.mainloop()
Result:
Result Red:
Result for yellow:

How do I fix this strange exception : Exception in Tkinter callback

I am working on a YouTube downloader project that takes a link and then puts the information about the video quality and sound quality of the link in the Combobox.
But when I try to put audio and video information in the Combobox, it gives this exception:
This is my code :
import tkinter
import tkinter.ttk
from tkinter import *
from tkinter import filedialog
from os import path
import pafy
from pafy import *
class Youtube():
def __init__(self):
self.label()
self.entry()
self.button()
self.combobox()
self.data=[]
def label(self):
Label(window, text='URL', font='bold').grid(row=0, column=0, padx=100)
Label(window, text='Destination', font='bold').grid(row=2, column=0, padx=100)
Label(window, text='File Name', font='bold').grid(row=4, column=0, padx=100)
Label(window, text='Video Quality', font='bold').grid(row=6, column=0, pady=20)
Label(window, text='Audio Quality', font='bold').grid(row=7, column=0, pady=5)
Label(window, text='Download Type', font='bold').grid(row=8, column=0, pady=15)
Label(window, text='Combine AV', font='bold').grid(row=8, column=1)
def entry(self):
global een
global en
en=Entry(window, width=35, borderwidth=10)
en.grid(row=1, column=0, padx=100, pady=5)
een=Entry(window, width=35, borderwidth=10)
een.grid(row=3, column=0, padx=100, pady=5)
Entry(window, width=35, borderwidth=10).grid(row=5, column=0, padx=100, pady=5)
def button(self):
Button(window, text='i', height=1, width=3, command=self.information).grid(row=1, column=1)
Button(window, text='d', height=1, width=3, command=self.destination).grid(row=3, column=1)
Button(window, text='Download', font='bold').grid(row=12, column=0, padx=150, pady=10, columnspan=3)
def combobox(self):
tkinter.ttk.Combobox(window, width=15).grid(row=6, column=1)
tkinter.ttk.Combobox(window, width=15).grid(row=7, column=1, pady=5)
tkinter.ttk.Combobox(window, values=['Audio only', 'Vido only', 'Audio and vido'],
width=15).grid(row=9, column=0)
tkinter.ttk.Combobox(window, values=['Yes', 'No'], width=15).grid(row=9, column=1, pady=20)
tkinter.ttk.Progressbar(window, orient=HORIZONTAL, length=300,
mode='determinate').grid(row=11, column=0, padx=200, pady=10, columnspan=3)
def destination(self):
path = str(filedialog.askdirectory())
een.insert(tkinter.END, path)
def information(self):
global link
link = en.get()
self.video()
self.audio()
def video(self):
video_quality_list = []
self.data = pafy.new(link)
video_streams = self.data.videostreams
for video_quality in video_streams:
video_quality_list.append(video_quality)
tkinter.ttk.Combobox(window, values=video_quality_list, width=15).grid(row=6, column=1, pady=5)
def audio(self):
audio_quality_list = []
self.data = pafy.new(link)
audio_streams = self.data.audiostreams
for audio_quality in audio_streams:
audio_quality_list.append(audio_quality)
tkinter.ttk.Combobox(window, values=audio_quality_list, width=15).grid(row=7, column=1)
window = Tk()
mywin = Youtube()
window.title('Youtube Downloader')
window.geometry("700x600+10+10")
window.mainloop()
I would be very grateful if anyone could help me to fix it.
Thanks!

Getting multiple results with one button (python/ tkiner)

I'm a beginner, and I've gathered a number of reference sites to make code!
But if you click the button, you'll see the value only for the last item.
Do you happen to know how to get each result in every row! And now you have to enter all the items to get the value, but even if there is a blank, I hope the result will come out for all the input boxes.
I think the code is a little tangled, but it's hard to solve. I'm posting the code's full text.
from tkinter import *
from tkinter import ttk
import csv
class App(ttk.Frame):
num_rows = 2
entry_list = []
def __init__(self, master, *args, **kwargs):
ttk.Frame.__init__(self, master, *args, **kwargs)
self.master = master
self.label_frame = ttk.Frame(self.master)
self.label_frame.grid()
self.label_list = []
label1 = Label(root, width=5, text="No.")
label2 = Label(root, width=12, text="Chip")
label3 = Label(root, width=12, text="Length[mm] : ")
label4 = Label(root, width=12, text="Width[mm] : ")
label5 = Label(root, width=12, text="Height[mm] : ")
label6 = Label(root, width=12, text="Watt[W] : ")
label7 = Label(root, width=12, text="Rjc[C/W] : ")
label8 = Label(root, width=12, text="h[W/㎡K] : ")
label9 = Label(master, width=12, text="Temp[C] : ",fg='red')
#grid
label1.grid(row=0, column=0, padx=1, pady=10)
label2.grid(row=0, column=1, padx=2, pady=10)
label3.grid(row=0, column=2, padx=2, pady=10)
label4.grid(row=0, column=3, padx=2, pady=10)
label5.grid(row=0, column=4, padx=2, pady=10)
label6.grid(row=0, column=5, padx=2, pady=10)
label7.grid(row=0, column=6, padx=2, pady=10)
label8.grid(row=0, column=7, padx=2, pady=10)
label9.grid(row=0, column=8, padx=2, pady=10)
##유동
self.Number_field = Entry(root, width=5)
self.Length_field = Entry(root, width=9)
self.Width_field = Entry(root, width=9)
self.Height_field = Entry(root, width=9)
self.Watt_field = Entry(root, width=9)
self.Rjc_field = Entry(root, width=9)
self.Temperature_field = Entry(root, width=9)
self.Number_field.grid(row=1, column=0, padx=1, pady=1)
self.Length_field.grid(row=1, column=2, padx=1, pady=1)
self.Width_field.grid(row=1, column=3, padx=1, pady=1)
self.Height_field.grid(row=1, column=4, padx=1, pady=1)
self.Watt_field.grid(row=1, column=5, padx=1, pady=1)
self.Rjc_field.grid(row=1, column=6, padx=1, pady=1)
self.Temperature_field.grid(row=1, column=8, padx=1, pady=1)
strs = StringVar()
strs2 = StringVar()
combx1 = ttk.Combobox(root, width=9, textvariable=strs)
combx1['values'] = (' Natural', ' Forced(Fan)')
combx1.current()
combx1.grid(column=7, row=1)
combx2 = ttk.Combobox(root, width=9, textvariable=strs2)
combx2['values'] = ('CPU', 'eMMC', 'PMIC')
combx2.grid(column=1, row=1)
combx2.current()
# Create a Submit Button and attached
button1 = Button(root, text="Submit", bg="black", fg="white", command=self.cal_Temp)
button1.grid(row=100, column=0, pady=10)
button2 = Button(root, text="Clear", fg="blue", command=self.clear_all)
button2.grid(row=100, column=1, pady=10)
button3 = Button(root, text="Add Row (+)", command=self.add_new)
button3.grid(row=102, column=0, pady=10)
button4 = Button(root, text="Delete Row (-)", command=self.delete)
button4.grid(row=102, column=1, pady=10)
button5 = Button(root, text="Export", command=self.writeToFile)
button5.grid(row=103, column=1, pady=10)
def writeToFile(self):
with open('Temperature_MJH.csv', 'a') as f:
w=csv.writer(f, quoting=csv.QUOTE_ALL)
w.writerow([self.Length_field.get()])
w.writerow([self.Width_field.get()])
w.writerow([self.Height_field.get()])
w.writerow([self.Watt_field.get()])
w.writerow([self.Rjc_field.get()])
w.writerow([self.Temperature_field.get()])
def clear_all(self):
self.Number_field.delete(0,END)
self.Length_field.delete(0, END)
self.Width_field.delete(0, END)
self.Height_field.delete(0, END)
self.Watt_field.delete(0, END)
self.Rjc_field.delete(0, END)
self.Temperature_field.delete(0, END)
#이거 지워도 되는지
self.Length_field.focus_set()
def cal_Temp(self):
Length = float(self.Length_field.get())
Width = float(self.Width_field.get())
Height = float(self.Height_field.get())
Watt = float(self.Watt_field.get())
Rjc = float(self.Rjc_field.get())
h = 1
Temperature = float(((Watt * 0.5) / (((Length * Width * 2) + (Length * 2) + (
Height * Width * 5)) / 1000)) / h + Rjc )
self.Temperature_field.insert(10,Temperature)
print(Temperature)
def add_new(self):
self.num_rows += 1
self.Number_field = Entry(root, width=5)
self.Length_field = Entry(root, width=9)
self.Width_field = Entry(root, width=9)
self.Height_field = Entry(root, width=9)
self.Watt_field = Entry(root, width=9)
self.Rjc_field = Entry(root, width=9)
self.Temperature_field = Entry(root, width=9)
self.Number_field.grid(row=self.num_rows, column=0, padx=1, pady=1)
self.Length_field.grid(row=self.num_rows, column=2, padx=1, pady=1)
self.Width_field.grid(row=self.num_rows, column=3, padx=1, pady=1)
self.Height_field.grid(row=self.num_rows, column=4, padx=1, pady=1)
self.Watt_field.grid(row=self.num_rows, column=5, padx=1, pady=1)
self.Rjc_field.grid(row=self.num_rows, column=6, padx=1, pady=1)
self.Temperature_field.grid(row=self.num_rows, column=8, padx=1, pady=1)
strs = StringVar()
strs2 = StringVar()
self.combx1 = ttk.Combobox(root, width=9, textvariable=strs)
self.combx1['values'] = (' Natural', ' Forced(Fan)')
self.combx1.current()
self.combx1.grid(row=self.num_rows, column=7)
self.combx2 = ttk.Combobox(root, width=9, textvariable=strs2)
self.combx2['values'] = ('CPU', 'eMMC', 'PMIC')
self.combx2.grid(row=self.num_rows, column=1)
self.combx2.current()
self.ics=self.num_rows
self.Number_field.insert(10, self.ics-1)
def delete(self):
self.num_rows -= 1
self.Number_field.destroy()
self.Length_field.destroy()
self.Width_field.destroy()
self.Height_field.destroy()
self.Watt_field.destroy()
self.Rjc_field.destroy()
self.Temperature_field.destroy()
self.combx1.destroy()
self.combx2.destroy()
self.ics -= 1
if __name__ == "__main__":
root = Tk()
root.configure(background='snow')
root.geometry("1000x450")
root.title("Expectation of Temp Calculator")
my_app = App(root)
root.mainloop()

Python big space between Button columns

I want to set my buttons in my Tk window close to each other, but there is too much space between them. They actually have to sit very close to each other, but i can't change their position.
Code:
from tkinter import *
from tkinter import ttk
def Page():
Profile = Tk()
TreeSearchbar = Text(Profile, width=30, height=1, font="Arial 15")
TreeSearchbar.grid(row=0, column=0, sticky=W, pady=5, columnspan=2)
TreeSearchButton = ttk.Button(Profile, text="Search").grid(row=0, column=1, sticky=W, columnspan=2)
Tree = ttk.Treeview(Profile, height=20)
Tree["columns"] = ("value1", "value2", "value3", "value4", "value5", "value6")
Tree.column("#0", width=170)
Tree.column("#1", width=180)
Tree.column("#2", width=0)
Tree.heading("#0", text="1")
Tree.heading("#1", text="2")
Tree.grid(row=1, column=0, sticky="nw", columnspan=2)
Button1 = ttk.Button(Profile, text="Delete").grid(row=2, column=0, sticky=W, pady=12, padx=(20, 0))
Button2 = ttk.Button(Profile, text="Update").grid(row=2, column=1, sticky=W)
Button3 = ttk.Button(Profile, text="Edit").grid(row=2, column=2, sticky=W)
Profile.mainloop()
Page()
Using frames inside your grid cells you will be able to pack controls. That will give you more flexibility in the layout, like this:
from tkinter import *
from tkinter import ttk
def Page():
Profile = Tk()
TreeSearchbar = Text(Profile, width=30, height=1, font="Arial 15")
TreeSearchbar.grid(row=0, column=0, sticky=W, pady=5, columnspan=2)
TreeSearchButton = ttk.Button(Profile, text="Search").grid(row=0, column=1, sticky=W, columnspan=2)
Tree = ttk.Treeview(Profile, height=20)
Tree["columns"] = ("value1", "value2", "value3", "value4", "value5", "value6")
Tree.column("#0", width=170)
Tree.column("#1", width=180)
Tree.column("#2", width=0)
Tree.heading("#0", text="1")
Tree.heading("#1", text="2")
Tree.grid(row=1, column=0, sticky="nw", columnspan=2)
ButtonFrame = ttk.Frame(Profile)
Button1 = ttk.Button(ButtonFrame,
text="Delete").pack(side=LEFT, padx=5, pady=5)
Button2 = ttk.Button(ButtonFrame,
text="Update").pack(side=LEFT, padx=5, pady=5)
Button3 = ttk.Button(ButtonFrame,
text="Edit").pack(side=LEFT, padx=5, pady=5)
ButtonFrame.grid(row=2, column=0)
Profile.mainloop()
Page()
You should grid your areas in the UI and probably apply this principle in each of them, using either grid again, or packer, inside them (although you can use placer it is usually not recommended, to be able to adjust to window size...)

Python tkinter, clearing an Entry widget from a class

This is the class I'm calling and the function from a different file
class CalcFunc:
def clearScreen(self):
self.log("CLEAR (CE)")
ent.delete(0, END)
This is the Entry Box
ent = Entry(root, textvariable=clc.getBtn, justify=RIGHT, font=10, relief=RIDGE, bd=2, width=15)
ent.grid(row=0, columnspan=3, pady=10)
This is the button I'm clicking to clear the Entry Box
buttonCC = Button(root, text="CLEAR (CE)", height=1, width=20, bg='orange', command=clc.clearScreen)
I'm not sure what the syntax is to be able to to clear an Entry widget from a class basically. That code worked when I had it in the same file but my project requires it to be in a separate file. It's a class project for a calculator and the "clear" button clears the Entry widget. I can post my entire code if that helps. Thank you.
----EDIT----
My Class
import time
class CalcFunc:
def log(self, val):
myFile = open(r".\log.dat", "a")
myFile.write("%s\n" % val)
myFile.close()
def onScreen(self, iVal):
self.log(iVal)
currentTxt = self.getBtn.get()
updateEnt = self.getBtn.set(currentTxt + iVal)
def clearScreen(self):
self.log("CLEAR (CE)")
ent.delete(0, END)
def evaL(self):
self.log("=")
self.getBtn.set(str(eval(self.getBtn.get())))
self.log(self.getBtn.get())
def logLbl(self):
myFile = open(r".\log.dat", "a")
myFile.write("\n==================================\n")
myFile.write("Date: " + str(time.strftime("%m/%d/%Y")) + " -- Time: " + str(time.strftime("%I:%M:%S")))
myFile.write("\n==================================\n")
myFile.close()
My Program
from tkinter import *
import time
import clcClass
root = Tk()
root.title('skClc v1')
clc = clcClass.CalcFunc()
clc.logLbl()
clc.getBtn = StringVar()
ent = Entry(root, textvariable=clc.getBtn, justify=RIGHT, font=10, relief=RIDGE, bd=2, width=15)
ent.grid(row=0, columnspan=3, pady=10)
button1 = Button(root, text="1", height=1, width=5, bg='light blue', command=lambda:clc.onScreen('1'))
button2 = Button(root, text="2", height=1, width=5, bg='light blue', command=lambda:clc.onScreen('2'))
button3 = Button(root, text="3", height=1, width=5, bg='light blue', command=lambda:clc.onScreen('3'))
button4 = Button(root, text="4", height=1, width=5, bg='light blue', command=lambda:clc.onScreen('4'))
button5 = Button(root, text="5", height=1, width=5, bg='light blue', command=lambda:clc.onScreen('5'))
button6 = Button(root, text="6", height=1, width=5, bg='light blue', command=lambda:clc.onScreen('6'))
button7 = Button(root, text="7", height=1, width=5, bg='light blue', command=lambda:clc.onScreen('7'))
button8 = Button(root, text="8", height=1, width=5, bg='light blue', command=lambda:clc.onScreen('8'))
button9 = Button(root, text="9", height=1, width=5, bg='light blue', command=lambda:clc.onScreen('9'))
button0 = Button(root, text="0", height=1, width=5, bg='light blue', command=lambda:onScreen('0'))
buttonP = Button(root, text="+", height=1, width=5, bg='gray', command=lambda:clc.onScreen('+'))
buttonM = Button(root, text="-", height=1, width=5, bg='gray', command=lambda:clc.onScreen('-'))
buttonMM = Button(root, text="x", height=1, width=5, bg='gray', command=lambda:clc.onScreen('*'))
buttonDD = Button(root, text="÷", height=1, width=5, bg='gray', command=lambda:clc.onScreen('/'))
buttonEE = Button(root, text="=", height=1, width=5, bg='light green', command=clc.evaL)
buttonCC = Button(root, text="CLEAR (CE)", height=1, width=20, bg='orange', command=clc.clearScreen)
button1.grid(row=1, column=0, pady=5)
button2.grid(row=1, column=1, pady=5)
button3.grid(row=1, column=2, pady=5)
button4.grid(row=2, column=0, pady=5)
button5.grid(row=2, column=1, pady=5)
button6.grid(row=2, column=2, pady=5)
button7.grid(row=3, column=0, pady=5)
button8.grid(row=3, column=1, pady=5)
button9.grid(row=3, column=2, pady=5)
button0.grid(row=4, column=0, pady=5)
buttonP.grid(row=4, column=1, pady=5)
buttonM.grid(row=4, column=2, pady=5)
buttonEE.grid(row=5, column=0, pady=5)
buttonDD.grid(row=5, column=1, pady=5)
buttonMM.grid(row=5, column=2, pady=5)
buttonCC.grid(row=6, column=0, pady=5, columnspan=3)
root.maxsize(140,245);
root.minsize(140,245);
root.mainloop()
ent = Entry(root, ....)
clc = clcClass.CalcFunc(ent)
class CalcFunc:
def __init__(self, entry):
self.entry = entry
def clearScreen(self):
self.log("CLEAR (CE)")
self.entry.delete(0, END)
Here's an abbreviated example:
#my_entry.py
from tkinter import END
import time
class EntryWithLogger:
def __init__(self, entry):
self.entry = entry
def log(self, val):
with open("log.dat", "a") as my_file: #Automatically closes the file--even if an exception occurs, which is not the case with my_file.close().
my_file.write("%s\n" % val)
def onScreen(self, i_val):
self.log(i_val)
self.entry.insert(END, i_val)
def clearScreen(self):
self.log("CLEAR (CE)")
self.entry.delete(0, END)
Note that I didn't use a StringVar(), which doesn't appear to be necessary. If you need it, you can always pass it as an argument to __init__(), then store it on self.
import my_entry as me
import tkinter as tk
root = tk.Tk()
root.title("Calculator")
root.geometry("+100+50") #("300x500+200+10") dimension, position
entry = tk.Entry(root, justify=tk.RIGHT, font=10, relief=tk.RIDGE, bd=2, width=15)
entry.grid(row=0, columnspan=3, pady=10)
entry_with_logger = me.EntryWithLogger(entry)
#Create the buttons in a loop:
for i in range(10):
row_num, col_num = divmod(i, 3) #divmod(7, 2) => (3, 1), divmod(0, 3) => (0, 0), divmod(4, 3) => (1, 1)
row_num += 1
button_text = str(i)
tk.Button(root, text=button_text,
height=1,
width=5,
bg='light blue',
command=lambda x=button_text: entry_with_logger.onScreen(x)
).grid(row=row_num, column=col_num, pady=5)
#Put the clear button at the bottom of the grid:
tk.Button(root, text="CLEAR (CE)",
height=1,
width=20,
bg='orange',
command=entry_with_logger.clearScreen
).grid(row=row_num+1, columnspan=3) #columnspan tells grid() to use 3 cells for the button,
#and the button will be centered by default.
root.mainloop()
Or, you could do it like this:
#my_entry.py
from tkinter import Entry, END
import time
class EntryWithLogger(Entry):
#Because __init__() is not implemented, the parent class's __init__() gets
#called, so you create an EntryWithLogger just like you would an Entry.
def log(self, val):
with open("log.dat", "a") as my_file: #Automatically closes the file--even if there is an exception, which is not the case with my_file.close().
my_file.write("%s\n" % val)
def onScreen(self, i_val):
self.log(i_val)
self.insert(END, i_val)
def clearScreen(self):
self.log("CLEAR (CE)")
self.delete(0, END)
import my_entry as me
import tkinter as tk
root = tk.Tk()
root.title("Calculator")
root.geometry("+100+50") #("300x500+200+10") dimension, position
entry = me.EntryWithLogger(root, justify=tk.RIGHT, font=10, relief=tk.RIDGE, bd=2, width=15)
entry.grid(row=0, columnspan=3, pady=10)
#Create the buttons in a loop:
for i in range(10):
row_num, col_num = divmod(i, 3) #divmod(7, 2) => (3, 1), divmod(0, 3) => (0, 0), divmod(4, 3) => (1, 1)
row_num += 1
button_text = str(i)
tk.Button(root, text=button_text,
height=1,
width=5,
bg='LightBlue',
command=lambda x=button_text: entry.onScreen(x)
).grid(row=row_num, column=col_num, pady=5)
#Put the clear button at the bottom of the grid:
tk.Button(root, text="CLEAR (CE)",
height=1,
width=20,
bg='orange',
command=entry.clearScreen
).grid(row=row_num+1, columnspan=3) #columnspan tells grid() to use 3 cells for the button,
#and the button will be centered by default.
root.mainloop()

Categories