I'm trying to create a sudoku solver. I have my grid with the entries at this point but I don't know how to get the values that the user has put in them.
I have no clue yet as to how I'm going to make the Sudoku solver but I think I'll first have to find a way to store the input in some variable(s) so I can work with them later on.
So my question is, how do I get the values that have been filled into the entries?
This is my code thus far:
from tkinter import *
root = Tk()
root.title('Sudoku Solver')
root.geometry('500x400')
mylabel = Label(root, text='Fill in the numbers and click solve').grid(row=0, column=0, columnspan=10)
# Create the grid
def beg():
global e
cells = {}
for row in range(1, 10):
for column in range(1, 10):
if ((row in (1,2,3,7,8,9) and column in (4,5,6)) or (row in (4,5,6) and column in (1,2,3,7,8,9))):
kleur='black'
else:
kleur='white'
cell = Frame(root, bg='white', highlightbackground=kleur,
highlightcolor=kleur, highlightthickness=2,
width=50, height=50, padx=3, pady=3, background='black')
cell.grid(row=row, column=column)
cells[(row, column)] = cell
e = Entry(cells[row, column], width=4, bg='white', highlightthickness=0, fg='black', relief=SUNKEN)
e.pack()
# Tell the button what to do
def solve():
global e
test = e.get()
print(test)
# Create the buttons and give them a command
clearer = Button(root, text='Clear', command=beg)
solver = Button(root, text='Solve', command=solve)
# Locate the buttons
clearer.grid(row=11, column=3, pady=30)
solver.grid(row=11, column=7, pady=30)
# Run it for the first time
beg()
root.mainloop()
I also tried changing e to e[row, column] but that gave me a syntax error.
Standard rule: if you have many elements then keep them on list or dictionary.
Do the same as with cells
Create dictionary
entries = {}
add to dictionary
entries[(row, column)] = e
and get from dictionary
def solve():
for row in range(1, 10):
for column in range(1, 10):
print(row, column, entries[(row, column)].get() )
# from tkinter import * # PEP8: `import *` is not preferred
import tkinter as tk
# --- functions ---
# Create the grid
def beg():
# remove old widgets before creating new ones
for key, val in cells.items():
print(key, val)
val.destroy()
for row in range(1, 10):
for column in range(1, 10):
if ((row in (1,2,3,7,8,9) and column in (4,5,6)) or (row in (4,5,6) and column in (1,2,3,7,8,9))):
kleur='black'
else:
kleur='white'
cell = tk.Frame(root, bg='white', highlightbackground=kleur,
highlightcolor=kleur, highlightthickness=2,
width=50, height=50, padx=3, pady=3, background='black')
cell.grid(row=row, column=column)
cells[(row, column)] = cell
e = tk.Entry(cell, width=4, bg='white', highlightthickness=0, fg='black', relief='sunken')
e.pack()
entries[(row, column)] = e
# Tell the button what to do
def solve():
for row in range(1, 10):
for column in range(1, 10):
print(row, column, entries[(row, column)].get() )
# --- main ---
entries = {}
cells = {}
root = tk.Tk()
root.title('Sudoku Solver')
root.geometry('500x400')
mylabel = tk.Label(root, text='Fill in the numbers and click solve')
mylabel.grid(row=0, column=0, columnspan=10)
# Create the buttons and give them a command
clearer = tk.Button(root, text='Clear', command=beg)
solver = tk.Button(root, text='Solve', command=solve)
# Locate the buttons
clearer.grid(row=11, column=2, pady=30, columnspan=3) # I added `columnspan=3`
solver.grid(row=11, column=6, pady=30, columnspan=3) # I added `columnspan=3`
# Run it for the first time
beg()
root.mainloop()
Related
I am using python3 tkinter. I am trying to update a table to dynamically add new lines of Entry widgets.
The layout is as follows:
frame_canvas include a canvas and a scrollbar
frame_entries is on the canvas, showing 5x7 windows only
frame_entries holds a 2-dimensional Entry table
I'd like to dynamically add new rows on the Entry table, thus, adding new Entry rows on frame_entries frame.
The problem now is that the addition of these new widgets won't update the widgets display, it would only replace the last row of Entry table on the screen. (data was updated correctly on the background, just the problem of display update)
I tried to call canvas.update() and frame_entries.update() but no use. Scrollbar doesn't reflect the updated Entry table either.
I updated the code snippet so you can download and try.
import tkinter as tk
total_columns = 5
total_rows = 18
tbl = []
def add_row_table():
global total_rows
new_row: list[Entry] = [tk.Entry() for _ in range(total_columns)]
for j in range(total_columns):
new_row[j] = tk.Entry(frame_entries, width=20)
new_row[j].grid(row=total_rows, column=j, sticky="news")
new_row[j].insert(tk.END, total_rows)
total_rows += 1
# canvas.update_idletasks()
# frame_entries.update_idletasks()
tbl.append(new_row)
root = tk.Tk()
root.grid_rowconfigure(0, weight=1)
root.columnconfigure(0, weight=1)
frame_main = tk.Frame(root, bg="gray")
frame_main.grid(sticky='news')
button2 = tk.Button(frame_main, text="Add Row", fg="green", command=add_row_table)
button2.grid(row=0, column=1, pady=(5, 0), sticky='nw')
frame_canvas = tk.Frame(frame_main)
frame_canvas.grid(row=2, column=0, pady=(5, 0), sticky='nw')
frame_canvas.grid_rowconfigure(0, weight=1)
frame_canvas.grid_columnconfigure(0, weight=1)
# Set grid_propagate to False to allow table resizing later
frame_canvas.grid_propagate(False)
canvas = tk.Canvas(frame_canvas, bg="yellow")
canvas.grid(row=0, column=0, sticky="news")
vsb = tk.Scrollbar(frame_canvas, orient="vertical", command=canvas.yview)
vsb.grid(row=0, column=1, sticky='ns')
canvas.configure(yscrollcommand=vsb.set)
frame_entries = tk.Frame(canvas, bg="blue")
canvas.create_window((0, 0), window=frame_entries, anchor='nw')
for i in range(total_rows):
line = [tk.Entry() for j in range(total_columns)]
for j in range(total_columns):
line[j] = tk.Entry(frame_entries, width=20)
line[j].grid(row=i, column=j, sticky="news")
line[j].insert(tk.END, i)
tbl.append(line)
frame_entries.update_idletasks()
columns_width = sum([tbl[0][j].winfo_width() for j in range(total_columns)])
rows_height = sum([tbl[i][0].winfo_height() for i in range(5)])
frame_canvas.config(width=columns_width + vsb.winfo_width(),
height=rows_height+150)
canvas.config(scrollregion=canvas.bbox("all"))
root.mainloop()
You need to update scrollregion of canvas after adding entries to frame_entries:
...
# function to be called whenever frame_entries is resized
def frame_entries_resized(event):
# update canvas scrollregion
canvas.config(scrollregion=canvas.bbox('all'))
...
frame_entries = tk.Frame(canvas, bg="blue")
# monitor size of frame_entries
frame_entries.bind('<Configure>', frame_entries_resized)
canvas.create_window((0, 0), window=frame_entries, anchor='nw')
...
Note that you have created duplicate set of entries:
for i in range(total_rows):
# initialise with entries into 'line'
line = [tk.Entry() for j in range(total_columns)]
# then assign new entry into 'line' again
for j in range(total_columns):
line[j] = tk.Entry(frame_entries, width=20)
line[j].grid(row=i, column=j, sticky="news")
line[j].insert(tk.END, i)
tbl.append(line)
You can initialize line as list of None instead:
line = [None for j in range(total_columns)]
Same issue inside add_row_table():
def add_row_table():
global total_rows
# should initialise new_row as list of None instead
new_row: list[Entry] = [tk.Entry() for _ in range(total_columns)]
for j in range(total_columns):
new_row[j] = tk.Entry(frame_entries, width=20)
new_row[j].grid(row=total_rows, column=j, sticky="news")
new_row[j].insert(tk.END, total_rows)
total_rows += 1
# canvas.update_idletasks()
# frame_entries.update_idletasks()
tbl.append(new_row)
I have the following script and the following GUI.
Question(s):
How can I vertically center the 4 boxes on the left side? (There is extra space at the bottom).
I currently have grid with rows and columns which I thought would default vertically center, but that seems to not be the case. Or I did it wrong?
Within mid, I have 2 frames that contain a series of buttons. I tried to place one of the frames above the buttons using the grid(row=) but that doesn't move the frame at all. I expected the behavior of the left view that contains the boxes but it didn't work out. How can I get one frame of boxes above the other?
Note: I'm sure there are simple solutions, I'm just missing it.
Note: I know I could use iteration for most of this, but I was looking to build up my tkinter skills hard-coding and then re-develop with more advanced topics.
Tkinter Script.txt
import tkinter as tk
from tkinter import *
#####################################################################################################
# UI
# Main Window
window = tk.Tk()
window.geometry('700x800')
## 3 Frames
left = tk.Frame(master=window)
mid = tk.Frame(master=window)
right = tk.Frame(master=window)
left.grid(row=0, column=1)
mid.grid(row=0, column=2)
right.grid(row=0, column=3)
## left
### Box1
box1_frame = tk.Frame(master=left)
box1_frame.grid(row=0, column=0)
#### Label
box1_label = tk.Label(master=box1_frame, text="Box1")
box1_label.pack()
#### Text
box1_text = tk.Text(master=box1_frame, width=20, height=10)
box1_text.pack()
### Box2
box2_frame = tk.Frame(master=left)
box2_frame.grid(row=1, column=0)
#### Label
box2_label = tk.Label(master=box2_frame, text="Box2")
box2_label.pack()
#### Text
box2_text = tk.Text(master=box2_frame, width=20, height=10)
box2_text.pack()
### Box3
box3_frame = tk.Frame(master=left)
box3_frame.grid(row=2, column=0)
#### Label
box3_label = tk.Label(master=box3_frame, text="Box3")
box3_label.pack()
#### Text
box3_text = tk.Text(master=box3_frame, width=20, height=10)
box3_text.pack()
### Box4
box4_frame = tk.Frame(master=left)
box4_frame.grid(row=3, column=0)
#### Label
box4_label = tk.Label(master=box4_frame, text="Box4")
box4_label.pack()
#### Text
box4_text = tk.Text(master=box4_frame, width=20, height=10)
box4_text.pack()
## Mid
### Buttons
button_frame = tk.Frame(master=mid)
button_frame.grid(row=0, column=0)
for r in range(3):
for c in range(4):
tk.Button(mid, text="Ironman", borderwidth=1).grid(row=r, column=c, padx=12, pady=4)
some_frame = tk.Frame(master=mid)
some_frame.grid(row=0, column=1)
for r in range(3):
for c in range(4):
tk.Button(mid, text="Taco", borderwidth=1).grid(row=r, column=c, padx=12, pady=4)
#####################################################################################################
# Functions
# Start main loop
window.mainloop()
Edit 1:
I changed it to the correct parent view for the individual buttons and still obtain the SAME output. Nothing has changed.
Mid
Buttons
button_frame = tk.Frame(master=mid)
button_frame.grid(row=0, column=0)
for r in range(3):
for c in range(4):
tk.Button(button_frame, text="Ironman", borderwidth=1).grid(row=r, column=c, padx=12, pady=4)
some_frame = tk.Frame(master=mid)
some_frame.grid(row=0, column=1)
for r in range(3):
for c in range(4):
tk.Button(some_frame, text="Taco", borderwidth=1).grid(row=r, column=c, padx=12, pady=4)
Output
I have two questions related to this attached code. This code is a part of my project in which i have to manage the attendance of 50 (or more) students.
When you will run this piece of code, you will see that there is a extra white space (that might be of the canvas) inside the Label Frame i.e. Attendance_Frame. All I wanted is that the there should be no extra white space and the scrollbar, instead of being at the extreme right, should be at the place where the labels end.
I have searched for the answer to my question and saw a similar case. But there, the person wanted the frame to expand to the canvas size. Link (Tkinter: How to get frame in canvas window to expand to the size of the canvas?).
But in my case, I want the canvas size to be equal to frame size (although the frame lies inside the canvas)
The other thing I want is that all the check boxes should initially be 'checked' (showing the present state) and when I uncheck random checkboxes (to mark the absent), and click the 'Submit' button (yet to be created at the bottom of the window), I should get a list with 'entered date' as first element and the roll numbers i.e. 2018-MC-XX as other elements. For example : ['01/08/2020', '2018-MC-7', '2018-MC-11', '2018-MC-23', '2018-MC-44'].
Actually my plan is when i will get a list i will easily write it to a text file.
from tkinter import *
from tkcalendar import DateEntry
root = Tk()
root.geometry('920x600+270+50')
root.minsize(920,600)
Attendance_frame = Frame(root) ### Consider it a Main Frame
Attendance_frame.pack()
attendaceBox = LabelFrame(Attendance_frame, text = 'Take Attendance', bd = 4, relief = GROOVE, labelanchor = 'n',font = 'Arial 10 bold', fg = 'navy blue', width = 850, height = 525) # A Label Frame inside the main frame
attendaceBox.pack_propagate(0)
attendaceBox.pack(pady = 15)
dateFrame = Frame(attendaceBox) # A small frame to accommodate date entry label & entry box
dateFrame.pack(anchor = 'w')
font = 'TkDefaultFont 10 bold'
date_label = Label(dateFrame, text = 'Enter Date : ', font = font).grid(row = 0, column = 0, sticky = 'w', padx = 10, pady = 10)
date_entry = DateEntry(dateFrame, date_pattern = 'dd/mm/yyyy', showweeknumbers = FALSE, showothermonthdays = FALSE)
date_entry.grid(row = 0, column = 1, sticky = 'w')
noteLabel = Label(attendaceBox, text = 'Note: Uncheck the boxes for absentees').pack(anchor = 'w', padx = 10, pady = 5)
canvas = Canvas(attendaceBox, borderwidth=0, background="#ffffff")
checkFrame = Frame(canvas, width = 100, height = 50)
vsb = Scrollbar(canvas, orient="vertical", command=canvas.yview)
canvas.configure(yscrollcommand=vsb.set)
vsb.pack(side="right", fill="y")
canvas.pack(side="left", fill="both", expand=True)
canvas.pack_propagate(0)
canvas.create_window((4,4), window=checkFrame, anchor="nw")
def onFrameConfigure(canvas):
'''Reset the scroll region to encompass the inner frame'''
canvas.configure(scrollregion=canvas.bbox("all"))
checkFrame.bind("<Configure>", lambda event, canvas=canvas: onFrameConfigure(canvas))
for i in range(0,51): # A loop to create Labels of students roll numbers & names
c = Checkbutton(checkFrame, text = f"{'2018-MC-'+str(i+1)} Student {i+1}")
c.grid(row = i, column = 0, padx = 10, sticky = 'w')
mainloop()
If you are creating a vertical list of items, you don't need to use a frame inside the canvas. The inner frame adds some unnecessary complexity. Instead, create the checkbuttons directly on the canvas with create_window.
You also need to configure the scrollregion attribute so that the scrollbar knows how much of the virtual canvas to scroll.
Finally, to have them selected you should assign a variable to each checkbutton, and make sure that the value is the proper value. By default checkbuttons use the values 0 and 1, so setting the variable to 1 will make it selected.
vars = []
for i in range(0,51):
var = IntVar(value=1)
vars.append(var)
x0, y0, x1, y1 = canvas.bbox("all") or (0,0,0,0)
c = Checkbutton(canvas, text = f"{'2018-MC-'+str(i+1)} Student {i+1}", variable=var)
canvas.create_window(2, y1+4, anchor="nw", window=c)
canvas.configure(scrollregion=canvas.bbox("all"))
Your all questions answer is here:
You should try this.
import tkinter as tk
from tkcalendar import DateEntry
root = tk.Tk()
root.geometry('920x600+270+50')
root.minsize(960, 600)
root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)
Attendance_frame = tk.Frame(root)
Attendance_frame.grid(row=0, column=0, sticky='nsew')
attendaceBox = tk.LabelFrame(Attendance_frame,
text='Take Attendance',
bd=4,
relief='groove',
labelanchor='n',
font='Arial 10 bold',
fg='navy blue',
width=850,
height=525)
attendaceBox.grid(row=0, column=0, sticky='nsew', padx=15)
Attendance_frame.columnconfigure(0, weight=1)
Attendance_frame.rowconfigure(0,weight=1)
dateFrame = tk.Frame(attendaceBox) # A small frame to accommodate date entry label & entry box
dateFrame.grid(row=0, column=0, sticky='nsew')
font = 'TkDefaultFont 10 bold'
date_label = tk.Label(dateFrame, text='Enter Date : ', font=font)
date_label.grid(row=0, column=0, sticky='w', padx=10, pady=10)
date_entry = DateEntry(dateFrame, date_pattern='dd/mm/yyyy', showweeknumbers=False, showothermonthdays=False)
date_entry.grid(row=0, column=1, sticky='w')
noteLabel = tk.Label(attendaceBox, text='Note: Uncheck the boxes for absentees', anchor='w')
noteLabel.grid(row=1, column=0, sticky='nsew')
attendaceBox.rowconfigure(2, weight=1)
canvas = tk.Canvas(attendaceBox, width=200, borderwidth=0, background="#ffffff")
# You can set width of canvas according to your need
canvas.grid(row=2, column=0, sticky='nsew')
canvas.columnconfigure(0, weight=1)
canvas.rowconfigure(0, weight=1)
vsb = tk.Scrollbar(attendaceBox, orient="vertical", command=canvas.yview)
vsb.grid(row=2, column=1, sticky='nsew')
canvas.configure(yscrollcommand=vsb.set)
checkFrame = tk.Frame(canvas, bg='green')
canvas.create_window((0, 0), window=checkFrame, anchor="nw", tags='expand')
checkFrame.columnconfigure(0, weight=1)
for i in range(0, 51): # A loop to create Labels of students roll numbers & names
c = tk.Checkbutton(checkFrame, anchor='w', text=f"{'2018-MC-' + str(i + 1)} Student {i + 1}")
c.grid(row=i, column=0, sticky='nsew')
c.select()
canvas.bind('<Configure>', lambda event: canvas.itemconfigure('expand', width=event.width))
checkFrame.update_idletasks()
canvas.config(scrollregion=canvas.bbox('all'))
root.mainloop()
Get Selected Value
vars = []
for i in range(0, 51): # A loop to create Labels of students roll numbers & names
var = tk.IntVar()
c = tk.Checkbutton(checkFrame,
variable=var,
anchor='w', text=f"{'2018-MC-' + str(i + 1)} Student {i + 1}")
c.grid(row=i, column=0, sticky='nsew')
c.select()
vars.append(var)
def state():
print(list(map((lambda var: var.get()), vars)))
This is my main code that creates a GUI. The user can enter the numbers or generate random numbers and it will sort it. However, i want it to change colour with each step taken in the sorting algorithm, and then change to a green colour once the array has been sorted.
import random
from tkinter import *
import Swap
numberArray = list()
def arrayList(number):
arrayListEntry.delete(0, END)
numberArray.append(number)
e.config(text=str(numberArray))
print numberArray
def randomiser():
for i in range(10):
numberArray.append(random.randint(1,100))
e.config(text=str(numberArray))
print numberArray
# Main selection sort function
def selectionSort(numberList):
for i in range(len(numberList)):
minimumIndex = i
print("\nMinimum index: " + str(minimumIndex))
for l in range(i + 1, len(numberList)):
if numberList[minimumIndex] > numberList[l]:
minimumIndex = l
print(numberArray)
Swap.startSwap(numberList, i, minimumIndex)
e.config(text=str(numberArray))
root.update()
root.after(1000)
e.config(text=str(numberArray))
width = 300
height = 250
root = Tk()
frame = Frame(root, width=width, height=height)
frame.grid(row=3, column=0, columnspan=3)
e = Label(root, text="Arraylist")
e.grid(row=1, column=1)
arrayListLabel = Label(root, text="Array List")
arrayListEntry = Entry(root)
arrayListButton = Button(root, text="Enter", command=lambda: arrayList(arrayListEntry.get()))
arrayListButton.grid(row=0, column=3)
sortButton = Button(root, text="Sort", command=lambda: selectionSort(numberArray))
sortButton.grid(row=2, column=1)
randomButton = Button(root, text="Randomise", command=lambda: randomiser())
randomButton.grid(row=3, column=1)
arrayListLabel.grid(row=0, column=0)
arrayListEntry.grid(row=0, column=1)
root.mainloop()
This is my swap method in another class, ignore the last line as that is only for the console for me to see what is happening
# Swap function for swaping the index in the array
def startSwap(array, firstIndex, secondIndex):
swapObject = array[firstIndex]
array[firstIndex] = array[secondIndex]
array[secondIndex] = swapObject
print("Number " + str(array[firstIndex]) + " swapped with number " + str(array[secondIndex]) + " in array\n")
I removed the frame widget as it was complicating the task of changing the color of the entire background.
I made the following changes inside the startSwap() function to change the colors at every step of the algorithm
First I created a list of color names:
colors = ['red', 'blue', 'orange', 'yellow']
Next, I randomly set the foreground color from the colors list. You can add other colors to increase randomness of color selection.
e.config(fg=random.choice(colors))
Finally when the the list of numbers are sorted, set the foreground color to green inside of the selectionSort() function
e.config(fg='green')
Here's the entire working code:
import random
from tkinter import *
#import Swap
root = Tk()
# define label before using it
e = Label(root, text="Arraylist")
e.grid(row=1, column=1, padx=10, pady=10)
numberArray = list()
def arrayList(number):
arrayListEntry.delete(0, END)
numberArray.append(number)
e.config(text=str(numberArray))
#print numberArray
def randomiser():
for i in range(10):
numberArray.append(random.randint(1,100))
e.config(text=str(numberArray))
#print numberArray
def startSwap(array, firstIndex, secondIndex):
# color list
colors = ['red', 'blue', 'orange']
# set a random color from the colors list
e.config(fg=random.choice(colors))
swapObject = array[firstIndex]
array[firstIndex] = array[secondIndex]
array[secondIndex] = swapObject
# Main selection sort function
def selectionSort(numberList):
for i in range(len(numberList)):
minimumIndex = i
for l in range(i + 1, len(numberList)):
if numberList[minimumIndex] > numberList[l]:
minimumIndex = l
#Swap.startSwap(numberList, i, minimumIndex)
startSwap(numberList, i, minimumIndex)
e.config(text=str(numberArray))
root.update()
root.after(1000)
e.config(text=str(numberArray))
# once numbers are sorted, set foreground as green
e.config(fg='green')
arrayListLabel = Label(root, text="Array List")
arrayListEntry = Entry(root)
arrayListButton = Button(root, text="Enter", command=lambda: arrayList(arrayListEntry.get()))
arrayListButton.grid(row=0, column=3, padx=10, pady=10)
sortButton = Button(root, text="Sort", command=lambda: selectionSort(numberArray))
sortButton.grid(row=2, column=1, pady=10)
randomButton = Button(root, text="Randomise", command=lambda: randomiser())
randomButton.grid(row=3, column=1, pady=10)
arrayListLabel.grid(row=0, column=0, padx=10, pady=10)
arrayListEntry.grid(row=0, column=1)
root.mainloop()
Lastly, I added some padding to the Label and Button widgets.
So I've been struggling with an issue for a week or so, been googling around trying to find different solutions, etc and getting nowhere. I was advised to put functioning code on here so I've cut it down some while still showing the issue.
I want to have a main page listing a set of goals, then if you click on the "Goal Entry" button up top a new window opens where you can input additional goals. Then you type in your desired additions, hit enter, and it adds it to the list on the main page.
I've accomplished all of the above EXCEPT, after you add the goals (and I have the list printing before and after so I know they're being added) and the entry window closes, the list of labels (created by an iteration) hasn't updated accordingly.
How do I get the list on the main page to automatically update when a new item is added to the list?
from tkinter import *
pg = ["goal1","goal2"]
pgtotal=1
psum=len(pg)
class yeargoals():
global pg, hg, fg, rg, rgtotal
def __init__(self,master):
self.master = master
master.title("This Year's Goals")
self.buttonframe = Frame(root)
self.buttonframe.pack(side=TOP, padx = 150, fill=BOTH)
self.home = Button(self.buttonframe, text="Home Page")
self.home.grid(row=1, column=1, padx=10)
self.enter = Button(self.buttonframe, text="Goal Entry", command=self.winenter)
self.enter.grid(row=1, column=2, padx=10)
self.finalize = Button(self.buttonframe, text="Finalize for Year")
self.finalize.grid(row=1, column=3, padx=10)
self.dashboard = Button(self.buttonframe, text="Goal Dashboard")
self.dashboard.grid(row=1,column=4, padx=10)
self.goalframe = Frame(root)
self.goalframe.pack(side=TOP, padx=150, pady=50, fill=BOTH, expand = True)
#Makes the label Fram I want the Checkboxes to go in
self.LabelFramep= LabelFrame(self.goalframe,text="Professional Goals")
self.LabelFramep.pack(side=LEFT, padx=10, anchor = N, fill=BOTH, expand = True)
#Makes the from the list above
for goal in pg:
l = Checkbutton(self.LabelFramep, text=goal, variable=Variable())
l.config(font=("Courier",12))
l.grid(sticky=W)
self.ptotal=Label(self.LabelFramep,text="Progress so far: "+str(pgtotal)+"/"+str(psum))
self.ptotal.config(font=("Courier",12))
self.ptotal.grid(sticky=W)
self.pper=Label(self.LabelFramep, text=str(round((pgtotal/psum)*100))+"% Complete")
self.pper.config(font=("Courier",12))
self.pper.grid(sticky=W)
def winenter(self):
global pg
self.winenter = Toplevel(root)
options = ["Professional", "Health", "Financial", "Reward Items"]
variable = StringVar(self.winenter)
variable.set(options[0])
#Title of entry section
t1 = Label(self.winenter, text="New Goal Entry")
t1.grid(row=0, column=1, columnspan=2)
#dropdown menu
d = OptionMenu(self.winenter, variable, *options)
d.grid(row=1, column=2)
#entry fields
e1 = Entry(self.winenter)
e1.grid(row=2, column=2, padx = 10, pady=5)
e2 = Entry(self.winenter)
e2.grid(row=3, column=2, padx=10, pady=5)
e3 = Entry(self.winenter)
e3.grid(row=4, column=2, padx=10, pady=5)
e4 = Entry(self.winenter)
e4.grid(row=5, column=2, padx=10, pady=5)
e5 = Entry(self.winenter)
e5.grid(row=6, column=2, padx=10, pady=5)
#Label for entry fields
l1 = Label(self.winenter, text="Goal Number 1")
l1.grid(row=2, column=1)
l2 = Label(self.winenter, text="Goal Number 2")
l2.grid(row=3, column=1)
l3 = Label(self.winenter, text="Goal Number 3")
l3.grid(row=4, column=1)
l4 = Label(self.winenter, text="Goal Number 4")
l4.grid(row=5, column=1)
l5 = Label(self.winenter, text="Goal Number 5")
l5.grid(row=6, column=1)
def enter():
global pg, main
print (pg)
if variable.get() == "Professional":
pg.append(e1.get())
self.winenter.destroy()
print (pg)
#Goal entry execute button
b = Button(self.winenter, text="Enter Goals", command=enter)
b.grid(row=7, column = 1)
root = Tk()
Window = yeargoals(root)
root.mainloop()
In your callback function to button "Enter Goals", you have done nothing to update your main window. Maybe you think the main window will magically keep updated with the variable pg, no, you need to do all those updates manually in your callback function.
For example, change your callback enter() to:
def enter():
global pg, main
print (pg)
if variable.get() == "Professional":
pg.append(e1.get())
l = Checkbutton(self.LabelFramep, text=pg[-1], variable=Variable())
l.config(font=("Courier",12))
l.grid(sticky=W)
self.winenter.destroy()
print (pg)
You can find the main window is updated after you click "Enter Goals".