tkinter 中的 SQL 查询结果 [英] SQL Query results in tkinter
问题描述
我有一个 tkinter 界面,我需要在其中显示一些查询结果,并且我需要用户能够修改列并提交结果.目前为了提取查询,我正在做这样的事情:
I have a tkinter interface where I need to display some query results and I need for the user to be able to modify a column and submit the results. Currently to pull the queries I'm doing something like this:
conn = connection_info_goes_here
cur = conn.cursor()
cur.execute(query_goes_here)
这是我的查询:
SELECT id, reviewer, task, num_seconds, start_time, end_time
FROM hours
WHERE DATE(start_time) = '2014-12-18'
AND reviewer = 'john'
用户需要修改的字段是num_seconds
(只是数字).我的问题是,如何使查询结果显示在网格中,以及如何使用按钮修改其中一个字段以提交更改?
The field that the user needs to modify is num_seconds
(just numbers). My question is, how do I make the query results show in the grid and how do I make one of the fields modifiable with a button to submit the changes?
附加信息:我已经使用 exec()
以一种非常混乱的方式完成了此操作,并以编程方式为每个字段创建了变量.它变得很长而且很混乱,我真的认为必须有更好、更简单的方法来做到这一点.
Additional info: I already did this in a very messy way using exec()
and programmatically creating variables for each field. It became very long and confusing and I really think there has to be a better and easier way to do this.
感谢任何帮助.谢谢!!
Any help is appreciated. Thanks!!
快速更新:由于这被搁置了,我将添加与我正在寻找的内容类似的图像:
Quick Update: since this was put on hold, i'll add an image of something similar to what I'm looking for:
当我将它们上传回数据库时,条目标签中的值必须替换右侧列中的值.
The values in the entry label must replace the values in the column to the right when I upload them back to the DB.
当我说我以一种凌乱的方式这样做时,是因为我这样做了(我能想到的唯一方法):
When I say I did this in a messy way, is because I did (the only way I could think of):
def cor_window():
corrections = Tk()
corrections.title("Corrections")
corrections_frame = ttk.Frame(corrections)
cor_values = []
count=0
cor_count=0
for x in results:
count2=0
for y in results[count]:
if count2 == 3:
exec('int' + str(cor_count) + '=tkinter.StringVar')
exec('int' + str(cor_count) + '_entry = ttk.Entry(corrections, width=20, textvariable=int' + str(cor_count) + ')')
exec('int' + str(cor_count) + '_entry.grid(column=count2, row=count+2)')
cor_count = cor_count+1
cor_values.append('int' + str(cor_count) + '_entry')
ttk.Label(corrections, width=20, anchor=CENTER, relief=SUNKEN, borderwidth=1, text= results[count][count2]).grid(column=count2+1, row=count+2)
elif count2 > 3:
ttk.Label(corrections, width=20, anchor=CENTER, relief=SUNKEN, borderwidth=1, text= results[count][count2]).grid(column=count2+1, row=count+2)
else:
ttk.Label(corrections, width=20, anchor=CENTER, relief=SUNKEN, borderwidth=1, text= results[count][count2]).grid(column=count2, row=count+2)
count2=count2+1
count=count+1
ttk.Button(corrections, text="Done!", command=upload_cor).grid(column=0, row=1)
其中 results
是包含查询结果的列表,upload_cor
是将更改上传到数据库的函数.由于我使用了exec
,即使用户修改了输入框,我也无法使用.get()
来获取用户输入的内容.当我尝试使用 .get()
时,即使在输入框中输入了某些内容,我也只会得到 None
.
Where results
is the list that contains the query results and upload_cor
is the function the will upload the changes to the DB. Since I used exec
, even if the user modifies the entry box, I can't use .get()
to get what the user typed. When I try use .get()
, I only get None
even if something was typed in the entry box.
我只需要一种不同的方法来做到这一点,同样,欢迎提出任何想法.
I just need a different method to do this, again, any ideas are welcome.
推荐答案
您绝对不想使用 exec,也不需要使用 textvariable
选项.这两者只会增加混乱.只需将您的小部件存储为字典,直接从入口小部件获取数据,这一切都变得非常易于管理.
You definitely don't want to use exec, and you don't need to use the textvariable
option. Both of those just add to the confusion. Simply store your widgets as a dictionary, get the data straight from the entry widget, and it all becomes very easy to manage.
这是一个工作示例:
import tkinter as tk
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)
data = (
(45417, "rodringof", "CSP L2 Review", 0.000394, "2014-12-19 10:08:12", "2014-12-19 10:08:12"),
(45418, "rodringof", "CSP L2 Review", 0.000394, "2014-12-19 10:08:12", "2014-12-19 10:08:12"),
(45419, "rodringof", "CSP L2 Review", 0.000394, "2014-12-19 10:08:12", "2014-12-19 10:08:12"),
(45420, "rodringof", "CSP L2 Review", 0.000394, "2014-12-19 10:08:12", "2014-12-19 10:08:12"),
(45421, "rodringof", "CSP L2 Review", 0.000394, "2014-12-19 10:08:12", "2014-12-19 10:08:12"),
(45422, "rodringof", "CSP L2 Review", 0.000394, "2014-12-19 10:08:12", "2014-12-19 10:08:12"),
(45423, "rodringof", "CSP L2 Review", 0.000394, "2014-12-19 10:08:12", "2014-12-19 10:08:12"),
)
self.widgets = {}
row = 0
for rowid, reviewer, task, num_seconds, start_time, end_time in (data):
row += 1
self.widgets[rowid] = {
"rowid": tk.Label(table, text=rowid),
"reviewer": tk.Label(table, text=reviewer),
"task": tk.Label(table, text=task),
"num_seconds_correction": tk.Entry(table),
"num_seconds": tk.Label(table, text=num_seconds),
"start_time": tk.Label(table, text=start_time),
"end_time": tk.Label(table, text=start_time)
}
self.widgets[rowid]["rowid"].grid(row=row, column=0, sticky="nsew")
self.widgets[rowid]["reviewer"].grid(row=row, column=1, sticky="nsew")
self.widgets[rowid]["task"].grid(row=row, column=2, sticky="nsew")
self.widgets[rowid]["num_seconds_correction"].grid(row=row, column=3, sticky="nsew")
self.widgets[rowid]["num_seconds"].grid(row=row, column=4, sticky="nsew")
self.widgets[rowid]["start_time"].grid(row=row, column=5, sticky="nsew")
self.widgets[rowid]["end_time"].grid(row=row, column=6, 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):
for rowid in sorted(self.widgets.keys()):
entry_widget = self.widgets[rowid]["num_seconds_correction"]
new_value = entry_widget.get()
print("%s: %s" % (rowid, new_value))
if __name__ == "__main__":
root = tk.Tk()
Example(root).pack(fill="both", expand=True)
root.mainloop()
我实际上会通过使用 add_row
方法创建一个 Table
类来实现这一点,但我不想变得太复杂.无论您是创建一个 Table
类,在一个类中完成所有操作,还是按程序进行操作,基本思想都是相同的 - 创建一个字典来表示您的数据.您也可以使用嵌套列表,但我发现字典更易于使用.它们也是自我记录的,因为您通过符号名称引用事物,而不仅仅是知道第 4 列是开始时间.
I would actually implement this a little differently by creating a Table
class with an add_row
method, but I didn't want to get too complex. The basic idea is the same whether you create a Table
class, do it all in the one class, or do it procedurally - create a dictionary to represent your data. You could use nested lists too, but I find dictionaries to be much easier to use. They are also self-documenting, since you reference things by a symbolic name rather than just knowing that column 4 is the start time.
这篇关于tkinter 中的 SQL 查询结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!