【问题标题】:SQL Query results in tkintertkinter 中的 SQL 查询结果
【发布时间】:2014-12-19 01:22:45
【问题描述】:

我有一个 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() 以一种非常混乱的方式完成了这项工作,并以编程方式为每个字段创建变量。它变得非常漫长和令人困惑,我真的认为必须有更好、更简单的方法来做到这一点。

感谢任何帮助。谢谢!!

快速更新:因为这被搁置了,我将添加与我正在寻找的东西相似的图像:

当我将条目标签中的值上传回数据库时,它们必须替换右侧列中的值。

当我说我以一种凌乱的方式这样做时,是因为我这样做了(我能想到的唯一方式):

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

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

【问题讨论】:

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

标签: python python-3.x tkinter


【解决方案1】:

您绝对不想使用 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()

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

【讨论】:

  • 这实际上非常棒,我想现在从不同的角度理解这一点。还有一个问题,如果结果大于窗口,我该如何放置滚动条?那可能吗?谢谢!!!!
  • 如果应该将其保存为另一个问题,请告诉我:)
  • @rodrigocf:这是一个单独的问题,之前已经回答过。见stackoverflow.com/a/3092341/7432
  • 当然,没问题,我会尽快奖励赏金,它告诉我我必须等待......
猜你喜欢
  • 1970-01-01
  • 2023-03-10
  • 2015-09-04
  • 2022-06-21
  • 2012-12-30
  • 1970-01-01
  • 1970-01-01
  • 2023-03-18
  • 2013-09-26
相关资源
最近更新 更多