Parameters passed to a function does not works as intended - python

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()

Related

How to align widgets in Tkinter to center

I am working on a simple counter app in tkinter. I rigged up some code looking at few tutorial on web. All the functions of a counter are set up. But when it comes to the designing of the app, I want the Count, the Count button, and the reset button to be aligned at the center.
The code is as below
from tkinter import Label, Button, Tk
from tkinter import font
window = Tk()
window.geometry('500x500')
window.title("Counter")
window.count = 0
def increment():
window.count += 1
lbl.configure(text=window.count)
def reset():
window.count = 0
lbl.configure(text=window.count)
lbl = Label(window, text="0", font=("Apple Braille", 60))
lbl.grid(column=0, row=0)
btn1 = Button(window, text="Count", command=increment)
btn1.grid(column=0, row=1)
btn2 = Button(window, text="Reset", command=reset)
btn2.grid(column=1, row=1)
btn1['font'] = btn2['font'] = font.Font(size=30)
window.mainloop()
A Screenshot of my counter app is here
Any help in this aspect will be appreciated.
Thanks,
It is easier to use pack() instead of grid() for your requirement.
lbl = Label(window, text="0", font=("Apple Braille", 60))
lbl.pack()
# frame for the two buttons
frame = Frame(window)
frame.pack()
btn1 = Button(frame, text="Count", command=increment)
btn1.grid(column=0, row=1)
btn2 = Button(frame, text="Reset", command=reset)
btn2.grid(column=1, row=1)
If you want to put at the center of the window:
# frame for the label and buttons
frame = Frame(window)
frame.place(relx=0.5, rely=0.5, anchor="c") # put at center of window
lbl = Label(frame, text="0", font=("Apple Braille", 60))
lbl.grid(row=0, column=0, columnspan=2)
btn1 = Button(frame, text="Count", command=increment)
btn1.grid(column=0, row=1)
btn2 = Button(frame, text="Reset", command=reset)
btn2.grid(column=1, row=1)

How to create a mandatory window in tkinter

I am using python 3.7 and tkinter for making a GUI which saves all my important passwords which are saved in a file passwords.txt. In this I want to create a button in my main window which pops up another window with an entry box and a button(which will close the window) and till this window is not closed it will not let the user to interact with my old window.
Here's my codes:
from tkinter import *
from tkinter import ttk
root = Tk()
f = open("passwords.txt", "r")
list1 = []
for item in f.readlines():
item = item.replace("\n", "")
list1.append(item)
def secondwindow():
root2 = Tk()
root2.title("Secure Your Password")
root2.configure(bg="black")
root2.geometry('700x600')
frame_color = "#%02x%02x%02x" % (150,150,150)
# Create A Main frame
main_frame = Frame(root2, bg=frame_color)
main_frame.pack(fill=BOTH,expand=1)
# Create Frame for X Scrollbar
sec = Frame(main_frame, bg=frame_color)
sec.pack(fill=X,side=BOTTOM)
# Create A Canvas
my_canvas = Canvas(main_frame, bg="black")
my_canvas.pack(side=LEFT,fill=BOTH,expand=1)
# Add A Scrollbars to Canvas
x_scrollbar = ttk.Scrollbar(sec,orient=HORIZONTAL,command=my_canvas.xview)
x_scrollbar.pack(side=BOTTOM,fill=X)
y_scrollbar = ttk.Scrollbar(main_frame,orient=VERTICAL,command=my_canvas.yview)
y_scrollbar.pack(side=RIGHT,fill=Y)
# Configure the canvas
my_canvas.configure(xscrollcommand=x_scrollbar.set)
my_canvas.configure(yscrollcommand=y_scrollbar.set)
my_canvas.bind("<Configure>",lambda e: my_canvas.config(scrollregion= my_canvas.bbox(ALL)))
# Create Another Frame INSIDE the Canvas
second_frame = Frame(my_canvas, bg=frame_color)
# Add that New Frame a Window In The Canvas
my_canvas.create_window((0,0),window=second_frame, anchor="nw")
f = Frame(second_frame, borderwidth=2, relief=SUNKEN, bg=frame_color)
f.pack(side=TOP, fill=X)
Label(f, text="Secure Your Password", fg="white", bg=frame_color, font="Algerian 35 italic").pack()
f1 = Frame(second_frame, bg="black")
f1.pack(fill=BOTH, side=TOP, expand=1)
Label(f1, text="Application", fg="red", bg="black", font="Calibri 20 bold", pady=10, padx=60).grid(row=1, column=1)
Label(f1, text="Username", fg="red", bg="black", font="Calibri 20 bold", pady=10, padx=210).grid(row=1, column=2)
Label(f1, text="Password", fg="red", bg="black", font="Calibri 20 bold", pady=10, padx=198).grid(row=1, column=3, padx=140)
for i in range(len(list1)):
application = list1[i].split(";;;")[0]
username = list1[i].split(";;;")[1]
password = list1[i].split(";;;")[2]
Label(f1, text=application, fg="white", bg="black", font="Calibri 20 bold", pady=5).grid(row=i+2, column=1)
Label(f1, text=username, fg="white", bg="black", font="Calibri 20 bold", pady=5).grid(row=i+2, column=2)
Label(f1, text=password, fg="white", bg="black", font="Calibri 20 bold", pady=5).grid(row=i+2, column=3)
root2.mainloop()
def checkPassword(password, l):
if password == "a":
root.destroy()
secondwindow()
else:
l.config(text="Wrong Password")
def password_window():
root.geometry('450x270')
root.title("Secure Your Password")
root.minsize(450, 270)
root.maxsize(450, 270)
root.configure(bg="black")
Label(root, text="Secure Your Password", fg="white", bg="black", font="Algerian 24 italic").pack(side=TOP)
Label(root, text="Your Password", fg="white", bg="black", font="Clibri 15").pack(pady=10)
password = StringVar()
Entry(root, textvariable=password, bg="grey", fg="white", font="Calibri 15 bold").pack(pady=10)
Button(root, text="Login", bg="grey", fg="white", activebackground="grey", font="Calibri 10", command=lambda: checkPassword(password.get(), l)).pack(pady=8)
l = Label(root, fg="red", bg="black", font="Clibri 10 bold")
l.pack()
password_window()
root.mainloop()
And my passwords.txt:
StackOverflow;;;PomoGranade;;;PomoGranade_StackOverflow
GitHub;;;Pomogranade;;;PomoGranade_GitHub
I am new to python and tkinter. Thanks for help in advance :)
I do not recommend using * imports, though it may not be exactly wrong in this case.
Use the TopLevel widget instead of initialising another Tk window. See why using another Tk is not good.
Use .grab_set() (Look at #TheLizzard's link in the comment for a better example)
Look at this example -
import tkinter as tk
root = tk.Tk()
def f1():
top1 = tk.Toplevel(root)
b2 = tk.Button(top1,text='Close New Window',command=top1.destroy)
b2.pack()
top1.grab_set()
b1 = tk.Button(root,text='Create Mandatory Window',command=f1)
b1.pack()
root.mainloop()
If you run this code, you will see that the first window does not react to any mouse press etc... and also you cannot close the first window after opening the new window until the it is closed

Add labels to the top of a tkinter grid?

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)

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()

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