I'm building my first python tkinter gui, part of which is an editable table. The code is based on this post where Bryan Oakley's answer is a fantastic resource: SQL Query results in tkinter
I also found this reference useful for editable guis based on SQL: https://www.ssucet.org/old/pluginfile.php/778/mod_resource/content/2/Python%20Database%20Lab.pdf
In Bryan Oakely's solution, I think the data is a tuple of tuples. For example,
data = (
(45417, "rodringof", "CSP L2 Review", 0.000394, "2014-12-19
10:08:12", "2014-12-19 10:08:12"),...
The data I obtain from my SQL connection is a list of tuples. I converted it to a tuple of tuples - which solved errors I was receiving and enabled the GUI to be populated with the data. I'd be grateful for comments describing a better way to restructure SQL data for tkinter equivalent to my 'big_tuple' creation in the code? (Note, this is reading an Access .mdb file which is the only type of SQL connection I can make - perhaps this is a specific issue I've had to overcome). Full code is posted at the end of the question.
More importantly, here is the real question:
Image shows snippet making 'big_tuple' and discrepancy between GUI and console output
You can see here that the data contained datetime objects which were re-formatted using strftime in the 'for' loop that assigns tuple of tuples 'data1'. However, according to the GUI, the floats in 'data1' were not re-formatted in this loop . If 'big_tuple' is printed to the console it shows floats were successfully re-formatted, but in the GUI they remain un-formatted. Please can you tell me why do the floats appear formatted in the print output but not in the GIU? Here is the full code:
#import tkinter as tk
#import pyodbc
import datetime
# db = pyodbc.connect('DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};\
# UID=admin;UserCommitSync=Yes;Threads=3;SafeTransactions=0;\
# PageTimeout=5;MaxScanRows=8;MaxBufferSize=2048;FIL={MS Access};DriverId=25;\
# DefaultDir=C:\\Tim local ;DBQ=C:\\Tim local\\copy2MobileBases.mdb')
# s= 'SELECT * FROM MASTER1'
# cursor = db.cursor()
# cursor.execute(s)
# data = cursor.fetchall() # our SQL data
data = [(1, 'AAA001', '07770000000', datetime.datetime(2016, 2, 16, 0, 0), datetime.datetime(2018, 2, 15, 0, 0), 10.0, 0.0, 0.0, 0.0),
(2, 'AAA001', '07770000001', datetime.datetime(2016, 2, 26, 0, 0), datetime.datetime(2018, 2, 25, 0, 0), 10.129999999999999, 0.0, 0.0, 0.0),
(3, 'AAA001', '07770000002', datetime.datetime(2016, 3, 8, 0, 0), datetime.datetime(2018, 2, 15, 0, 0), 10.129999999999999, 2.5, 0.0, 0.0),
(4, 'AAA001', '07770000003', datetime.datetime(2016, 4, 8, 0, 0), datetime.datetime(2018, 2, 15, 0, 0), 10.129999999999999, 0.0, 0.0, 0.0)
]
# class to convert the floats to 2dp
class prettyfloat(float):
def __repr__(self):
return "%0.2f" % self
# format to convert the strftime
format = ('%d/%m/%Y')
# MAKE 'big_tuple': solving the list of tuples problem - make a tuple of tuples and format too
x = list(data)
list_of_lists = [list(elem) for elem in x]
big_list = []
for i in list_of_lists:
data1=(str(i[0]),i[1],str(i[2]),(i[3].strftime(format)), (i[4].strftime(format)),
prettyfloat(i[5]), prettyfloat(i[6]), prettyfloat(i[7]), prettyfloat(i[8]))
big_list.append(data1)
big_tuple = tuple(big_list)
print(big_tuple)
class Example(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
b = tk.Button(self, text="Done!", command=self.upload_cor)
b.pack()
table = tk.Frame(self)
table.pack(side="top", fill="both", expand=True)
self.widgets = {}
row = 0
for rent_id, Client, CLI, Connected_Date, Contract_End_Date, Current_Line_Rental, V1, V2, V3 in (big_tuple):
row += 1
self.widgets[rent_id] = {
"rent_id": tk.Label(table, text=rent_id),
"Client": tk.Label(table, text=Client),
"CLI": tk.Label(table, text=CLI),
"handset": tk.Entry(table),
"Connected_Date": tk.Label(table, text=Connected_Date),
"Contract_End_Date": tk.Label(table, text=Contract_End_Date),
"Current_Line_Rental": tk.Label(table, text=str(Current_Line_Rental)),
"V1": tk.Label(table, text=V1),
}
self.widgets[rent_id]["rent_id"].grid(row=row, column=0, sticky="nsew")
self.widgets[rent_id]["Client"].grid(row=row, column=1, sticky="nsew")
self.widgets[rent_id]["CLI"].grid(row=row, column=2, sticky="nsew")
self.widgets[rent_id]["handset"].grid(row=row, column=3, sticky="nsew")
self.widgets[rent_id]["Connected_Date"].grid(row=row, column=4, sticky="nsew")
self.widgets[rent_id]["Contract_End_Date"].grid(row=row, column=5, sticky="nsew")
self.widgets[rent_id]["Current_Line_Rental"].grid(row=row, column=6, sticky="nsew")
self.widgets[rent_id]["V1"].grid(row=row, column=7, sticky="nsew")
table.grid_columnconfigure(1, weight=1)
table.grid_columnconfigure(2, weight=1)
# invisible row after last row gets all extra space
table.grid_rowconfigure(row+1, weight=1)
def upload_cor(self):
updates = []
for rent_id in (sorted(self.widgets.keys())):
entry_widget = self.widgets[rent_id]["handset"]
new_value = entry_widget.get()
print("%s: %s" % (rent_id, new_value))
updates.append(new_value)
print (updates)
if __name__ == "__main__":
root = tk.Tk()
Example(root).pack(fill="both", expand=True)
root.mainloop()
# cursor.close()
# db.close()