Deleting a Label in Python Tkinter? - python

I am trying to hide everything in this function:
def addHome(self):
Label(self, text = "Would you like to add to your to-do list, or generate a random item?", bg="#efefef").grid(row = 3, columnspan = 2, sticky="W")
self.txtHome = Entry(self)
self.btnAddToIt = Button(self, text = "Add To It!", bg="#efefef")
self.btnAddToIt.grid(row = 4, columnspan = 2)
self.btnAddToIt["command"] = self.addToIt
self.btnRandom = Button(self, text = "Random!", bg="#efefef")
self.btnRandom.grid(row = 5, columnspan = 2)
self.btnRandom["command"] = self.addRandom
So that I can show the things in these functions:
def addToIt(self):
#self.clearMiddle()
Label(self, text = "Add To List").grid(row = 3, columnspan = 2)
self.addInput()
self.btnProcessAdd = Button(self, text = "Add To It!", bg="#efefef")
self.btnProcessAdd.grid(row = 7, column = 0)
self.btnProcessAdd["command"] = self.processAdd
self.btnCancel = Button(self, text = "Cancel", bg="#efefef")
self.btnCancel.grid(row = 7, column = 1)
self.btnCancel["command"] = self.addHome
def addInput(self):
#adds input for add to item page
Label(self, text = "Name of Item:", bg="#efefef", width=50).grid(row=3, column=0)
self.nameOfItem = Entry(self)
self.nameOfItem.grid(row = 3, column = 1)
self.nameOfItem.insert(0, "Be Awesome")
Label(self, text = "Item Category:", bg="#efefef", width=50).grid(row = 4, column = 0, sticky="E")
self.itemCategory = Listbox(self, height = 5)
self.itemCategory.grid(row = 4, column = 1)
self.itemCategory.insert(END, "Fun", "School", "Work", "Exercise", "Other")
Label(self, text = "Other Item Details:", bg="#efefef", width=50).grid(row = 5, column = 0, sticky="E")
self.otherItemDetails = Text(self, width=22, height=3)
self.otherItemDetails.grid(row = 5, column = 1)
Label(self, text = "Due Date (mm/dd/yy):", bg="#efefef", width=50).grid(row = 6, column = 0, sticky="E")
self.dueDate = Entry(self)
self.dueDate.grid(row = 6, column = 1)
self.dueDate.insert(0, "06/19/2013")
Then vice versa when the Cancel button is hit (clearing the things in addToIt and addInput). Is there any way I can do this?

Yes, there is some way. I see you are using grid. So, to hide an object use Object.grid_forget().
Just in case, if you use pack, you can hide an object by Object.pack_forget(). Same thing works with place.
I have some idea, that might come in handy. I recommend you to have all objects you want to hide simultaneously in a single Frame, so you will just use Frame.grid_forget() instead of
Obj1.grid_forget()
Obj2.grid_forget()
Obj3.grid_forget()
.
.
.
Remember that using this will only make any object invisible, but it still exists "within" memory with all its properties.

Related

How do I add things with button in tkinter?

So, what i wanna do is that when i click the button, a new thing to be added to my project.
I have few tabs, and on the second one (WorkExp) I got Company and job description labels, and i want that whenever i click the button it to add new same labels.
it works, the button, but the thing is add the placement on these new labels is the same as old ones.
I tried while and for cycle but i couldnt make any of them work.
What I have tried:
WorkExp = ttk.Frame(Tabs)
Tabs.add(WorkExp, text = "Work Experience")
######################
def AddExp():
Label(WorkExp, text = "Company/Place", padx = 5, pady = 5).grid(row = 3, column = 1)
Label(WorkExp, text="Job Description", padx=5, pady=5).grid(row = 4 , column=1)
Comp2 = Entry(WorkExp).grid(row=3, column=2)
Work2 = Entry(WorkExp).grid(row=4, column=2)
######################
Label(WorkExp, text = "Company/Place", padx = 5, pady = 5).grid(row = 1, column = 1)
Label(WorkExp, text = "Job Description", padx = 5, pady = 5).grid(row = 2, column = 1)
Comp1 = Entry(WorkExp).grid(row = 1, column = 2)
Work1 = Entry(WorkExp).grid(row = 2, column = 2)
Button(WorkExp, text = "Add Experience", command = AddExp).grid(row = 10, column = 1)
import Tkinter as tk
# Now Start From Here
class App(object):
def new_row(self):
# Create widgets -----
new_entry = tk.Entry(root, width=7)
# Put widgets in grid----------
self.num_rows += 1
new_entry.grid(column=0, row=self.num_rows, sticky='WE')
def __init__(self):
self.num_rows = 1
createRow_button = tk.Button(
root, text='New Row', command=self.new_row)
createRow_button.grid()
root = tk.Tk()
app = App()
root.mainloop()

Can i Make Labels Clickable in tkinter and get the Value of label clicked?

I would like user to click on the number's and then the number should change color and i shall be able to capture on what label user has clicked, this form then shall be saved in Text and PDF format..Thanks a mil in advance for any help
from tkinter import *
from tkinter import ttk
from tkinter import messagebox
class Proj_pres:
"""Defininf clickable labels in frame"""
#def fr_lb(self):
def __init__(self,master):
master.title(" Feedback Form")
#master.resizable(False,False)
self.frame_header = ttk.Frame(master, borderwidth = 5, relief ='ridge').grid(sticky = NE)
#self.frame_header.pack()
ttk.Label(self.frame_header, text = " For recording feedback on Autumn(inerm) project presentations",
font=('Arial',16,'bold')).grid(row = 0, column = 0,sticky = NW)
"""Defining new frame"""
self.frame_content = ttk.Frame(master,borderwidth = 5)
self.frame_content.grid(row = 2, column = 0,columnspan = 3, sticky = NW)
"""Adding check buttons for Studio 1 and Studio 2"""
self.chkb1 = IntVar()
self.b1 = ttk.Checkbutton(self.frame_content, text = "UC1Studio1", variable = self.chkb1).grid(row =0,column = 0)
self.chkb2 = IntVar()
self.b2 = ttk.Checkbutton(self.frame_content, text = "UC2Studio2", variable = self.chkb2).grid(row = 0, column = 8,columnspan = 2,stick=W)
"""Adding Labels for Team and Reviewer"""
ttk. Label(self.frame_content, text = "Team Name").grid(row =4, column = 0,sticky = W)
ttk.Label(self.frame_content, text = "Reviewer").grid(row = 4,column = 7, sticky = E)
ttk.Label(self.frame_content).grid(row=2, column=0)
"""Adding Entry Boxes for team name and reviewer"""
ttk.Entry(self.frame_content).grid( row = 4, column = 1,columnspan = 4,sticky = W)
ttk.Entry(self.frame_content).grid( row = 4, column = 8,columnspan = 2, sticky = E)
"""Adding Label and frame for grading info"""
self.frame_info = ttk.Frame(master,borderwidth = 5, relief = 'solid')
self.frame_info.grid(row = 3, column = 0,sticky = NW)
ttk.Label(self.frame_info).grid(row =5,column = 0)
ttk.Label(self.frame_info, text ="Please use the feeedback scale for each of the following criterion, "
"where 5 = excellent and 1 = poor").grid(row = 7, column = 0,sticky = W)
ttk.Label(self.frame_info).grid(row = 6, column =0)
ttk.Label(self.frame_info,text = "OVERVIEW OF PROJECT").grid(row = 8, column = 0, sticky = NW)
ttk.Label(self.frame_info, text = " 5: Well Structured,4: Clear aim, 3:Understandable project "
"view").grid(row = 9, column = 0, sticky = NW)
ttk.Label(self.frame_info, text=" 2: Absent,1: Confused "
"view").grid(row=9, column=5, sticky=NW)
#ttk.Label(self.frame_info, text=" should come here").grid(row=9, column=1, sticky=NW)
"""Adding frame in column 2 for clickable Labels"""
self.frame_clk=ttk.Frame(self.frame_info, borderwidth= 5, relief ='solid')
self.frame_clk.grid(row = 9,column = 2,columnspan = 3,sticky = NW)
self.f1_l5 = StringVar()
l5 = ttk.Label(self.frame_clk,text = " 5 " ,
background = 'white',borderwidth=5,relief= 'ridge',font =('Helvetica',12,'bold'))
#,textvariable = self.f1_l5
l5.grid(row=0,column =1,columnspan =2 )
f1_l4= ttk.Label(self.frame_clk, text=" 4 ",background = 'white',borderwidth=5,relief= 'ridge', font=('Helvetica', 12, 'bold'))
f1_l4.grid(row =0 , column = 3)
f1_l3 = ttk.Label(self.frame_clk, text=" 3 ",background = 'white',borderwidth=5,relief= 'ridge', font=('Helvetica', 12, 'bold'))
f1_l3.grid(row=0, column=4)
f1_l2 = ttk.Label(self.frame_clk, text=" 2 ",background = 'white',borderwidth=5,relief= 'ridge', font=('Helvetica', 12, 'bold'))
f1_l2.grid(row=0, column=5)
f1_l1 = ttk.Label(self.frame_clk, text=" 1 ",background = 'white', borderwidth=5,relief= 'ridge',font=('Helvetica', 12, 'bold'))
f1_l1.grid(row=0, column=6)
#elf.frame_content.pack()
def main():
root = Tk()
proj_pres = Proj_pres(root)
root.mainloop()
if __name__ == '__main__':main()
def clickFunction(event): #event is argument with info about event that triggered the function
global selectedNumber #make the number visible throughout the program, don't need this if you'll just pass it as argument to function
event.widget.config(background = "green") #event.widget is reference to widget that was clicked on and triggered the function
selectedNumber = 7 - event.widget.grid_info()["column"] #grid info is dictionary with info about widget's grid relative to widget, more at http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/grid-methods.html
if(selectedNumber > 5): selectedNumber = 5
print(selectedNumber)
''' if someday you won't use grid, but will use list to store Labels, this is a way to get Label's position
selectedNumber = myLabels.index(event.widget)
'''
l5.bind("<Button-1>", clickFunction)
f1_l4.bind("<Button-1>", clickFunction)
f1_l3.bind("<Button-1>", clickFunction)
f1_l2.bind("<Button-1>", clickFunction)
f1_l1.bind("<Button-1>", clickFunction)
''' Alternative way for making lots of similar widgets, not to mention extending Label class
myLabels = [] #create List to make code more compact and to be able to use loops
for i in range(5, 0, -1):
myLabels.append(ttk.Label(self.frame_clk, text=" " + str(i) + " ",background = 'white',borderwidth=5,relief= 'ridge', font=('Helvetica', 12, 'bold'))
myLabels.bind("<Button-1>", clickFunction)
myLabels[i].grid(row =0 , column = 6 - i)
'''
Here is code you can add below "f1_l1.grid(row=0, column=6)" line (around ln 77). But I think you might need RadioButton for that purpose since it automatically unmarks other options and supports IntVar. More about events: http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/events.html This webpage has excellent (but a bit outdated) documentation.
Btw, there is one quick fix you might want to apply when making programs for yourself. In Python you can add fields to classes and their instances outside their definition. E.g. in your code, you cold have written f1_l1.myNumber = 1 after "creating" it and in clickFunction instead of grid_info() use selectedNumber = event.widget.myNumber. It'd do the thing, but don't tell them I taught you that ;) since it isn't considered good practice adding fields that way.
If you have any more questions feel free to ask.

Tkinter grid method

I'm using Tkinter to create a GUI for my computer science coursework based on steganography. I'm using the .grid() function on the widgets in my window to lay them out, however I can't get this particular part to look how I want it to.
Here's what my GUI currently looks like: http://imgur.com/LNEZtEL
(or just the part with the error).
I want the remaining characters label to sit directly underneath the text entry box, but for some reason row 4 starts a large way down underneath the box. If I label the GUI with columns and rows anchored north west it looks like this: http://imgur.com/a/V7dTW.
If I shrink the image box on the left, it looks how I want, however I don't want the image this small: http://imgur.com/a/0Dudu.
The image box has a rowspan of 2, so what is causing the 4th row to start so low down from the text entry box? Here's roughly what I want the GUI to look like: http://imgur.com/a/ck04A.
Full code:
imageButton = Button(root, text="Add Image", command = add_image)
imageButton.grid(row = 2, columnspan = 2, sticky = W, padx = 30, pady = 20)
steg_widgets.append(imageButton)
image = Image.open("square.jpg")
image = image.resize((250,250))
photo = ImageTk.PhotoImage(image)
pictureLabel = Label(root, image = photo)
pictureLabel.image = photo
pictureLabel.grid(column = 0, row = 3, columnspan = 2, rowspan = 2, padx = 20, pady = (0, 20), sticky = NW)
steg_widgets.append(pictureLabel)
nameLabel = Label(root, text = "Brandon Edwards - OCR Computer Science Coursework 2016/2017")
nameLabel.grid(row = 0, column = 2, columnspan = 2, padx = (0, 20), pady = 10)
steg_widgets.append(nameLabel)
inputTextLabel = Label(root, text = "Enter text:")
inputTextLabel.grid(row = 2, column = 2, sticky = W)
steg_widgets.append(inputTextLabel)
startButton = Button(root, text="Go!", command = start_stega)
startButton.grid(row = 2, column = 2, sticky = E)
steg_widgets.append(startButton)
inputTextBox = Text(root, height = 10, width = 30)
inputTextBox.grid(row = 3, column = 2, sticky = NW)
steg_widgets.append(inputTextBox)
maxCharLabel = Label(root, text = "Remaining characters:")
maxCharLabel.grid(row = 4, column = 2, sticky = NW)
steg_widgets.append(maxCharLabel)
saveButton = Button(root, text="Save Image", command = save_image)
saveButton.grid(row = 2, column = 3, sticky = W)
steg_widgets.append(saveButton)
I recommend breaking your UI down into logical sections, and laying out each section separately.
For example, you clearly have two distinct sections: the image and button on the left, and the other widgets on the right. Start by creating containers for those two groups:
import Tkinter as tk
...
left_side = tk.Frame(root)
right_side = tk.Frame(root)
Since they are side-by-side, pack is the simplest way to lay them out:
left_side.pack(side="left", fill="y", expand=False)
right_side.pack(side="right", fill="both", expand=True)
Next, you can focus on just one side. You can use pack or grid. This uses grid for illustrative purposes:
image = tk.Canvas(left_side, ...)
button = tk.Button(left_side, ...)
left_side.grid_rowconfigure(0, weight=1)
left_side.grid_columnconfigure(0, weight=1)
image.grid(row=0, column=0, sticky="nw")
button.grid(row=1, column=0, sticky="n")
Finally, work on the right side. Since widgets are stacked top-to-bottom, pack is the natural choice:
l1 = tk.Label(right_side, text="Enter text:")
l2 = tk.Label(right_side, text="Remaining characters")
text = tk.Text(right_side)
l1.pack(side="top", fill="x")
text.pack(side="top", fill="both", expand=True)
l2.pack(side="top", fill="x")

Python-tkinter: For loop supposed to collect entries from an array and pass to text box, only passes last entry

I'm new to coding, so apologies if this question is a little base. Anyways, this GUI im making in python is supposed to collect several user entries, and pass them to a text box in the GUI. Right now though, the for loop at the end of the code is only putting the last entry into the text box. Why?
from Tkinter import *
class Application(Frame):
""" A SPC program that takes user input and saves the file """
def __init__(self,master):
""" initializes the frame """
Frame.__init__(self,master)
self.grid()
#creates an array to store entries into
self.entry_list = [None]*7
self.create_widgets()
def create_widgets(self):
"""create widgets for user inputted data"""
# creates a text widget next to the entries that displays what the user has input
Label(self, text = "Do these values you entered seem correct?").grid(row = 0, column = 4, sticky = W, padx = 5, pady = 5)
self.checktext = Text(self, width =15, height = 42, wrap = WORD)
self.checktext.grid(row = 1, rowspan = 10, column = 4, sticky = W, padx =5, pady =5)
# get name
Label(self, text = "First Name:").grid(row = 0, column = 0, sticky = W, padx=5, pady=5)
self.entry_list[0] = Entry(self)
self.entry_list[0].grid(row = 0, column = 1)
Label(self, text = "Last Name:").grid(row = 1, column = 0, sticky = W, padx=5, pady=5)
self.entry_list[1] = Entry(self)
self.entry_list[1].grid(row = 1, column = 1)
# get work order
Label(self, text = "Work Order Number:").grid(row = 2, column = 0, sticky = W, padx=5, pady=5)
self.entry_list[2] = Entry(self)
self.entry_list[2].grid(row = 2, column = 1)
# get todays date
Label(self, text = "Todays Date:").grid(row = 3, column = 0, sticky = W, padx=5, pady=5)
self.entry_list[3] = Entry(self)
self.entry_list[3].grid(row = 3, column = 1)
# get bubble number
Label(self, text = "Bubble Number:").grid(row = 4, column = 0, sticky = W, padx=5, pady=5)
self.entry_list[4] = Entry(self)
self.entry_list[4].grid(row = 4, column = 1)
# get USL and LSL
Label(self, text = "USL:").grid(row = 5, column = 0, sticky = W, padx=5, pady=5)
self.entry_list[5] = Entry(self)
self.entry_list[5].grid(row = 5, column = 1)
Label(self, text = "LSL:").grid(row = 6, column = 0, sticky = W, padx=5, pady=5)
self.entry_list[6] = Entry(self)
self.entry_list[6].grid(row = 6, column = 1)
# button to submit user entered values up to the input data values portion of the gui
self.button = Button(self)
self.button["text"] = "Submit"
self.button["command"] = self.submit
self.button.grid(row = 5, column = 2, sticky = W, padx=5, pady=5)
# creates a spot to dictate whether USL and LSL are correct
self.checklimits = Text(self, width = 20, height = 3, wrap = WORD)
self.checklimits.grid(row = 6, column = 3, sticky = W, padx = 5)
"""# get User Input Data values
Label(self, text = "Enter Results:").grid(row = 7, column = 0, sticky = W, padx=5, pady=5)
self.entry_list8 = Text(self, width = 15, height = 30)
self.entry_list8.grid(row = 7, column = 1) """
def submit(self):
""" submits user data up to input data section of GUI and checks USL vs LSL"""
# checks to make sure limits were imput properly
USL = int(self.entry_list[5].get())
LSL = int(self.entry_list[6].get())
if USL > LSL:
message = "Limits are good"
else:
message = "USL can't be less than LSL, please re-enter USL and LSL"
self.checklimits.delete(0.0, END)
self.checklimits.insert(0.0, message)
# puts entries into text box
for x in self.entry_list:
entry = x.get()
if entry:
self.checktext.delete(0.0, END)
self.checktext.insert(END, entry + "\n")
root = Tk()
root.title("SPC Input Program")
root.geometry("700x750")
app = Application(root)
The problem is here:
for x in self.entry_list:
entry = x.get()
if entry:
self.checktext.delete(0.0, END)
self.checktext.insert(END, entry + "\n")
You're deleting everything in the widget before putting the next string into it, every time. To fix the issue, simply don't delete everything every time. If you want to clear the widget before repopulating it, move the deletion out of the loop:
self.checktext.delete(0.0, END)
for x in self.entry_list:
entry = x.get()
if entry:
self.checktext.insert(END, entry + "\n")
Ok I figured it out and boy do I feel dumb. So here was my for loop before:
for x in self.entry_list:
entry = x.get()
if entry:
self.checktext.delete(0.0, END)
self.checktext.insert(END, entry + "\n")
That self.chectext.delete(0.0, END) line is there to delete whatever the user input into the text box each time they submit, but by being inside the for loop it deleted each entry before adding the next. So duh, of course it would only show the last entry because it deleted the first few! So I put the line outside of the for loop like so:
# puts entries into text box
self.checktext.delete(0.0, END)
for x in self.entry_list:
entry = x.get()
if entry:
print entry
self.checktext.insert(END, entry + "\n")
and now it works fine

Tkinter trying simple math using GUI

Trying to make a very basic addition calculator with python and tkinter. It gives me an error:
btresult = Button(window, text = "Compute Sum", command = self.result).grid(row = 4, column = 2, sticky = E)
^
SyntaxError: invalid syntax
I am having trouble figuring out how to connect this.
from tkinter import *
class addCalculator:
def __init__(self):
window = Tk()
window.title("Add Calculator")
Label(window, text = "First Number: ").grid(row = 1, column = 1, sticky = W)
Label(window, text = "Second Number: ").grid(row = 2, column = 1, sticky = W)
self.number1Var = StringVar()
Entry(window, textvariable = self.number1Var, justify = RIGHT).grid(row = 1, column = 2)
self.number2Var = StringVar()
Entry(window, textvariable = self.number2Var, justify = RIGHT).grid(row = 2, column = 2)
self.resultVar = StringVar()
lblresult = Label(window, textvariable = self.result.grid(row = 3, column = 2, sticky = E)
btresult = Button(window, text = "Compute Sum", command = self.result).grid(row = 4, column = 2, sticky = E)
def result(self):
resultVar = self.resultVar.set(eval(self.number1Var.get()) + eval(self.number2Var.get()))
return resultVar
window.mainloop()
addCalculator()
On the previous line (lblresult = ...), you forgot to close your opened parentheses. Python interprets this (both that line and the next line, btresult = ...) as one whole line of code, but obviously this can't work with your code, hence the SyntaxError
I solved this problem in my own way. I tried to stay faithful to the original question but the code needed a lot of clean up. There was lots of little odds and ends to fix, but i think the main problem was the method of passing the integers to the function. I also changed the original lblresult from a label to an Entry widget. Im still new at Python but getting better. I found this question while looking for a similar answer and solving this also solved my problem. Thanks! Code below:
from Tkinter import *
class addCalculator:
def __init__(self):
window = Tk()
window.title("Add Calculator")
def result(z1,z2):
biz=z1+z2
lblresult.delete(0,END)
lblresult.insert(0,biz)
return
Label1 = Label(window, text = "First Number: ").grid(row = 1, column = 1, sticky = W)
Label2 = Label(window, text = "Second Number: ").grid(row = 2, column = 1, sticky = W)
self.number1Var = IntVar()
Entry1 = Entry(window, textvariable = self.number1Var, justify = RIGHT).grid(row = 1, column = 2)
self.number2Var = IntVar()
Entry2 = Entry(window, textvariable = self.number2Var, justify = RIGHT).grid(row = 2, column = 2)
Label3 = Label(window, text = "Result: ").grid(row = 3, column = 1, sticky = W)
lblresult = Entry(window, justify = RIGHT)
lblresult.grid(row = 3, column = 2, sticky = E)
btresult = Button(window,text="Compute Sum",command=lambda:result(self.number1Var.get(),self.number2Var.get()))
btresult.grid(row = 4, column = 2, sticky = E)
window.mainloop()
addCalculator()

Categories

Resources