I have the code where you can tick a checkbox and delete any row you want but I can't figure out how to get the rows beneath the row deleted to shift up and fill the space from the deleted row. Here is the code I'm running in jupyter. Please help!!
import tkinter as tk
from tkinter import messagebox
class GUI:
def __init__(self, root):
self.root = root
self.root.title("Editable Headings")
self.headings = ['Pad #', 'Location Name', 'Projected Level',
'# 130 bbl Loads', '24hr Rate', 'Rate Per Tank',
'# of Tanks', 'Notes', 'Water weight']
self.entries = []
self.vars = []
self.init_gui()
def init_gui(self):
for i, heading in enumerate(self.headings):
label = tk.Label(self.root, text=heading, font=("TkDefaultFont", 14))
label.grid(row=0, column=i, padx=10, pady=10, sticky="w")
entry = tk.Entry(self.root)
entry.grid(row=1, column=i, padx=10, pady=10, sticky="we")
self.entries.append(entry)
var = tk.IntVar()
checkbox = tk.Checkbutton(self.root, variable=var)
checkbox.grid(row=1, column=len(self.headings), padx=10, pady=10, sticky="w")
self.vars.append(var)
add_button = tk.Button(self.root, text="+", command=self.add_row)
add_button.grid(row=1, column=len(self.headings)+1, padx=25, pady=10)
delete_button = tk.Button(self.root, text="Delete", command=self.delete_row)
delete_button.grid(row=2, column=len(self.headings)+1, padx=25, pady=10)
def add_row(self):
row = len(self.entries) // len(self.headings) + 1
for i, heading in enumerate(self.headings):
entry = tk.Entry(self.root)
entry.grid(row=row, column=i, padx=10, pady=10, sticky="we")
self.entries.append(entry)
var = tk.IntVar()
checkbox = tk.Checkbutton(self.root, variable=var)
checkbox.grid(row=row, column=len(self.headings), padx=10, pady=10, sticky="w")
self.vars.append(var)
def delete_row(self):
if not self.entries:
return
if messagebox.askyesno("Delete", "Are you sure you want to delete the selected rows?"):
indices = [i for i, var in enumerate(self.vars) if var.get()]
for i in sorted(indices, reverse=True):
for j in range(len(self.headings)):
entry = self.entries.pop(i * len(self.headings))
entry.destroy()
var = self.vars.pop(i)
var.set(0)
if __name__ == "__main__":
root = tk.Tk()
app = GUI(root)
root.mainloop()
I would just like the rows beneath the row that is selected to be deleted to shift up after the selected is deleted.
For easier control, I would suggest to:
put those entry boxes and checkbuttons in a frame and those action buttons in another frame
use a single dictionary to store those widgets and tk.IntVar using row number as the key instead of separate lists
Then it is easy to delete the widgets in a row by just looking up them in the dictionary. Note that if all widgets in a row are deleted, the height of that row will be zero. So the widgets beneath will be shift up.
import tkinter as tk
from tkinter import messagebox
class GUI:
def __init__(self, root):
self.root = root
self.root.title("Editable Headings")
self.headings = ['Pad #', 'Location Name', 'Projected Level',
'# 130 bbl Loads', '24hr Rate', 'Rate Per Tank',
'# of Tanks', 'Notes', 'Water weight']
self.entries = {}
self.init_gui()
def init_gui(self):
# frame for the entries and checkbuttons
self.frame = tk.Frame(self.root)
self.frame.pack(side="left", fill="y")
# show the headings
for i, heading in enumerate(self.headings):
label = tk.Label(self.frame, text=heading, font=("TkDefaultFont", 14))
label.grid(row=0, column=i, padx=10, pady=10, sticky="w")
# add an initial row
self.add_row()
# frame for the buttons
button_frame = tk.Frame(self.root)
button_frame.pack(side="right", fill="y")
add_button = tk.Button(button_frame, text="+", command=self.add_row)
add_button.grid(row=1, column=len(self.headings)+1, padx=25, pady=10)
delete_button = tk.Button(button_frame, text="Delete", command=self.delete_row)
delete_button.grid(row=2, column=len(self.headings)+1, padx=25, pady=10)
def add_row(self):
# get the insertion row number
row = self.frame.grid_size()[1]
widgets = []
for i, heading in enumerate(self.headings):
entry = tk.Entry(self.frame)
entry.grid(row=row, column=i, padx=10, pady=10, sticky="we")
widgets.append(entry)
var = tk.IntVar()
checkbox = tk.Checkbutton(self.frame, variable=var)
checkbox.grid(row=row, column=len(self.headings), padx=10, pady=10, sticky="w")
widgets.append(checkbox)
# store the widgets in the new row and IntVar into the dictionary
self.entries[row] = (var, widgets)
def delete_row(self):
# any row selected
rows = [row for row, (var, _) in self.entries.items() if var.get()]
if rows and messagebox.askyesno("Delete", "Are you sure you want to delete the selected rows?"):
for row in rows:
_, widgets = self.entries.pop(row)
for w in widgets:
w.destroy()
if __name__ == "__main__":
root = tk.Tk()
app = GUI(root)
root.mainloop()
Related
I am working on a little finance project. When I add to my balance, the entry gets listed among themselves. But I want to "change direction", so the newest entry is always on row 3 and the others lists among themselves. The problem is I don't know how to access to the other Elements to add to their row.
It should be something like that:
I entry a amount to add to the main balance- for example 40$
It gets shown on column 0, row 3
If I add another amount it should show on row 3- for example 20$, and the 40$ should move to row 4.
It should get listed like that:
row 3: 20$ ,
row 4: 40$
and so on..
Sorry for beginner mistakes, Im new to python :)
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox
class App():
def __init__(self):
self.window = tk.Tk()
self.window.title("Expenses")
self.window.geometry("700x600")
self.window.resizable(0,0)
self.username_list = ["a"]
self.password_list = ["a"]
self.balace = 90
self.row_first_column = 2
self.start_frame()
self.window.mainloop()
def start_frame(self):
self.window.columnconfigure(0, weight=1)
self.window.columnconfigure(1, weight=1)
self.window.columnconfigure(2, weight=1)
self.heading_label = ttk.Label(self.window, text="Log-In", font=("", 25))
self.heading_label.grid(column=1, row=0, sticky=tk.NS, pady=40)
self.username = ttk.Label(self.window, text="Username:")
self.username.grid(column=1, row=1, sticky=tk.W, pady=30)
self.password = ttk.Label(self.window, text="Password:")
self.password.grid(column=1, row=2, sticky=tk.W)
self.entry1 = ttk.Entry(self.window)
self.entry1.grid(column=1, row=1)
self.entry2 = ttk.Entry(self.window)
self.entry2.grid(column=1, row=2)
self.warning = ttk.Label(self.window, text="")
self.warning.grid(column=1, row=3, sticky= tk.NS, pady=10)
self.button1 = ttk.Button(self.window, text="Submit", command= self.check_data)
self.button1.grid(column=1, row=4, sticky=tk.NS)
def check_data(self):
username_check = self.entry1.get()
password_check = self.entry2.get()
if username_check in self.username_list and password_check in self.password_list:
self.main_frame()
else:
self.warning.configure(text="Incorrect data! Try again")
self.entry2.delete(0, tk.END)
def main_frame(self):
self.username.destroy()
self.password.destroy()
self.entry1.destroy()
self.entry2.destroy()
self.warning.destroy()
self.button1.destroy()
self.heading_label.configure(text="Finance", font=("", 25))
#First Column
self.sub_heading1 = ttk.Label(self.window, text="Overview", font=("", 15))
self.sub_heading1.grid(column=0, sticky=tk.NS, row=1, pady=20)
self.balance_label = ttk.Label(self.window, text=f"{self.balace}$")
self.balance_label.grid(column=0, row=2, pady=20, sticky=tk.NS)
#Second Column
self.sub_heading2 = ttk.Label(self.window, text="Add", font=("", 15))
self.sub_heading2.grid(column=1, sticky=tk.NS, row=1, pady=20)
self.add_balance = ttk.Entry(self.window, width=5)
self.add_balance.grid(column=1, row=2, pady=20, sticky=tk.NS)
self.add_button = ttk.Button(self.window, text="Add",width=3, command= self.entry_add_balance)
self.add_button.grid(column=1, row=3, pady=10, sticky=tk.NS)
#Third Column
self.sub_heading3 = ttk.Label(self.window, text="Minus", font=("", 15))
self.sub_heading3.grid(column=2, sticky=tk.NS, row=1, pady=20)
def entry_add_balance(self):
addjust_balance_user = int(self.add_balance.get())
self.add_balance.delete(0, tk.END)
self.balace += addjust_balance_user
self.balance_label.configure(text=f"{self.balace}$")
#First Column
self.row_first_column += 1
new_add_label = ttk.Label(self.window, text=f"+{addjust_balance_user}$")
new_add_label.grid(column=0, row=self.row_first_column, pady=5,padx=15, sticky=tk.E)
app = App()
I'm having trouble resizing the ComboBox. Instead of being on the "Filter Order Status" side, she walked away. I realized that this happened because the size of the grid line was increased due to the size of the largest widget, which in this case are the tables.
How can I place the ComboBox next to "Filter Order Status" as it is in frame2, without changing the table size?
Here the sample code that shows the ComboBox being resized according to the size of the table
from tkinter import *
from tkinter import ttk
def make_table(row, column, window, text=0, headings=[], image=None, letter_pos=LEFT, borderwidth=1):
""" Returns a Frame with the created table """
data = [[0] * column for i in range(row)]
labels = [[0] * column for i in range(row)]
table = Frame(window)
while len(headings) < column:
headings.append(1)
for i in range(row):
# Insert "headings" values in the first line
if i == 0:
labels[i] = [Label(table, text=headings[j], image=image, compound=letter_pos, borderwidth=borderwidth,
relief='groove', anchor=W, width=0) for j in range(column)]
else:
labels[i] = [Label(table, text=0, image=None, compound=LEFT, borderwidth=1,
relief='groove', anchor=W, width=0) for j in range(column)]
for j in range(column):
labels[i][j].grid(row=i, column=j, sticky='we')
return table
window = Tk()
window.grid_rowconfigure(1, weight=1)
window.grid_columnconfigure(0, weight=1)
# Create the Frames
frame1 = Frame(window, bg='yellow')
frame2 = Frame(window, bg='red')
# Position the Frames
frame1.grid(row=0, column=0, sticky='nesw')
frame2.grid(row=0, column=1, sticky='nesw')
""" Frame1 content """
# Create the "frame1" widgets
label1 = Label(frame1, text='frame1')
filter_order_status1 = Label(frame1, text='Filter Order Status')
comboBox_1 = ttk.Combobox(frame1, values=['Entregado', 'Não entregado'])
table1 = make_table(8, 4, frame1, headings=['', 'Customer', 'Order Status', 'Order Date'])
# Place the "frame1" widgets
label1.grid(row=0, column=0, sticky='w')
filter_order_status1.grid(row=1, column=0, sticky='w')
comboBox_1.grid(row=1, column=1, sticky='w')
table1.grid(row=2, column=0, sticky='w')
""" Frame2 content """
# Create the "frame2" widgets
label2 = Label(frame2, text='frame2')
filter_order_status2 = Label(frame2, text='Filter Order Status')
comboBox_2 = ttk.Combobox(frame2, values=['Entregado', 'Não entregado'])
table2 = make_table(8, 4, frame2, headings=[' ', 'Customer'])
# Place the "frame2" widgets
label2.grid(row=0, column=0, sticky='w')
filter_order_status2.grid(row=1, column=0, sticky='w')
comboBox_2.grid(row=1, column=1, sticky='w')
table2.grid(row=2, column=0, sticky='w')
window.mainloop()
The way I would do it is to create a frame specifically to hold just the label and the combobox. You can then easily use pack to align the label to the left and the combobox right next to it.
I am creating a simple entry UI to intake 2 text fields and a folder path. I'm just getting started with tkinter and I can't get the browse button to appear next to the entry field for the CSV file. Instead it appears with the other buttons.
I have read the tkinter tutorial. I've tried three different Frame ideas from coworkers and the web. I did try to put this in an element, but either my brain is fried or I'm just not good enough to understand how that works. I think grids might be my answer, but as this is the first UI I've tried like this I can't follow the code.
import tkinter as tk
fields = 'Version', 'Database Name', 'CSV File'
def fetch(entries):
for entry in entries:
field = entry[0]
text = entry[1].get()
print('%s: "%s"' % (field, text))
def callback():
path = tk.filedialog.askopenfilename()
entry.delete(0, tk.END)
entry.insert(0, path)
def initUI(root, fields):
entries = []
for field in fields:
if field == 'CSV File':
frame = tk.Frame(root)
frame.pack(fill=tk.X)
lbl = tk.Label(frame, text=field, width=20, anchor='w')
lbl.pack(side=tk.LEFT, padx=5, pady=5)
entry = tk.Entry(frame)
entry.pack(fill=tk.X, padx=5)
btn = tk.Button(root, text="Browse", command=callback)
btn.pack(side=tk.RIGHT,padx=5, pady=5)
entries.append((field, entry))
else:
frame = tk.Frame(root)
frame.pack(fill=tk.X)
lbl = tk.Label(frame, text=field, width=20, anchor='w')
lbl.pack(side=tk.LEFT, padx=5, pady=5)
entry = tk.Entry(frame)
entry.pack(fill=tk.X, padx=5, expand=True)
entries.append((field, entry))
return entries
if __name__ == '__main__':
root = tk.Tk()
root.title("Helper")
entries = initUI(root,fields)
root.bind('<Return>', (lambda event, e=entries: fetch(e)))
frame = tk.Frame(root, relief=tk.RAISED, borderwidth=1)
frame.pack(fill=tk.BOTH, expand=True)
closeButton = tk.Button(root, text="Close", command=root.quit)
closeButton.pack(side=tk.RIGHT, padx=5, pady=5)
okButton = tk.Button(root, text="OK", command=(lambda e=entries: fetch(e)))
okButton.pack(side=tk.RIGHT)
root.mainloop()
I am wanting the Browse button next to the entry field instead of its current location down with the OK and Close buttons.
Side problem... I can't figure out how to get my callback to work!
Question: How to keep tkinter button on same row as label and entry box
To reach this you have to pack the Entry and Button into a own Frame.
Note: Use always side=tk.LEFT to get the widgets in a row.
This example shows a OOP solution:
Define a class LabelEntry inherited from tk.Frame.
class LabelEntry(tk.Frame):
def __init__(self, parent, text, button=None):
super().__init__(parent)
self.pack(fill=tk.X)
lbl = tk.Label(self, text=text, width=14, anchor='w')
lbl.pack(side=tk.LEFT, padx=5, pady=5)
Condition: If a Button passed, create a new Frame to pack the Entry and Button.
if button:
frame2 = tk.Frame(self)
frame2.pack(side=tk.LEFT, expand=True)
entry = tk.Entry(frame2)
entry.pack(side=tk.LEFT, fill=tk.X, padx=5)
button.pack(in_=frame2, side=tk.LEFT, padx=5, pady=5)
else:
entry = tk.Entry(self)
entry.pack(side=tk.LEFT, fill=tk.X, padx=5)
Usage:
Define a class App inherit from tk.Tk.
class App(tk.Tk):
def __init__(self):
super().__init__()
self.title("Helper")
frame = tk.Frame(self)
frame.grid(row=0, column=0)
Loop the fields and create a LabelEntry object
entries = []
for field in 'Version', 'Database Name', 'CSV File':
if field == 'CSV File':
button = tk.Button(text="Browse", command=self.callback)
entries.append(LabelEntry(frame, field, button))
else:
entries.append(LabelEntry(frame, field))
Run the Application.
if __name__ == "__main__":
App().mainloop()
Tested with Python: 3.5
I'm placing a scrollbar in a frame, and the frame in a widget. The frame has a label above it. The label above has three columns. The frame with the scrollbar has three columns. I can't get the three columns in the frame and above the frame to line up.
I saw and used the following two questions to get this far, but got stuck.
Adding a scrollbar to a group of widgets in Tkinter
Tkinter - Add scrollbar for each LabelFrame
Any help on lining up the columns would be greatly appreciated. Thanks.
Here's a picture of the widget without the lined up columns:
Columns don't line up
Here's a MWE:
import tkinter as tk
class Selections(tk.Frame):
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
self.FifthLabelLeft = tk.Label(self,
text="""Riding""",
justify = tk.CENTER,
padx = 10).grid(row=4, column = 0, pady=5)
self.FifthLabelCenter = tk.Label(self,
text="""Winning Candidate""",
justify = tk.CENTER,
padx = 10).grid(row=4, column = 1, pady=5)
self.FifthLabelRight = tk.Label(self,
text="""Percent of Vote""",
justify = tk.CENTER,
padx = 10).grid(row=4, column = 2, pady=5)
mybox = tk.LabelFrame(self, padx=5, pady=4)
mybox.grid(row=5, column=0, columnspan=3)
canvas = tk.Canvas(mybox, borderwidth=5, background="#70ff33")
frame = tk.Frame(canvas, background="#33f4ff")
vsb = tk.Scrollbar(mybox, orient="vertical", command=canvas.yview)
canvas.configure(yscrollcommand=vsb.set, width=450, heigh=50)
vsb.pack(side="right", fill="y")
canvas.pack(side="left", fill="both", expand=True)
canvas.create_window((4,4), window=frame, anchor="nw", tags="frame")
# be sure that we call OnFrameConfigure on the right canvas
frame.bind("<Configure>", lambda event: self.OnFrameConfigure(canvas))
self.fillWindow(frame)
self.QuitButton = tk.Button(self,
text="QUIT",
command=root.destroy,
padx=25, pady=0)
self.QuitButton.grid(column = 0, columnspan=3)
def fillWindow(self, frame):
PartyWinnersList = [['Some list of places', "Somebody's Name", 0.37448599960838064],
['A shorter list', 'Three Long Names Here', 0.52167817821240514],
['A much longer, longer entry', 'Short Name', 0.41945832387008858]]
placement = 2
for i in PartyWinnersList:
ShowYear = tk.Label(frame,
text="""%s """ % i[0]
)
ShowYear.grid(row=placement, column = 0, sticky=tk.S)
ShowSystem = tk.Label(frame,
text="""%s """ % i[1]
)
ShowSystem.grid(row=placement, column = 1, sticky=tk.N)
PercentVotes = i[2]*100
ShowVotes = tk.Label(frame,
text="""%3.1f""" % PercentVotes
)
ShowVotes.grid(row=placement, column = 2, sticky=tk.N)
placement += 1
def OnFrameConfigure(self, canvas):
canvas.configure(scrollregion=canvas.bbox("all"))
if __name__ == "__main__":
root = tk.Tk()
main = Selections(root)
main.pack(side="top", fill="both", expand=True)
root.mainloop()
The two defined functions are in the class, but I couldn't get them to line up.
I usually don't solve the problem this way, but you can force alignment by specifying label widths. The problem will come when you dynamically resize the window -- everything is static. But this will solve the specified problem -- alignment.
import tkinter as tk
class Selections(tk.Frame):
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
self.FifthLabelLeft = tk.Label(self,
text="""Riding""",
justify = tk.CENTER,
width=25,padx = 10)
self.FifthLabelLeft.grid(row=4, column = 0, pady=5)
self.FifthLabelCenter = tk.Label(self,
text="""Winning Candidate""",
justify = tk.CENTER,
width=25,
padx = 10).grid(row=4, column = 1, pady=5)
self.FifthLabelRight = tk.Label(self,
text="""Percent of Vote""",
justify = tk.CENTER,
padx = 10).grid(row=4, column = 2, pady=5)
mybox = tk.LabelFrame(self, padx=5, pady=4)
mybox.grid(row=5, column=0, columnspan=3)
canvas = tk.Canvas(mybox, borderwidth=5, background="#70ff33")
frame = tk.Frame(canvas, background="#33f4ff")
# frame.grid_columnconfigure((0,1,2), weight=3)
vsb = tk.Scrollbar(mybox, orient="vertical", command=canvas.yview)
canvas.configure(yscrollcommand=vsb.set, width=450, heigh=50)
vsb.pack(side="right", fill="y")
canvas.pack(side="left", fill="both", expand=True)
canvas.create_window((4,4), window=frame, anchor="nw", tags="frame")
# be sure that we call OnFrameConfigure on the right canvas
frame.bind("<Configure>", lambda event: self.OnFrameConfigure(canvas))
self.fillWindow(frame)
self.QuitButton = tk.Button(self,
text="QUIT",
command=root.destroy,
padx=25, pady=0)
self.QuitButton.grid(column = 0, columnspan=3)
def fillWindow(self, frame):
PartyWinnersList = [['Some list of places', "Somebody's Name", 0.37448599960838064],
['A shorter list', 'Three Long Names Here', 0.52167817821240514],
['A much longer, longer entry', 'Short Name', 0.41945832387008858]]
placement = 2
for i in PartyWinnersList:
ShowYear = tk.Label(frame, text="""%s """ % i[0], width=25)
ShowYear.grid(row=placement, column = 0, sticky=tk.S)
ShowSystem = tk.Label(frame,
text="""%s """ % i[1],
width=25
)
ShowSystem.grid(row=placement, column = 1, sticky=tk.N)
PercentVotes = i[2]*100
ShowVotes = tk.Label(frame,
text="""%3.1f""" % PercentVotes,
width=15
)
ShowVotes.grid(row=placement, column = 2, sticky=tk.N)
placement += 1
def OnFrameConfigure(self, canvas):
canvas.configure(scrollregion=canvas.bbox("all"))
if __name__ == "__main__":
root = tk.Tk()
main = Selections(root)
main.pack(side="top", fill="both", expand=True)
root.mainloop()
The problem I'm currently stuck with is that when I add a new shift I can't get the GUI to update properly. Currently the best I can seem to get is getting the updated information but it is displayed on top of the old information.
I did read about the whole mainloop() issue and tried to get use the after() method but I'm not sure if thats what I'm looking for:
class ViewShifts(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
buttonFrame = tk.Frame(self)
buttonFrame.pack(side='bottom', fill='both', expand=True)
#frame to display shifts
table = tk.Frame(self)
table.pack(side='top', fill='both', expand=True)
table.destroy()
#dictionary which will contain widgets that will display shifts (in viewNew method)
self.widgets = {}
button1= tk.Button(self, text="Home",
command=lambda: controller.showFrame(StartPage))
button1.pack(padx=0, pady=10, side='bottom')
button2 = tk.Button(self, text='Update',
command=lambda: deleteShiftFrame(self))
button2.pack(padx=0, pady=10, side='bottom')
text = tk.Label(self, text="All shifts", font=LARGEFONT)
text.pack(padx=10, side='top')
def deleteShiftFrame(self):
table.destroy()
viewNew(self)
def viewNew(self):
#frame to display shifts
table = tk.Frame(self)
table.pack(side='top', fill='both', expand=True)
row = 0
#make dictionary empty
self.widgets = {}
c.execute("SELECT * FROM shifts")
data = c.fetchall()
#create labels for each column
date_label = tk.Label(table, text="Date")
shift_label=tk.Label(table, text="Shift")
shop_label=tk.Label(table, text="Shop")
hours_label=tk.Label(table, text="Hours")
#add labels to grid
date_label.grid(row=0, column=0, sticky="nsw")
shift_label.grid(row=0, column=1, sticky="nsw")
shop_label.grid(row=0, column=2, sticky="nsw")
hours_label.grid(row=0, column=3, sticky="nsw")
#for each column create a tk label for each row within column with corresponding details
for id, date, shift, shop, hours in (data):
row+=1
self.widgets[id] = {
"id":tk.Label(table, text=id),
"date":tk.Label(table, text=date),
"shift":tk.Label(table, text=shift),
"shop":tk.Label(table, text=shop),
"hours":tk.Label(table, text=hours)
}
#add current row of column to grid
self.widgets[id]["date"].grid(row=row, column=0, sticky="nsw")
self.widgets[id]["shift"].grid(row=row, column=1, sticky="nsw")
self.widgets[id]["shop"].grid(row=row, column=2, sticky="nsw")
self.widgets[id]["hours"].grid(row=row, column=3, sticky="nsw")
#add blank column between each field for spacing
table.grid_columnconfigure(0, weight=1)
table.grid_columnconfigure(1, weight=1)
table.grid_columnconfigure(2, weight=1)
table.grid_columnconfigure(3, weight=1)
#add extra row for padding
table.grid_rowconfigure(row+1, weight=1)
viewNew(self)
class AddShifts(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
text = tk.Label(self, text = "Add shifts", font=LARGEFONT)
text.pack(padx=10, side = 'top')
#create frame for entry
AddShiftFrame = tk.Frame(self)
AddShiftFrame.pack(side="top", fill="both", expand=True)
#add column headers
dateLabel = tk.Label(AddShiftFrame, text="Date")
shiftLabel = tk.Label(AddShiftFrame, text="Shift")
shopLabel = tk.Label(AddShiftFrame, text='Shop')
dateLabel.grid(row=1, column=0, sticky="nsw")
shiftLabel.grid(row=1, column=1, sticky="nsw")
shopLabel.grid(row=1, column=2, sticky="nsw")
#create dictionary of widgets
self.widgets = {
"Date":tk.Entry(AddShiftFrame),
"Shift":tk.Entry(AddShiftFrame),
"Shop":tk.Entry(AddShiftFrame)
}
#add widgets to frame
self.widgets["Date"].grid(row=2, column=0, sticky="nsw")
self.widgets["Shift"].grid(row=2, column=1, sticky="nsw")
self.widgets["Shop"].grid(row=2, column=2, sticky="nsw")
#this method will submit the data (callback function)
def submit_data(self):
shift_data = [(self.widgets["Date"].get()), (self.widgets["Shift"].get()), (self.widgets["Shop"].get())]
c.execute("INSERT INTO shifts (date, shift, shop) VALUES(?,?,?)", (shift_data[0], shift_data[1], shift_data[2]))
conn.commit()
print("done")
#submit button
submit = tk.Button(self, text="Submit",
command= lambda: submit_data(self))
submit.pack(padx=10, pady=10, side="left")
#home button
button1 = tk.Button(self, text="Home",
command=lambda: controller.showFrame(StartPage))
button1.pack(padx=10, pady=10, side='left')
app = MainApplication()
app.after(1000, getShifts)
app.mainloop()