2014-12-19 117 views
5

我有一个tkinter接口,我需要显示一些查询结果,我需要用户能够修改列并提交结果。目前,拉我做这样的事情的疑问:SQL查询结果tkinter

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(只是数字)。我的问题是,如何使查询结果显示在网格中,以及如何使用按钮修改某个字段以提交更改?

附加信息:我已经以非常混乱的方式使用exec()并以编程方式为每个字段创建变量。它变得非常漫长和令人困惑,我真的认为必须有更好更简单的方法来做到这一点。

任何帮助表示赞赏。谢谢!!

快速更新:,因为这被搁置,我会的类似图像添加到我正在寻找:

enter image description here

在输入标签的值必须更换当我将它们上传到数据库时,该列中的值位于右侧。

当我说我在一个混乱的方式做到这一点,是因为我做了(我能想到的唯一途径):

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

我只是需要一个不同的方法来做到这一点,再次,任何想法都是值得欢迎的。

+0

num_seconds将使用一个条目(或一个条目ID列表),其余的将是标签。您还必须将行号链接到记录,并将每个条目与原始值进行比较以查看哪些行已更改,但是如果“id”是唯一的,那么它应该很简单。输入部件信息http://effbot.org/tkinterbook/entry.htm – 2014-12-19 01:31:53

回答

7

您绝对不想使用exec,也不需要使用textvariable选项。这些都增加了混乱。只需将您的小部件作为字典存储,直接从入口小部件获取数据,并且这一切都变得非常容易管理。

这里有一个工作示例:

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() 

我真的实现这个有点不同通过创建Table类的add_row的方法,但我不想弄得太复杂。无论您创建Table类,在一个类中完成所有操作,还是在程序上执行它,基本思路都是一样的 - 创建一个字典来表示您的数据。你也可以使用嵌套列表,但是我发现字典更容易使用。它们也是自我记录的,因为你用符号名称来引用事物,而不是仅仅知道第4列是开始时间。

+0

这实际上非常棒,我想从不同的角度理解这一点。还有一个问题,如果结果大于窗口,我该如何放置滚动条?那可能吗?谢谢!!!! – rodrigocf 2014-12-22 22:36:54

+0

如果应该只保存另一个问题,请让我知道:) – rodrigocf 2014-12-22 22:37:33

+0

@rodrigocf:这是一个单独的问题,它已被回答。见http://stackoverflow.com/a/3092341/7432 – 2014-12-22 22:53:11