Add labels to the top of a tkinter grid? - python

The point of this is to press a button and have new rows appear but currently, titles appear above each new row that is added. Instead, I would like to have one row at the top of the grid with column titles. Is there a way to modify this code I already have? Later, I will be incorporating this into a larger tkinter GUI.
from tkinter import *
#------------------------------------
def addbox():
frame =Frame(root)
frame.pack()
#Item
Label(frame, text="Item").grid(row=0, column=0)
ent1 = Entry(frame, width=10)
ent1.grid(row=2, column=0)
#Day
Label(frame, text="Day").grid(row=0, column=1)
ent2 = Entry(frame, width=10)
ent2.grid(row=2, column=1)
#Code
ent3 = Entry(frame, width=10)
ent3.grid(row=2, column=2)
#Factor
ent4 = Entry(frame, width=10)
ent4.grid(row=2, column=3)
all_entries.append( (ent1, ent2, ent3, ent4) )
#Buttons.
showButton = Button(frame, text='Print', command=refresh)
addboxButton = Button(frame, text='Add Item', fg="Red", command=addbox)
#------------------------------------
def refresh():
for number, (ent1, ent2, ent3, ent4) in enumerate(all_entries):
print (number, ent1.get(), ent2.get(), ent3.get(),ent4.get())
#------------------------------------
all_entries = []
root = Tk()
addboxButton = Button(root, text='Add Instrument', fg="Red", command=addbox)
addboxButton.pack()
root.mainloop()

You can check the row count before you add the label:
if len(all_entries) < 1:
Label(frame, text="Item").grid(row=0, column=0)

Related

how to update getting results from an entry box automatically?

I want to update getting results from an entry box in a way that when an integer enters, the equivalent rows of entry boxes appear below that. I have written the below code to make it work using a button. However, I want to make it happen automatically without a button as I entered the number, the rows update. I checked one way of doing that is using the after(). I placed after after() in the function and out of the function but it is not working.
from tkinter import *
root = Tk()
root.geometry("400x400")
n_para = IntVar()
label1 = Label(root, text="Numeric parameters")
label1.grid(row=0, column=0)
entry1 = Entry(root, textvariable=n_para)
entry1.grid(row=0, column=1)
def update():
for i in range(1, n_para.get()+1):
entryX = Entry(root)
entryX.grid(row=i+1, column=0)
entryY = Entry(root)
entryY.grid(row=i+1, column=1)
entryZ = Entry(root)
entryZ.grid(row=i+1, column=2)
root.after(100, update)
root.after(1, update)
button1 = Button(root, text="update", command=update)
button1.grid(row=1, column=0)
root.mainloop()
You should try using the <KeyRelease> event bind.
import tkinter as tk
def on_focus_out(event):
label.configure(text=inputtxt.get())
root = tk.Tk()
label = tk.Label(root)
label.pack()
inputtxt = tk.Entry()
inputtxt.pack()
root.bind("<KeyRelease>", on_focus_out)
root.mainloop()
This types the text entered in real-time.
Edited Code with OP's requirement:
from tkinter import *
root = Tk()
root.geometry("400x400")
n_para = IntVar()
label1 = Label(root, text="Numeric parameters")
label1.grid(row=0, column=0)
entry1 = Entry(root, textvariable=n_para)
entry1.grid(row=0, column=1)
def upd(event):
x = entry1.get()
if not x.isnumeric():
x = 0
for i in range(1, int(x)+1):
entryX = Entry(root)
entryX.grid(row=i+1, column=0)
entryY = Entry(root)
entryY.grid(row=i+1, column=1)
entryZ = Entry(root)
entryZ.grid(row=i+1, column=2)
# root.after(100, update)
root.bind("<KeyRelease>", upd)
# button1 = Button(root, text="update", command=update)
# button1.grid(row=1, column=0)
root.mainloop()

Parameters passed to a function does not works as intended

When the "view" button is pressed, it should trigger the function solution(i) such that label should be displayed in the new window. The problem is that the window opens and the previous label is packed but the label which gets it's text from "i" does not gets packed, Is there any issue in passing the parameter.
Any help is appreciated.
root = Tk()
root.config(background = "#303939")
root.state('zoomed')
def pre():
with open("DoubtSolution.txt","r+") as f:
dousol = f.read()
dousol_lst = dousol.split("`")
k = 0
window = Tk()
window.config(background = "#303939")
window.state('zoomed')
predoubt = Label(window,
text="Previous Doubts",
fg="Cyan",
bg="#303939",
font="Helvetica 50 bold"
).grid(row=0, column=1)
def solution(text):
print(text)
window1 = Tk()
window1.config(background="#303939")
window1.state('zoomed')
sol = Label(window1,
text=text[:text.find("~")],
font=font.Font(size=20),
bg="#303939",
fg="Cyan")
sol.pack()
window1.mainloop()
for i in dousol_lst:
if i[-5:] == admno:
doubt = Label(window, text=i[i.find("]]")+2:i.find("}}}}")], font=font.Font(size=20), bg="#303939",
fg="Cyan")
doubt.grid(row=2+k, column=1, pady=10)
view = Button(
master=window,
text="View", font=font.Font(size=15, family="Helvetica"),
activebackground="White",
bg="Teal",
bd=0.8,
fg="White",
command = lambda k = k:solution(i)
)
view.grid(row=2+k, column=2, padx=20)
k=k+1
window.mainloop()
previous = Button(
master=root,
text="Previous Doubts", font="Helvetica 22 bold",
activebackground="White",
bg="Teal",
bd=0.8,
fg="White",
command = pre
).grid(row=4, column=3, padx=20)
root.mainloop()

How can I remove items on a Tkinter window?

I am trying to clear the items on the window without closing the root window just the items visible.While everything is deleted Some of the labels are still left.I created a button "close" to remove the items.My code is as below;
from tkinter import*
root = Tk()
root.geometry("480x480")
# Node
myLabel1 = Label(root, text=f'Node')
myLabel1.grid(row=0, column=0)
rows = [] # show the input entry boxes
for i in range(6):
# name
entry = Entry(root, width=5, bd=5)
entry.grid(row=2+i, column=0)
# x
myLabel2 = Label(root, text=f'x{i}')
myLabel2.grid(row=2+i, column=1)
entry_x = Entry(root, width=5, bd=5)
entry_x.grid(row=2+i, column=2)
# y
myLabel3 = Label(root, text=f'y{i}')
myLabel3.grid(row=2+i, column=3)
entry_y = Entry(root, width=5, bd=5)
entry_y.grid(row=2+i, column=4)
# save current input row
rows.append((entry, entry_x, entry_y))
def close():
for name,ex,ey in rows:
name.destroy()
ex.destroy()
ey.destroy()
myLabel3.destroy()
myLabel2.destroy()
myLabel1.destroy()
myButton_close.destroy()
myButton_close = Button(root, text="close",padx = 10,pady = 10, command=close)
myButton_close.grid(row=8, column=6)
root.mainloop()
where could i be going wrong?
Create a Frame to hold the widgets and then you can destroy the frame to clear the window:
from tkinter import *
root = Tk()
root.geometry("480x480")
frame = Frame(root)
frame.pack(fill=BOTH, expand=1)
# Node
myLabel1 = Label(frame, text=f'Node')
myLabel1.grid(row=0, column=0)
rows = [] # store the input entry boxes
for i in range(6):
# name
entry = Entry(frame, width=5, bd=5)
entry.grid(row=2+i, column=0)
# x
myLabel2 = Label(frame, text=f'x{i}')
myLabel2.grid(row=2+i, column=1)
entry_x = Entry(frame, width=5, bd=5)
entry_x.grid(row=2+i, column=2)
# y
myLabel3 = Label(frame, text=f'y{i}')
myLabel3.grid(row=2+i, column=3)
entry_y = Entry(frame, width=5, bd=5)
entry_y.grid(row=2+i, column=4)
# save current input row
rows.append((entry, entry_x, entry_y))
def close():
frame.destroy()
myButton_close = Button(frame, text="close", padx=10, pady=10, command=close)
myButton_close.grid(row=8, column=6)
root.mainloop()
Grouping widgets into a frame make it easier to clear certain part of the window.
You create the labels in a loop but you are not saving any reference to the labels except for the last myLabel2/3. However you can ask a widget about its children, and then destroy them all:
def close():
for widget in root.winfo_children():
widget.destroy()

how to place frames in tkinter to display the data in a table?

I need to display the data in a table using frames or grid in tkinter.
I have displayed the data in the tkinter window but i want to place in a table, so can anyone help me with the code (and also the scroll bar)..
here is the code :
def allClub():
data=cursor.execute("SELECT * from CLUBS order by club_name")
master = Tk()
master.geometry('500x500')
master.title('CLUBS')
Label1 = Label(master, text="CLUB ID", width=10)
Label1.grid(row=0, column=0)
Label2 = Label(master, text="CLUB NAME", width=10)
Label2.grid(row=0, column=1)
Label3 = Label(master, text="RATING", width=10)
Label3.grid(row=0, column=2)
Label1 = Label(master, text="MANAGER", width=10)
Label1.grid(row=0, column=3)
Label1 = Label(master, text="CHAIRMAN", width=10)
Label1.grid(row=0, column=4)
Label1 = Label(master, text="LEAGUE", width=15)
Label1.grid(row=0, column=5)
Label1 = Label(master, text="TITLES", width=10)
Label1.grid(row=0, column=6)
Label1 = Label(master, text="YEAR FOUNDED", width=10)
Label1.grid(row=0, column=7)
for index, dat in enumerate(data):
Label(master, text=dat[0]).grid(row=index+1, column=0)
Label(master, text=dat[1]).grid(row=index+1, column=1)
Label(master, text=dat[2]).grid(row=index+1, column=2)
Label(master, text=dat[3]).grid(row=index+1, column=3)
Label(master, text=dat[4]).grid(row=index+1, column=4)
Label(master, text=dat[5]).grid(row=index+1, column=5)
Label(master, text=dat[6]).grid(row=index+1, column=6)
Label(master, text=dat[7]).grid(row=index+1, column=7)
link for screenshot of output window here:
https://i.stack.imgur.com/zFymD.jpg
Tkinter doesn't have any "table" widget and if you are planning to have a lot of rows and columns, the best thing you could use is a Treeview or Listbox.
On the other hand you cant create a scrollbar for Frame because the documentation for that widget doesn't say it supports scrolling. There is a solution for this problem that involves creating a canvas and you can check it out here.
Here is an example of Treeview widget:
from tkinter import *
from tkinter import ttk
root = Tk()
root.geometry("500x200")
data = [ ["val1", "val2", "val3"],
["asd1", "asd2", "asd3"],
["bbb1", "bbb3", "bbb4"],
["ccc1", "ccc3", "ccc4"],
["ddd1", "ddd3", "ddd4"],
["eee1", "eee3", "eee4"] ]
frame = Frame(root)
frame.pack()
tree = ttk.Treeview(frame, columns = (1,2,3), height = 5, show = "headings")
tree.pack(side = 'left')
tree.heading(1, text="Column 1")
tree.heading(2, text="Column 2")
tree.heading(3, text="Column 3")
tree.column(1, width = 100)
tree.column(2, width = 100)
tree.column(3, width = 100)
scroll = ttk.Scrollbar(frame, orient="vertical", command=tree.yview)
scroll.pack(side = 'right', fill = 'y')
tree.configure(yscrollcommand=scroll.set)
for val in data:
tree.insert('', 'end', values = (val[0], val[1], val[2]) )
root.mainloop()
# One way to make a table is to use a loop for the Entry class.
import tkinter as tk
win=tk.Tk()
win.title('Tk GUI')
cols=['Col1','Col2','Col3']
data = [ ["val1", "val2", "val3"],
["asd1", "asd2", "asd3"],
["bbb1", "bbb3", "bbb4"],
["ccc1", "ccc3", "ccc4"],
["ddd1", "ddd3", "ddd4"],
["eee1", "eee3", "eee4"] ]
for y in range(len(data)+1):
for x in range(len(cols)):
if y==0:
e=tk.Entry(font=('Consolas 8 bold'),bg='light blue',justify='center')
e.grid(column=x, row=y)
e.insert(0,cols[x])
else:
e=tk.Entry()
e.grid(column=x, row=y)
e.insert(0,data[y-1][x])
win.mainloop()

grid_remove on an Entry widget

Im new to Tkinter and am trying to build a simple GUI using grid manager which upon the push of button1, button2 appears along with an adjacent entry box. If you then press button2 the entry box and button2 dissapear. Below is a slice from the GUI code, the button dissapears but the entry box does not:
import Tkinter
from Tkinter import *
master = Tk()
CreateTestButton = Button(master, text="Create Test", command = CreateTest, fg="red", bg="white", font="Helvetica 10 bold")
CreateTestButton.grid(column=7, row=1)
def CreateTest():
TestEntry = Entry(master, text="", width = 100).grid(row=4,columnspan=6)
Label(self, text="Enter Test Name:").grid(row=3, column=0)
SaveTestButton = Button(master, text="Save to database", command=saveTest, fg="green", bg="white", font="Helvetica 10 bold")
SaveTestButton.grid(row=4, column=5)
def saveTest():
SaveTestButton.grid_remove()
TestEntry.grid_remove() #ERROR
mainloop()
How is one to remove entry boxes using grid manager in Tkinter? And other widgets for that matter I will also be needing to remove a list box, labels and widgets uppon a button click or event.
Regards,
Daniel
grid return nothing; By executing TestEntry = Entry(..).grid(...), TestEntry become None instead of Entry object.
Replace following line:
TestEntry = Entry(self, text="", width = 100).grid(row=4,columnspan=6)
with:
TestEntry = Entry(self, text="", width = 100)
TestEntry.grid(row=4,columnspan=6)
Complete code
from Tkinter import *
def CreateTest():
def saveTest():
SaveTestButton.grid_remove()
TestEntry.grid_remove() #ERROR
TestEntry = Entry(master, text="", width = 100)
TestEntry.grid(row=4,columnspan=6)
Label(master, text="Enter Test Name:").grid(row=3, column=0)
SaveTestButton = Button(master, text="Save to database", command=saveTest, fg="green", bg="white", font="Helvetica 10 bold")
SaveTestButton.grid(row=4, column=5)
master = Tk()
CreateTestButton = Button(master, text="Create Test", command = CreateTest, fg="red", bg="white", font="Helvetica 10 bold")
CreateTestButton.grid(column=7, row=1)
mainloop()

Categories