我正在构建我的第一个python tkinter gui,其中一部分是一个可编辑的表。该代码基于这篇文章,其中Bryan Oakley的答案是一个很棒的资源:SQL Query results in tkinter
我还发现这个引用对基于SQL的可编辑guis很有用: https://www.ssucet.org/old/pluginfile.php/778/mod_resource/content/2/Python%20Database%20Lab.pdf
在Bryan Oakely的解决方案中,我认为数据是元组的元组。例如,
data = (
(45417, "rodringof", "CSP L2 Review", 0.000394, "2014-12-19
10:08:12", "2014-12-19 10:08:12"),...
我从SQL连接中获取的数据是元组列表。我将它转换为元组元组 - 它解决了我收到的错误并使GUI能够填充数据。我很感激评论描述为tkinter重构SQL数据的更好方法,相当于我的' big_tuple'在代码中创建?(注意,这是读取Access .mdb文件,这是我可以做的唯一类型的SQL连接 - 也许这是我必须克服的特定问题)。完整代码发布在问题的最后。
更重要的是,这是一个真正的问题:
图片显示片段制作' big_tuple' GUI和控制台输出之间的差异
你可以在这里看到数据包含在' for'中使用strftime重新格式化的datetime对象。循环,分配元组的元组' data1'。但是,根据GUI,“数据1”中的浮点数。没有在这个循环中重新格式化。如果' big_tuple'打印到控制台,它显示浮动已成功重新格式化,但在GUI中,它们保持未格式化。 请告诉我为什么浮动片在打印输出中显示格式但在GIU中没有?以下是完整代码:
#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()
答案 0 :(得分:2)
您看到差异的原因是print
将打印字符串值prettyfloat
,但您将实际的浮点数传递给标签小部件。此浮点值将传递给tkinter所基于的底层tcl解释器,并且正是此tcl解释器正在转换浮点值以进行显示。 tcl解释器不知道如何调用__repr__
函数。
如果您使用repr
将值显式转换为字符串,则可以看到漂亮的版本,因为您定义了__repr__
方法:
self.widgets[rent_id] = {
...
"Current_Line_Rental": tk.Label(..., text=repr(Current_Line_Rental)),
...
}
或者,您可以定义__str__
,然后使用str(Current_Line_Rental)
。