【发布时间】:2017-04-28 13:43:11
【问题描述】:
我正在构建我的第一个 python tkinter gui,其中一部分是一个可编辑的表。该代码基于这篇文章,其中 Bryan Oakley 的回答是一个极好的资源:@987654321@
我还发现此参考对基于 SQL 的可编辑 gui 很有用: https://www.ssucet.org/old/pluginfile.php/778/mod_resource/content/2/Python%20Database%20Lab.pdf
在 Bryan Oakley 的解决方案中,我认为数据是元组的元组。例如,
data = (
(45417, "rodringof", "CSP L2 Review", 0.000394, "2014-12-19
10:08:12", "2014-12-19 10:08:12"),...
我从我的 SQL 连接获得的数据是一个元组列表。我将它转换为元组的元组 - 这解决了我收到的错误并使 GUI 能够填充数据。我会感谢 cmets 描述 一种更好的方法来为 tkinter 重构 SQL 数据,相当于我在代码中创建的“big_tuple”?(注意,这是读取一个 Access .mdb 文件,它是唯一的我可以建立的 SQL 连接类型 - 也许这是我必须克服的特定问题)。完整代码贴在问题末尾。
更重要的是,这是真正的问题:
图像显示 sn-p 制作“big_tuple”以及 GUI 和控制台输出之间的差异
您可以在此处看到数据包含 datetime 对象,这些对象在分配元组“data1”的“for”循环中使用 strftime 重新格式化。但是,根据 GUI,“data1”中的浮点数在此循环中没有重新格式化。如果 '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()
【问题讨论】:
-
就我的原始答案而言,元组元组、元组列表或列表列表的行为方式完全相同。
-
我们无法运行您的代码,因为我们没有您的数据库。请用一些静态数据重写您的示例。此外,您还有缩进问题。例如,
upload_cor的缩进错误。 -
@BryanOakley,对格式不正确的代码表示歉意。我还用静态数据替换了连接。