【问题标题】:Tkinter GUI – How to remove a row of Entry widgets, using a ButtonTkinter GUI – 如何使用按钮删除一行条目小部件
【发布时间】:2017-10-13 11:06:34
【问题描述】:

我正在构建一个表格,使用 ttk.Entry 和 `ttk.Combobox'(行和列 - 行数可能不同)。

用户应该能够使用放置在 GUI 上的“删除按钮”删除该表的整行。

  1. 要删除的行可以放在任何位置(第一个、最后一个、中间的任何位置)。
  2. 无需在每行的末尾/开头添加“复选框”小部件来标记所需的行。

试过了:

a) 使用focus_get() 确定Entry 的行号,然后删除整行小部件。 但是,当按下“Delete Button”时,focus_get() 会从 Entry 变为 Button,并且“Delete Button”被删除了。

b) 我没有尝试过,但是有一种方法使用类绑定到整个,但它似乎并不优雅。

知道什么是“正确”的方法吗?

编辑 1:添加 的图片。选择任何条目,将删除整行小部件

【问题讨论】:

  • 将最后选择的行保存在变量中。按下按钮时将其删除。哪个部分难?
  • @stark 到 bind 每个小部件?希望有更好的方法
  • 在 validate 方法中设置变量。
  • 请告诉我们minimal reproducible example。我假设您正在使用 ttk 按钮,但您没有明确说明。
  • 您可以在自己的框架中创建每一行,然后在可用于destroy() 框架的行旁边有一个x 按钮。

标签: python user-interface tkinter


【解决方案1】:

您没有在问题中说明,但我假设您使用 ttk 作为按钮。当您单击 ttk 按钮小部件时,它会获得焦点,这既不同于 tkinter,也不同于按钮的一般工作方式。在我看来,这是 ttk 按钮中的一个错误,但我在几年前提出了这个问题,开发人员决定保留这种行为。

快速解决方法是将按钮的 takefocus 选项设置为 False。不幸的是,这会破坏使用键盘遍历您的 gui 的能力(例如:按 tab 将焦点从小部件移动到小部件)。这两个问题都可以通过一些自定义绑定来解决。

这是一个程序,说明了将takefocus 设置为FalseTrue 之间的区别

import tkinter as tk
from tkinter import ttk

root = tk.Tk()

def click():
    label.configure(text="Widget with focus: %s" % root.focus_get())

e1 = ttk.Entry(root, name="e1")
e2 = ttk.Entry(root, name="e2")
label = ttk.Label(root)

b1 = ttk.Button(root, text="Steal focus", command=click, name="b1", takefocus=True)
b2 = ttk.Button(root, text="Don't Steal focus", command=click, name="b2", takefocus=False)

e1.pack(fill="x")
e2.pack(fill="x")
label.pack(side="top", fill="both", expand=True)
b1.pack(side="left")
b2.pack(side="left")

root.mainloop()

【讨论】:

  • Bryan - 很好的例子,我一直在寻找“优雅”。
  • 由于我没有为每个条目命名 - 知道如何将这个数字关联起来:.1976965872.1976966128.1976965936.1982974256.1976966224.1976966352.1977008240 - 到条目行?
  • @Guy.D:名字无关紧要。只是为了让代码可以轻松地打印出有用的东西。该小部件是root.focus_get() 的结果。
  • 我知道-仍然,我需要以某种方式获取行号才能删除该行上的所有小部件
  • @Guy.D:如果您使用的是grid,您可以调用root.focus_get().grid_info(),它会返回所有网格参数的字典。或者,将所有条目小部件保存在列表列表中,然后只需搜索每个子列表以查看哪个具有条目小部件。有很多方法可以解决这个问题。
【解决方案2】:

正如@Bryan Oakley 所建议的,这里是更新代码的相关部分——作为我问题的答案。

按钮的焦点设置为False

del_row_button = ttk.Button(buttons_frame, width=10, text="Delete Row", takefocus=False, command=self.del_row)
        del_row_button.grid(row=1, column=1, pady=5, padx= 5)

self.del_row_button 回调更新以通过使用grid_info().get('row')-1 获取小部件的行号来删除self.datafile 中的确切行

def del_row(self):

        #delete data from list
        del self.datafile[self.class_frame.focus_get().grid_info().get('row') -1]

        #save data
        self.save_data()

        #destroy and rebuild rows with updated data
        self.rows_frame.destroy()
        self.rebuild_table()

        print("row deleted")

【讨论】:

    猜你喜欢
    • 2022-06-28
    • 1970-01-01
    • 2018-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-18
    • 2013-10-22
    • 1970-01-01
    相关资源
    最近更新 更多