Skip to content

Commit 96313dc

Browse files
committed
add spreadsheet app tkinter tutorial
1 parent e5493fa commit 96313dc

File tree

3 files changed

+128
-0
lines changed

3 files changed

+128
-0
lines changed

Diff for: README.md

+1
Original file line numberDiff line numberDiff line change
@@ -231,5 +231,6 @@ This is a repository of all the tutorials of [The Python Code](https://www.thepy
231231
- [How to Make a Markdown Editor using Tkinter in Python](https://www.thepythoncode.com/article/markdown-editor-with-tkinter-in-python). ([code](gui-programming/markdown-editor))
232232
- [How to Build a GUI Currency Converter using Tkinter in Python](https://www.thepythoncode.com/article/currency-converter-gui-using-tkinter-python). ([code](gui-programming/currency-converter-gui/))
233233
- [How to Detect Gender by Name using Python](https://www.thepythoncode.com/article/gender-predictor-gui-app-tkinter-genderize-api-python). ([code](gui-programming/genderize-app))
234+
- [How to Build a Spreadsheet App with Tkinter in Python](https://www.thepythoncode.com/article/spreadsheet-app-using-tkinter-in-python). ([code](gui-programming/spreadsheet-app))
234235

235236
For any feedback, please consider pulling requests.

Diff for: gui-programming/spreadsheet-app/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# [How to Build a Spreadsheet App with Tkinter in Python](https://www.thepythoncode.com/article/spreadsheet-app-using-tkinter-in-python)

Diff for: gui-programming/spreadsheet-app/spreadsheet_app.py

+126
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# Imports
2+
from tkinter import *
3+
import string
4+
import sys
5+
import ctypes
6+
7+
# Increase Dots Per inch so it looks sharper
8+
ctypes.windll.shcore.SetProcessDpiAwareness(True)
9+
10+
# Define X and Y Axis Lists
11+
xAxis = string.ascii_lowercase[0:7]
12+
yAxis = range(0, 12)
13+
14+
# Cells will hold the strings vars and the lables
15+
cells = {}
16+
17+
# Open the content of the given file
18+
# if one was provided and save it as a two
19+
# dimensional list.
20+
CsvContent = ''
21+
if len(sys.argv) > 1:
22+
with open(sys.argv[1], 'r') as f:
23+
CsvContent = f.read().split('\n')
24+
for i, layer in enumerate(CsvContent):
25+
CsvContent[i] = layer.split(',')
26+
27+
# Make a new Top Level Element (Window)
28+
root = Tk()
29+
30+
# Set the the title to also mention the given file name
31+
# if there is one
32+
title = "Spreadsheet App" if CsvContent == '' else f"Spreadsheet App - {sys.argv[1]}"
33+
root.title(title)
34+
35+
# Evaluating a cell
36+
def evaluateCell(cellId, *i):
37+
38+
# Get the content from the string var
39+
# and make it lowercase
40+
content = cells[cellId][0].get()
41+
content = content.lower()
42+
43+
# get the reference to the label
44+
label = cells[cellId][1]
45+
46+
# if the cell starts with a = it is evaluated
47+
if content.startswith('='):
48+
49+
# Loop through all cells ...
50+
for cell in cells:
51+
52+
# ... and see if their name appears in this cell
53+
if cell in content.lower():
54+
55+
# if it is then replace the name occurences
56+
# with the evaluated content from there.
57+
content = content.replace(cell, str(evaluateCell(cell)))
58+
59+
# Get the content without the = and try to evaluate it
60+
content = content[1:]
61+
try:
62+
content = eval(content)
63+
except:
64+
content = 'NAN'
65+
label['text'] = content
66+
return content
67+
68+
# If not, the label just shows the content
69+
else:
70+
label['text'] = content
71+
return content
72+
73+
# Call the eval function for every cell every ten milliseconds.
74+
def updateAllCells():
75+
76+
# Call it again
77+
root.after(10, updateAllCells)
78+
79+
# Loop through all cells
80+
for cell in cells:
81+
evaluateCell(cell)
82+
83+
84+
# Display the Y axis lables
85+
for y in yAxis:
86+
label = Label(root, text = y, width=5, background='white')
87+
label.grid(row=y + 1, column=0)
88+
89+
# Display the X axis lables with enumerate
90+
for i, x in enumerate(xAxis):
91+
label = Label(root, text = x, width=35, background='white')
92+
label.grid(row=0, column=i + 1, sticky='n')
93+
94+
95+
# Display the Cells, by using a nested loop
96+
for y in yAxis:
97+
for xcoor, x in enumerate(xAxis):
98+
99+
# Generate a Unique ID for the cell with the coordinates
100+
id = f'{x}{y}'
101+
102+
# Make String Var associated with the Cell
103+
var = StringVar(root, '', id)
104+
105+
# Make Entry and label, offset each axis by one because of the lables
106+
e = Entry(root, textvariable=var, width=30)
107+
e.grid(row=y + 1, column=xcoor + 1)
108+
109+
label = Label(root, text = '', width=5)
110+
label.grid(row=y + 1, column=xcoor + 1, sticky='e')
111+
112+
# Save the string var and a reference to the lables in the dictionary
113+
cells[id] = [var, label]
114+
115+
# Insert CSV content if it possible
116+
if CsvContent != '':
117+
try:
118+
var.set(CsvContent[y][xcoor])
119+
except:
120+
pass
121+
122+
# Start the updating Process
123+
updateAllCells()
124+
125+
# Run the Mainloop
126+
root.mainloop()

0 commit comments

Comments
 (0)