2014-12-19 155 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