How do i make the button to add two box (side by side) below when it is being clicked as the user decided to put more input?
def addBox():
labelframe = Tkinter.Frame()
labelframe.bind("<Add Input>", callback)
labelframe.pack()
labelframe = Tkinter.Frame()
labelFrom = Tkinter.Label(labelframe, text= "from")
labelFrom.grid(column=1, row=0)
e = Tkinter.Entry(labelframe)
e.grid(column=1, row=1)
labelTo = Tkinter.Label(labelframe, text= "to")
labelTo.grid(column=2, row=0)
e2 = Tkinter.Entry(labelframe)
e2.grid(column=2, row=1)
labelframe.pack()
addboxButton = Button( root,text='<Add Time Input>', fg="Red",command="addBox")
addboxButton.pack(side=Tkinter.TOP)
This is example how to add Entry.
Probably you get problem because you use quotation marks in command=addBox
Because you will have to get values from entries you have to remeber them on list.
I add button which print text from entries.
from Tkinter import *
#------------------------------------
def addBox():
print "ADD"
ent = Entry(root)
ent.pack()
all_entries.append( ent )
#------------------------------------
def showEntries():
for number, ent in enumerate(all_entries):
print number, ent.get()
#------------------------------------
all_entries = []
root = Tk()
showButton = Button(root, text='Show all text', command=showEntries)
showButton.pack()
addboxButton = Button(root, text='<Add Time Input>', fg="Red", command=addBox)
addboxButton.pack()
root.mainloop()
#------------------------------------
EDIT:
Example with boxes side by side.
I use new frame to keep entries side by side using grid().
This way I don't mix grid() with pack() in main window/frame.
I use len(all_entries) to get number of next free column.
from Tkinter import *
#------------------------------------
def addBox():
print "ADD"
# I use len(all_entries) to get nuber of next free column
next_column = len(all_entries)
# add label in first row
lab = Label(frame_for_boxes, text=str(next_column+1))
lab.grid(row=0, column=next_column)
# add entry in second row
ent = Entry(frame_for_boxes)
ent.grid(row=1, column=next_column)
all_entries.append( ent )
#------------------------------------
def showEntries():
for number, ent in enumerate(all_entries):
print number, ent.get()
#------------------------------------
all_entries = []
root = Tk()
showButton = Button(root, text='Show all text', command=showEntries)
showButton.pack()
addboxButton = Button(root, text='<Add Time Input>', fg="Red", command=addBox)
addboxButton.pack()
frame_for_boxes = Frame(root)
frame_for_boxes.pack()
root.mainloop()
#------------------------------------
EDIT:
Another example:
from Tkinter import *
#------------------------------------
def addBox():
print "ADD"
frame = Frame(root)
frame.pack()
Label(frame, text='From').grid(row=0, column=0)
ent1 = Entry(frame)
ent1.grid(row=1, column=0)
Label(frame, text='To').grid(row=0, column=1)
ent2 = Entry(frame)
ent2.grid(row=1, column=1)
all_entries.append( (ent1, ent2) )
#------------------------------------
def showEntries():
for number, (ent1, ent2) in enumerate(all_entries):
print number, ent1.get(), ent2.get()
#------------------------------------
all_entries = []
root = Tk()
showButton = Button(root, text='Show all text', command=showEntries)
showButton.pack()
addboxButton = Button(root, text='<Add Time Input>', fg="Red", command=addBox)
addboxButton.pack()
root.mainloop()
#------------------------------------
First of all, the indentation is a whole mess, so I don't know where does the addBox function end ..
Second, I don't think you need a button, I suppose a checkbutton will do the same thing and it's also more common and familiar to users, I once had this problem and I simply created an entry box and put above it a label indicating that it's optional, and as for code, I simply ignored it if it was empty and verified the input if I found any input ..Howerver, that was for only one entry box, and you probably will need something more complex ..
See this ..
class OptionsView(Frame):
"""Frame for options in main window"""
def __init__(self, x, y, parent):
Frame.__init__(self, parent)
self.x = x
self.y = y
self.placed = False
self.hidden = False
self.btn = Button(self, text = 'Button attached to the frame ..', command = lambda: print('Button in frame clicked ..')).pack()
def pack(self):
self.place(x = self.x, y = self.y)
self.placed = True
def toggle_view(self):
if self.hidden:
self.pack()
self.hidden = False
else:
self.place_forget()
self.hidden = True
if __name__ == '__main__':
def m_frame():
if val.get() and not options_frame.placed:
print('Showing Frame ..')
options_frame.pack()
else:
print('Toggling Frame ..')
options_frame.toggle_view()
root = Tk()
root.geometry('300x400+500+600')
root.title('Testing Hiding Frames ..')
options_frame = OptionsView(200, 300, root)
val = BooleanVar(value = False)
Checkbutton(text = 'View more Options ..', var = val, command = m_frame).place(x=root.winfo_height()/2, y=root.winfo_width()/2)
try: root.mainloop()
except e: showerror('Error!', 'It seems there\'s a problem ..', str(e))
Ofcourse you can also modify the length and the x axis of the main window if you want to be more realistic ..
Related
This is to be a desktop application for opening multiple small databases and running queries on them. So far I've written some code for opening forms as necessary. Is this a good way to do it? Also - the code shown opens two copies of each form - what am I doing wrong? It's my first attempt at Python and I'm a rudimentary programmer so simple answers would be of most help please. TIA (Python 3.9.6)
link_1.py
from tkinter import Tk
import link_2
root = Tk()
class ClassLink_1:
#if another function in the class is called, the __init__ function is run at start up
def __init__(self):
print("in link_1 __init__ instruction")
#the call_function function can be called at start up, or not, and will act accordingly
def call_function(self):
print("in call_function")
#the line below is run at start up whether or not another function in the class is called
print("in link_1")
root.withdraw() #hides the blank form at start up
#if __name__ == "__main__":
#the line below shows the link_2 form, whether or not the if __name__==__main__ condition is used as its condition
link_2.ClassLink_2(root).__init__(root)
#link_3.ClassLink_3(root).__init__(root)
#the line below runs call_function on start up to print text
ClassLink_1().call_function()
root.mainloop()
link_2.py
from tkinter import Tk, Button
from tkinter import * #for Toplevel
import link_3
root = Tk()
class ClassLink_2:
def __init__(self, master):
self.openNewWindow()
def openNewWindow(self):
newWindow = Toplevel(root) #creates a top level widget with the parent root (first parameter)
newWindow.title("Title opened from link_1")
newWindow.geometry("500x500")
label = Label(newWindow, text ="Opened from link_1").grid(row=1, column=1)
self.add_button = Button(newWindow, text="in ClassLink_2", command= self.do_add)
self.add_button.grid(row=3, column=1)
def do_add(self):
print("button pressed")
link_3.ClassLink_3(root).__init__(root)
root.withdraw() #hides the blank form at start up
link_3.py
from tkinter import Tk, Button
from tkinter import * #for Toplevel
root = Tk()
class ClassLink_3:
def __init__(self, master):
self.openNewWindow()
def openNewWindow(self):
newWindow = Toplevel(root) #creates a top level widget with the parent root (first parameter)
newWindow.title("Title opened from link_2")
newWindow.geometry("500x500")
label = Label(newWindow, text ="Opened from link_2").grid(row=1, column=1)
self.add_button = Button(newWindow, text="in ClassLink_3", command= self.do_add)
self.add_button.grid(row=3, column=1)
def do_add(self):
print("button pressed")
# link_4.ClassLink_4(root).__init__(root) this file has not yet been made
root.withdraw() #hides the blank form at start up
This is a proposed solution, can be expanded as needed. Constructive suggestions for improvement of the structure or code would be appreciated. TIA. I've left in the details in case they are of use to anyone.
link_1
from tkinter import Tk
import link_2
root = Tk()
class ClassLink_1:
def __init__(self):
print("in link_1 __init__ instruction")
root.withdraw() #hides the blank form at start up
link_2.ClassLink_2(root).openNewWindow(0)
root.mainloop()
link_2
from tkinter import Tk, Button
from tkinter import *
import link_3
root = Tk()
class ClassLink_2:
root.withdraw() #hides the blank form at start up
class_var_1 = 0
inst_var_1 = 0
def __init__(self, incoming_inst_var_1):
pass
def openNewWindow(self, inst_var_1_to_open):
newWindow = Toplevel(root)
newWindow.title("Title opened from link_1")
newWindow.geometry("500x500")
label = Label(newWindow, text ="Opened from link_1").grid(row=1, column=1)
self.add_button = Button(newWindow, text="in ClassLink_2", command= self.do_add)
self.add_button.grid(row=3, column=1)
self.add_button = Button(newWindow, text="increment class_var_1", command= self.inc_class_var_1)
self.add_button.grid(row=5, column=1)
self.inst_var_1 = inst_var_1_to_open
def do_add(self):
print("button pressed")
link_3.ClassLink_3(root).openNewWindow(0)
def inc_class_var_1(self):
ClassLink_2.class_var_1 += 2
self.inst_var_1 += 1
print("self.class_var_1 = " + (str)(self.class_var_1))
print("self.inst_var_1 = " + (str)(self.inst_var_1))
link_3
from tkinter import Tk, Button
from tkinter import *
from tkinter.ttk import Combobox
import tkinter.scrolledtext as tkscrolled
# import link_4 <filename of next form>
root = Tk()
class ClassLink_3:
class_var_1 = 0
inst_var_1 = 0
# ------------------------------- START CLASS CONTROLS -----------------------------
root.withdraw()
def __init__(self, incoming_inst_var_1):
pass
def openNewWindow(self, inst_var_1_to_open):
new_window = Toplevel(root)
self.widget_factory(new_window)
self.inst_var_1 = inst_var_1_to_open
def do_add(self):
print("button pressed")
# link_4.ClassLink_4(root).openNewWindow(0) # <filename of next form>
# ---------------------------------- END CLASS CONTROLS -----------------------------
# -------------------------------------- START CALCS --------------------------------------
def inc_class_var_1(self):
ClassLink_3.class_var_1 += 2
self.inst_var_1 += 1
print("self.class_var_1 = " + (str)(self.class_var_1))
print("self.inst_var_1 = " + (str)(self.inst_var_1))
# ---------------------------------------- END CALCS --------------------------------------
# ---------------------------------------- START FACTORY SHOPS-----------------------------------------
def widget_factory(self, new_window):
self.shop_window(new_window)
self.shop_labels(new_window)
self.shop_buttons(new_window)
self.shop_menu(new_window)
self.shop_listbox(new_window)
self.shop_combobox(new_window)
self.shop_radiobuttons(new_window)
self.shop_checkbuttons(new_window)
self.shop_entries(new_window)
self.shop_canvas(new_window)
self.shop_scale(new_window)
self.shop_scrollbars(new_window)
self.shop_textbox(new_window)
self.shop_menu(new_window)
pass
# ------------------------
def shop_window(self, new_window):
new_window.title("Title opened from link_2")
new_window.geometry("800x900")
def shop_labels(self, new_window):
self.label_1 = Label(new_window, text ="Opened from link_2").grid(row=1, column=1)
def shop_buttons(self, new_window):
self.button_1 = Button(new_window, text="in ClassLink_3", command= self.do_add)
self.button_1.grid(row=3, column=1)
self.button_2 = Button(new_window, text="increment class_var_1", command= self.inc_class_var_1)
self.button_2.grid(row=5, column=1)
def shop_listbox(self, new_window):
data=("one", "two", "three", "four")
self.listbox_1 = Listbox(new_window, height=5, selectmode='multiple')
for num in data:
self.listbox_1.insert(END,num)
self.listbox_1.grid(row=7, column=1)
def shop_combobox(self, new_window):
data=("one", "two", "three", "four")
self.combobox_1 = Combobox(new_window, values=data)
self.combobox_1.grid(row=8, column=3)
def shop_radiobuttons(self, new_window):
var_1 = IntVar()
var_1.set(1)
self.rad_btn_1 = Radiobutton(new_window, text="male", variable=var_1, value=1)
self.rad_btn_2 = Radiobutton(new_window, text="female", variable=var_1, value=2)
self.rad_btn_1.grid(row=9, column=1)
self.rad_btn_2.grid(row=9, column=2)
def shop_checkbuttons(self, new_window):
var_1 = IntVar()
var_2 = IntVar()
self.checkbtn_1 = Checkbutton(new_window, text = "Cricket", variable = var_1)
self.checkbtn_2 = Checkbutton(new_window, text = "Tennis", variable = var_2)
self.checkbtn_1.grid(row=10, column=1)
self.checkbtn_2.grid(row=10, column=2)
def shop_entries(self, new_window):
self.entry_1 = Entry(new_window, width = 20)
self.entry_1.insert(0,'Username')
self.entry_1.grid(row= 11, column=2)
self.entry_2 = Entry(new_window, width = 15)
self.entry_2.insert(0,'password')
self.entry_2.grid(row= 12, column=2)
#might want to place on a frame, see example https://coderslegacy.com/python/list-of-tkinter-widgets/
def shop_canvas(self, new_window):
canvas = Canvas(new_window, bg= 'white', width = 260,height = 260) #this is the background for the figure
# left and top of figure is from [x from left, y from top] of canvas right and bottom of figure from [x from left, y from top] of canvas
coordinates = 20, 50, 210, 230
arc = canvas.create_arc(coordinates, start=0, extent=250, fill="blue") #start is from E, extent is in degrees CCW
arc = canvas.create_arc(coordinates, start=250, extent=50, fill="red")
arc = canvas.create_arc(coordinates, start=300, extent=60, fill="yellow")
canvas.grid(row=2, column=1)
def shop_scale(self, new_window):
self.scale_1 = Scale(new_window, from_=0, to=10, orient=VERTICAL)
self.scale_1.grid(row=15, column=2)
self.scale_2 = Scale(new_window, from_=0, to=10, orient = HORIZONTAL)
self.scale_2.grid(row=15, column=3)
def shop_scrollbars(self, new_window):
self.scroll_vert = Scrollbar(new_window)
self.scroll_vert.grid(row=19, column=3)
self.listbox_3 = Listbox(new_window, yscrollcommand = self.scroll_vert.set )
for line in range(1, 100):
self.listbox_3.insert(END, "Number " + str(line))
self.listbox_3.grid(row=19 , column=2)
self.scroll_vert.config(command = self.listbox_3.yview)
def shop_textbox(self, new_window):
#make a frame with parent new_window
self.frame_textbox_1 = Frame(new_window)
self.frame_textbox_1.grid(row=1, column=5)
#make the textbox with parent frame
self.textbox_1 = Text(self.frame_textbox_1)
self.textbox_1.config(wrap=NONE, width=15, height=8) #width, height are characters x rows permitted wrap values should be WORD CHAR, or NONE
#make the X scrollbar with parent frame
self.scroll_text_horiz = Scrollbar(self.frame_textbox_1, orient="horizontal")
self.scroll_text_horiz.config(command = self.textbox_1.xview)
#make the Y scrollbar with parent frame
self.scroll_text_vert = Scrollbar(self.frame_textbox_1, orient="vertical")
self.scroll_text_vert.config(command = self.textbox_1.yview)
#pack the scrollbars before the texbox to allow them to fill the frame width and height
self.scroll_text_horiz.pack(side=BOTTOM, fill=X)
self.scroll_text_vert.pack(side=RIGHT, fill=Y)
self.textbox_1.pack(fill="y")
#connect the scrollbars to the textbox
self.textbox_1["xscrollcommand"] = self.scroll_text_horiz.set
self.textbox_1["yscrollcommand"] = self.scroll_text_vert.set
message = "the quick brown fox"
self.textbox_1.insert(1.1, message)
# ----------------------------------------------
def shop_menu(self, new_window):
print("in shop menu1")
menubar = Menu(new_window)
print("in shop_menu2")
file = Menu(menubar, tearoff=0)
file.add_command(label="New")
file.add_command(label="Open")
file.add_command(label="Save")
file.add_command(label="Save as...")
file.add_command(label="Close")
file.add_separator()
file.add_command(label="Exit", command=new_window.quit)
menubar.add_cascade(label="File", menu=file)
edit = Menu(menubar, tearoff=0)
edit.add_command(label="Undo")
edit.add_separator()
edit.add_command(label="Cut")
edit.add_command(label="Copy")
edit.add_command(label="Paste")
edit.add_command(label="Delete")
edit.add_command(label="Select All")
menubar.add_cascade(label="Edit", menu=edit)
help = Menu(menubar, tearoff=0)
help.add_command(label="About")
menubar.add_cascade(label="Help", menu=help)
new_window.config(menu=menubar)
print("in shop menu3")
# --------------------------------------- END FACTORY SHOPS---------------------------------------
I'm trying to make an example for some high school students using tkinter with multiple forms, and accessing form data in different functions. I'm trying to keep the example simple, but having a small problem. The sv3 & sv4 variables are not getting the values from the second form. Any suggestions or ideas?
from tkinter import *
root = Tk()
sv1 = StringVar()
sv2 = StringVar()
sv3 = StringVar()
sv4 = StringVar()
#first function - this DOES NOT take text from entry widgets and displays, but should
def callback2():
test2 = sv3.get()
print(test2)
print (sv4.get())
print("show second form entry widgets values")
return True
#first function - this takes text from entry widgets and displays
def callback():
test = sv1.get()
print(test)
print (sv2.get())
print("show first form entry widgets values")
new_form()
return True
#new form
def new_form():
newfrm = Tk()
entry3 = Entry(newfrm, textvariable=sv3).pack()
entry4 = Entry(newfrm, textvariable=sv4).pack()
button = Button(newfrm, text="Click Me", command=callback2).pack()
newfrm.mainloop()
#initial form
def main_form():
entry1 = Entry(root, textvariable=sv1).pack()
entry2 = Entry(root, textvariable=sv2).pack()
button = Button(root, text="Click Me", command=callback).pack()
root.mainloop()
main_form()
Here how to avoid using multiple Tk instances and manually transfers the values from the first two Entrys to the second pair. See lines with #### comments.
from tkinter import *
root = Tk()
sv1 = StringVar()
sv2 = StringVar()
sv3 = StringVar()
sv4 = StringVar()
#first function - this now take text from entry widgets and displays as it should.
def callback2():
test2 = sv3.get()
print(test2)
print (sv4.get())
print("show second form entry widgets values")
return True
#first function - this takes text from entry widgets and displays
def callback():
test = sv1.get()
print(test)
print (sv2.get())
print("show first form entry widgets values")
new_form()
return True
#new form
def new_form():
#### newfrm = Tk()
newfrm = Toplevel() #### Instead.
sv3.set(sv1.get()) #### Trasfer value.
sv4.set(sv2.get()) #### Trasfer value.
entry3 = Entry(newfrm, textvariable=sv3).pack()
entry4 = Entry(newfrm, textvariable=sv4).pack()
button = Button(newfrm, text="Click Me", command=callback2).pack()
newfrm.mainloop()
#initial form
def main_form():
entry1 = Entry(root, textvariable=sv1).pack()
entry2 = Entry(root, textvariable=sv2).pack()
button = Button(root, text="Click Me", command=callback).pack()
root.mainloop()
main_form()
I cannot get my code to pass the pop up text entry to a global variable i am also attempting to set this global variable as the default text in the entry field in all future instances.
Pop up -> Enter Filepath -> accept&close -> Re-open shows last filepath present as default -> if changed new filepath entry becomes default in future.
import tkinter as tk
from tkinter import ttk
from tkinter import *
master = tk.Tk()
Var1 = StringVar()
Filepath_Var = None
def A_Connect():
root = Tk()
root.title("Entry Field")
def entry_field():
global Filepath_Var
Filepath_Var = Var1.get()
tk.Label(root, text="filepath: ").grid(row=0)
e1 = tk.Entry(root, textvariable=Var1)
tk.Label(root, text="Item Number: ").grid(row=1)
e2 = tk.Entry(root)
#e1.insert(0, r"C:\Users\zxy\ghj\iugf\Bea\something.xlsx")
e1.insert(0, Var1.get())
e1.grid(row=0, column=1)
e2.grid(row=1, column=1)
Button(root, text = 'Accept', command = entry_field).grid(row=3, column=1,
sticky=W, pady=4)
root.mainloop()
note = ttk.Notebook(master)
tab1 = tk.Frame(note)
canvas7 = Canvas(tab1, width=520, height=350)
canvas7.pack()
A_Button = tk.Button(tab1, text="A",
width=12, height=3,command=A_Connect, anchor = 'w')
A_Button_Window = canvas7.create_window(20, 120, anchor = 'sw',
window = A_Button)
note.add(tab1, text = " Main ")
note.pack()
master.mainloop()
As a follow up to your earlier question, I encapsulated an example of the (bare bones) desired behavior in two classes:
The main App consists of a button that launches an entry popup; upon filling the fields and accepting, the value in the entry is provided to the App, and the popup closed.
The value entered is stored by the App, and used to populate the entry field of the entry fields in successive popups.
You will probably want to add confirmations and verifications before changing the defaults, and closing the popup, but here, you have the basic skeleton to attach this to.
import tkinter as tk
class PopUpEntry(tk.Toplevel):
def __init__(self, master, default_value=None):
self.master = master
super().__init__(self.master)
if default_value is None:
self.default_entry = 'C:*****\somthing.xlsx'
else:
self.default_entry = default_value
self.title("Entry Field")
tk.Label(self, text="Filepath: ").pack()
self.e1 = tk.Entry(self)
self.e1.insert(0, self.default_entry)
self.e1.pack()
tk.Button(self, text = 'Accept', command=self.entry_field).pack()
def entry_field(self):
self.default_entry = self.e1.get()
self.master.provide_entry_value(self.default_entry)
self.destroy()
class App(tk.Tk):
def __init__(self):
super().__init__()
self.pop_entry = tk.Button(self, text='launch entry', command=self.launch_entry)
self.pop_entry.pack()
self.default_entry_value = None
self.mainloop()
def launch_entry(self):
PopUpEntry(self, self.default_entry_value)
def provide_entry_value(self, value):
self.default_entry_value = value
print(self.default_entry_value)
App()
I want to create a GUI with Tkinter, such that you are at a grocery store, you enter the item, price, and quantity, and each item will appear on the top part of the screen.
I have a top and bottom frame, and when I place an entry it goes right in the middle of the bottom frame. I have tried justifying the position to the left, anchoring it, sticking it and doing whatever, but it's not moving.
This is my code.
from Tkinter import *
root = Tk()
root.title("project")
root.geometry("700x850+0+0")
textInput = StringVar()
class MenuBoard(object):
def __init__(self,master):
self.master = master
mainFrame = Frame(self.master,bg = "white",width=700,height=400)
mainFrame.grid(row=0,column=0)
labelFrame = Frame(self.master, bg = "red",height=40,width=700)
labelFrame.grid(row=0,column=0,sticky = N)
welcomeLabel = Label(self.master, text = "",fg= "black",bg="red",)
welcomeLabel.config(font=("Courier New",23))
welcomeLabel.grid(row=0,column=0,sticky = N)
actual = MenuBoard(root)
root.mainloop()
-Use
bottomFrame.grid_propagate(False)
to expand the frame and
storeItemEntry.grid(pady=30)
Or whatever value you want for pady. You might have to give row and column numbers to grid() if you're going to place other widgets in bottomFrame.
You saw "a strange dark grey background" as mentioned in the comment because you gave bg = "grey" to bottomFrame. The background wasn't visible initially because the frame shrank to fit the Entry. You can change the color to what you want or remove it entirely.
The following should be close to what you're looking for:
from Tkinter import *
root = Tk()
root.title("project")
root.geometry("700x850+0+0")
textInput = StringVar()
class MenuBoard(object):
def __init__(self,master):
self.master = master
mainFrame = Frame(self.master,bg = "white",width=700,height=400)
mainFrame.grid(row=0,column=0)
labelFrame = Frame(self.master, bg = "red",height=40,width=700)
labelFrame.grid(row=0,column=0,sticky = N)
welcomeLabel = Label(self.master, text = "Main Heading Here",fg= "black",bg="red",)
welcomeLabel.config(font=("Courier New",23))
welcomeLabel.grid(row=0,column=0,sticky = N)
bottomFrame = Frame(self.master, bg = "grey", height=450,width=700) #Change/remove bg
bottomFrame.grid(row=1, column=0)
bottomFrame.grid_propagate(False)
storeItemEntry = Entry(bottomFrame, font=("Courier New",10,"bold"), textvariable=textInput, bd =4)
storeItemEntry.grid(pady=30)
actual = MenuBoard(root)
root.mainloop()
UPDATE:
Based on your comments, here is a rough implementation to work with.
from Tkinter import *
root = Tk()
root.title("project")
root.geometry("700x850+0+0")
class MenuBoard(object):
def __init__(self,master):
self.master = master
mainFrame = Frame(self.master,bg = "white",width=700,height=400)
mainFrame.grid(row=0,column=0)
mainFrame.grid_propagate(False)
mainFrame.grid_columnconfigure(0, weight=1)
heading = " Store Item".ljust(45)[:45] + "Item Price" # Pad the text with white spaces
listHeading = Label(mainFrame, text=heading, anchor="w", font=("Courier New",14,"bold"))
listHeading.grid(row=1, column=0, pady=5, stick="we")
# Use Text widget so you can keep inserting items
self.listItems = Text(mainFrame, font=("Courier New",12))
self.listItems.grid(row=2, column=0, pady=5, stick="we")
self.listItems.config(state="disabled") # Prevents edits on the Text
welcomeLabel = Label(mainFrame, text = "Main Heading Here",fg= "black",bg="red",)
welcomeLabel.config(font=("Courier New",23))
welcomeLabel.grid(row=0,column=0, stick="we")
bottomFrame = Frame(self.master, bg = "grey", height=450,width=700) #Change/remove bg
bottomFrame.grid(row=1, column=0)
bottomFrame.grid_propagate(False)
storeItemLabel = Label(bottomFrame, text="Food Item: ")
storeItemLabel.grid(row=0, column=0)
self.storeItemEntry = Entry(bottomFrame, font=("Courier New",10,"bold"), bd =4)
self.storeItemEntry.grid(row=0, column=1, pady=15)
priceLabel = Label(bottomFrame, text="Price: ")
priceLabel.grid(row=2, column=0)
self.priceEntry = Entry(bottomFrame, font=("Courier New",10,"bold"), bd =4)
self.priceEntry.grid(row=2, column=1,)
btn = Button(bottomFrame, text="Add Item", command=self.add)
btn.grid(row=3, column=1, pady=15)
def add(self):
price = self.storeItemEntry.get() # Get item name from Entry
#Get price, format name and price
groceryItem = price.ljust(50)[:50] + "$%s" %(self.priceEntry.get())
self.listItems.config(state="normal") # Enable edits on the Text
self.listItems.insert("end", "\n "+groceryItem) # Edit Text
self.listItems.config(state="disabled") # Prevents edits on the Text
actual = MenuBoard(root)
root.mainloop()
A couple of things to note:
I removed some of your frames because they seemed redundant, you can add them back if needed.
Since you're working with a class, I added the self keyword to some of the attributes so I can use/call them later in other methods without errors. I left out the attributes that I do not need to call after creation.
StringVar/textvariable is not needed since you're updating the list with a button click.
There are lots of refinements I did not do (i.e. checking to see if a valid input is given before updating the list, ability to delete from the list, etc).
I used methods and features that you may or may not be aware of (.ljust(50)[:50], %s, etc)
I hope this helps :).
I am trying to make a tkinter widget that will remember the previous entry. The problem I am having is the that the button method I made erases the previous entry every time its pressed.
from Tkinter import *
class step1():
def __init__(self):
pass
def getTextbook(self):
temp = str(textbook.get())
textbook.delete(0, END)
x = " "
x += temp
print x
def equal_button(self):
print getTextbook(self)
root = Tk()
root.title("step1")
root.geometry("600x600")
s = step1()
app = Frame(root)
app.grid()
label = Label(app, text = "step1")
label.grid()
textbook = Entry(app, justify=RIGHT)
textbook.grid(row=0, column = 0, columnspan = 3, pady = 5)
textbook2 = Entry(app, justify=RIGHT)
textbook2.grid(row=1, column = 0, columnspan = 3, pady = 5)
button1 = Button(app, text = "Return", command = lambda: s.getTextbook())
button1.grid()
button2 = Button(app, text="Equal")
button2.grid()
root.mainloop()
The variable X in your getTextbook() is being overwritten every time you set it to " ". Try a list instead, and append each entry to the list when the button is pressed:
from Tkinter import *
root = Tk()
textbookList = []
def getTextbook():
textbookList.append(textbook.get())
textbook.delete(0,END)
print textbookList
textbook = Entry(root)
textbook.pack()
btn1 = Button(root, text='Return', command=getTextbook)
btn1.pack()
root.mainloop()