I am creating a table like this in tkinter, https://www.geeksforgeeks.org/create-table-using-tkinter/. I am unable to update specific sections, have not been able to find anything that works yet.
# code for creating table
for i in range(5):
for j in range(5):
example_table = tkinter.Entry(root, width=20, fg='blue',
font=('Arial',16,'bold'))
example_table.grid(row=i, column=j)
example_table.insert(tkinter.END, "f")
After creating the table, If I want to update the 4th row and 4th column, how would I do so?
The simplest way would be to keep a reference to each entry within the table class using a 2d list, and then you can just access each entry from it's index value
for example:
from tkinter import *
class Table:
def __init__(self,root):
self.entries = [] # now each of the entries will be stored in rows
# code for creating table
for i in range(total_rows):
row = [] # this will actually contain 1 row of cell entry widgets
for j in range(total_columns):
e = Entry(root, width=20, fg='blue',
font=('Arial',16,'bold'))
e.grid(row=i, column=j)
e.insert(END, lst[i][j])
row.append(e)
self.entries.append(row)
lst = [(1,'Raj','Mumbai',19),
(2,'Aaryan','Pune',18),
(3,'Vaishnavi','Mumbai',20),
(4,'Rachna','Mumbai',21),
(5,'Shubham','Delhi',21)]
# this is the function that updates the table
def updateTable(row, col):
e = t.entries[row][col] # get the entry at row, col
val = e.get() # Get the current text in cell
e.delete(0,last=len(val)) # remove current text
e.insert(END, "Something Differnet") # insert new text
root = Tk()
t = Table(root)
# clicking this button will change the cell text for 4th column 4th row
B = Button(root, text="Change Table", command=lambda: updateTable(3, 3))
B.grid(row=5,column=1, columnspan=2)
root.mainloop()
Related
I am working on a project that solves sudoku puzzles. To gather the inputs I am using a GUI called "Tkinter" with 81 separate input(entry) boxes. I also have a submit button. When I press submit I would like to create a series of objects that contain atribues like cell value, row, and column. the code below does this, but I would have to copy and paste this code 81 times only adjusting the variable names and position by one each time(within the submit function). Is there any way to create a loop that could iterate these lines of code 81 times while altering the number part of the variable names?
class Cell:
def __init__(self,number,location):
self.number = number
self.row = (location // 9) + 1
self.column = (location % 9) + 1
def submit():
cell1 = Cell(c1.get(),0)
cell2 = Cell(c2.get(),1)
cell3 = Cell(c3.get(),2)
...
*the .get() method is how I am retrieving the numbers from the input boxes(called c1,c2,c3...) once the button is pressed.
**location is just a number(0-80) that I use to find the row and column info.
The simplest I could think of was to use nested for loops to create the widgets and grid them (btw row and column start at 0) and append to a list, from where they can be later referenced. So when you press the button, it goes over each of the Entrys in that list and calls their get method (and prints the value):
import tkinter as tk
def submit():
for e in entry_list:
print(e.get())
root = tk.Tk()
entry_list = []
for col in range(9):
for row in range(9):
entry = tk.Entry(root, width=2, font=('Calibri', 20))
entry.grid(row=row, column=col, sticky='news')
entry_list.append(entry)
btn = tk.Button(root, text='Submit', command=submit)
btn.grid(row=9, column=0, columnspan=9)
root.mainloop()
Hi i want to add a new entry box when clicking a button. How can i do that ?
What've done is im able to "for loop" a group of entry boxes. But i want the entry boxes to appear one by one by clicking a button.
What've done
My code:
import tkinter as tk
from tkinter import *
root = Tk()
root.title("Entry box")
root.geometry("700x500")
my_entries = []
def something():
entry_list = ''
for entries in my_entries:
entry_list = entry_list + str(entries.get()) + '\n'
my_label.config(text=entry_list)
print(my_entries[0].get())
for x in range(5):
my_entry = Entry(root)
my_entry.grid(row=0, column=x, pady=20, padx=5)
my_entries.append(my_entry)
my_button = Button(root, text="Click Me!", command=something)
my_button.grid(row=1, column=0, pady=20)
There is not much of work here, create a variable to keep track of the columns you are inserting the widget into and then just insert it based on that number, like:
# Rest of your code..
my_entries = []
count = 0 # To keep track of inserted entries
def add():
global count
MAX_NUM = 4 # Maximum number of entries
if count <= MAX_NUM:
my_entries.append(Entry(root)) # Create and append to list
my_entries[-1].grid(row=0,column=count,padx=5) # Place the just created widget
count += 1 # Increase the count by 1
Button(root, text='Add', command=add).grid(row=1, column=1, padx=10) # A button to call the function
# Rest of your code..
Though I am not sure about your other function and its functionality, but it should work after you create entries and then click that button.
An array of Entries was created using the following code
from tkinter import *
root = Tk()
height = 5
width = 5
delta=0
for i in range(height): #Rows
for j in range(width): #Columns
b = Entry(root, text="",width=8)
b.grid(row=i, column=j)
mainloop()
How do I access each Entry to update its value ( using StringVar - for example ) ?
You could create a list of lists for your Entry widgets.
from tkinter import *
root = Tk()
height = 5
width = 5
delta=0
entries = []
for i in range(height): #Rows
newrow = []
for j in range(width): #Columns
b = Entry(root, text="",width=8)
b.grid(row=i, column=j)
newrow.append(b)
entries.append(newrow)
mainloop()
You could then address individual entries as e.g. entries[2][4].
Edit: To edit the text of entry widget e, first use e.delete(0, END) to clear it, and then use e.insert(0, "new text") to insert new text.
Edit2: Alternatively, you could store the StringVars in a list of lists instead of the widgets...
You need to first declare the StringVar variable:
myvar = StringVar()
Then in your loop whenever you want to check to content of the variable use the get() method.
x = myvar.get()
Now x will hold the value. You can also perform a bool test with if
if myvar.get():
print(myvar.get())
In that if statement the program checks if there is data in the var. If not it will move on
Looking at it again you should also declare the StringVar() in your button. Like so:
b = Button(text='clickme', texvariable=myvar)
Look Here for more info
I have constructed a GUI with tkinter. There are two buttons, one to load an excel sheet and parse all cells and print their value. Also, I have a series of empty textboxes with headers. What I am trying to achieve is to load the parsed excel cells each onto a variable, then fill the empty textboxes with the cell value (i.e. the variable in question). Any pointers would be greatly appreciated. Here's my code so far:
#!/usr/bin/python3
from tkinter import filedialog
from tkinter import *
import openpyxl
from openpyxl import load_workbook
#Define Window Geometry
main = Tk()
main.geometry("1024x768")
main.title("Window Title")
#Define Empty Cells to be Filled in by Excel File & Calculation
def OpenDataInputSpreadsheetCallBack():
main.iconify()
file_path = filedialog.askopenfilename(initialdir = "file_path_goes_here",title = "Choose Input Spreadsheet",filetypes = (("Excel 2010 files","*.xlsx"),("Excel 2003 Files","*.xls")))
wb = load_workbook(filename = file_path, read_only=True)
ws = wb.active
for row in ws.iter_rows():
for cell in row:
if (cell.value==None):
pass
else:
print(cell.value)
#
#
#Function to display empty rows and columns
#
height = 5
width = 6
for x in range(1,height+1): #Rows
for y in range(width): #Columns
b = Entry(main, text='')
b.grid(row=x, column=y)
#
# Define Buttons
b1 = Button(main, text = "Open Data Input Spreadsheet", command = OpenDataInputSpreadsheetCallBack)
b1.place(x = 1,y = 120)
b2 = Button(main, text='Quit', command=main.destroy)
b2.place(x = 1,y = 150)
##
##
### Initialize Column Headers
Label(main, text="Header1").grid(row=0, column=0, sticky=W)
Label(main, text="Header2").grid(row=0, column=1, sticky=W)
Label(main, text="Header3").grid(row=0, column=2, sticky=W)
Label(main, text="Header4").grid(row=0, column=3, sticky=W)
Label(main, text="Header5").grid(row=0, column=4, sticky=W)
Label(main, text="Header6").grid(row=0, column=5, sticky=W)
###
# Define a function to close the window.
def quit(event=None):
main.destroy()
# Cause pressing <Esc> to close the window.
main.bind('<Escape>', quit)
#
#
main.mainloop()
Question: What I am trying to achieve is to load the parsed excel cells each onto a variable, then fill the empty textboxes with the cell value
You don't have to use a variable, you can pass the cell values direct to the textbox.
For instance:
class Textbox(object):
text = None
series_of_textboxes = [Textbox(),Textbox(),Textbox(),Textbox()]
# start reading from row 2
for i, row in enumerate( ws.iter_rows(min_row=2) ):
series_of_textboxes[i].text = ' '.join(cell.value for cell in row)
print( series_of_textboxes[0].text )
Output:
Bundesliga 27.08.16 Hamburg Ingolstadt
Tested with Python:3.4.2 - openpyxl:2.4.1
Come back and Flag your Question as answered if this is working for you or comment why not.
I have a small script that generates a random number of entry widgets. Each one needs a StringVar() so I can assign text to the widget. How can I create these as part of the loop since I won't know ahead of time as to how many there will be?
from Tkinter import *
import random
root = Tk()
a = StringVar()
height = random.randrange(0,5)
width = 1
for i in range(height): #Rows
value + i = StringVar()
for j in range(width): #Columns
b = Entry(root, text="", width=100, textvariable=value+i)
b.grid(row=i, column=j)
mainloop()
The direct answer to your question is to use a list or dictionary to store each instance of StringVar.
For example:
vars = []
for i in range(height):
var = StringVar()
vars.append(var)
b = Entry(..., textvariable=var)
However, you don't need to use StringVar with entry widgets. StringVar is good if you want two widgets to share the same variable, or if you're doing traces on the variable, but otherwise they add overhead with no real benefit.
entries = []
for i in range(height):
entry = Entry(root, width=100)
entries.append(entry)
You can insert or delete data with the methods insert and delete, and get the value with get:
for i in range(height):
value = entries[i].get()
print "value of entry %s is %s" % (i, value)
Just store them in a list.
vars = []
for i in range(height): #Rows
for j in range(width): #Columns
vars.append(StringVar())
b = Entry(root, text="", width=100, textvariable=vars[-1])
b.grid(row=i, column=j)
That said, you should probably be storing the Entry widgets themselves in a list, or a 2D list as shown:
entries = []
for i in range(height): #Rows
entries.append([])
for j in range(width): #Columns
entries[i].append(Entry(root, text="", width=100))
entries[i][j].grid(row=i, column=j)
You can then assign text to each widget with the insert() method:
entries[0][3].insert(0, 'hello')