Python Tkinter Tksheet组件单列表头设置与表格数据变更回退问题咨询
Tksheet 两个常见问题解决方案
问题1:校验失败时阻止无效修改写入表格
tksheet的end_edit_cell、end_paste这类修改类事件的回调函数,只要返回False,组件会自动回滚到修改前的状态,无需手动保存原始值再重置。你猜测的set_data_ref_on_destroy属性和该功能无关,它是控制组件销毁时是否保留数据引用的参数。
修改后的事件处理逻辑示例:
def cell_edited(self, info_tuple): r, c, key_pressed, updated_value = info_tuple if check_input(updated_value): # 校验通过后的业务逻辑 pass else: msg.showwarning("输入错误", f"'{updated_value}' 不是合法值") # 返回False即可阻止修改生效 return False def cells_pasted(self, info_tuple): key_pressed, rc_tuple, updated_array = info_tuple r, c = rc_tuple if check_input(updated_array): # 校验通过后的业务逻辑 pass else: msg.showwarning("输入错误", "粘贴的内容包含非法值") # 返回False即可撤销整个粘贴操作 return False
问题2:单独修改指定列的表头
不要用headers()方法修改单列,直接修改组件内部存储表头的列表对应下标值,再调用重绘方法即可,无需自己维护全量表头副本:
def column_header_change(self): r, c = self.sheet.get_currently_selected() col_name = sd.askstring("用户输入", "请输入列名:") if col_name is not None and col_name.strip() != "": # 直接修改对应下标的表头值 self.sheet.headers[c] = col_name # 仅重绘画表头区域,性能更好 self.sheet.redraw_header()
修改后可直接运行的完整代码
from tksheet import Sheet import tkinter as tk import tkinter.messagebox as msg import tkinter.simpledialog as sd class demo(tk.Tk): def __init__(self): tk.Tk.__init__(self) self.grid_columnconfigure(0, weight=1) self.grid_rowconfigure(0, weight=1) self.frame = tk.Frame(self) self.frame.grid_columnconfigure(0, weight=1) self.frame.grid_rowconfigure(0, weight=1) self.frame.grid(row=0, column=0, sticky="nswe") self.sheet = Sheet(self.frame, data=[[]]) self.sheet.grid(row=0, column=0, sticky="nswe") self.sheet.enable_bindings(bindings= ("single_select", "select_all", "column_select", "row_select", "drag_select", "arrowkeys", "column_width_resize", "double_click_column_resize", "row_height_resize", "double_click_row_resize", "right_click_popup_menu", "rc_select", "copy", "cut", "paste", "delete", "undo", "edit_cell" )) self.sheet.set_options(expand_sheet_if_paste_too_big=False) self.sheet.extra_bindings("end_edit_cell", func=self.cell_edited) self.sheet.extra_bindings("end_paste", func=self.cells_pasted) label = "修改列名" self.sheet.popup_menu_add_command(label, self.column_header_change, table_menu=False, index_menu=False, header_menu=True) def cell_edited(self, info_tuple): r, c, key_pressed, updated_value = info_tuple if check_input(updated_value): pass else: msg.showwarning("输入错误", f"'{updated_value}' 不是合法值") return False def cells_pasted(self, info_tuple): key_pressed, rc_tuple, updated_array = info_tuple r, c = rc_tuple if check_input(updated_array): pass else: msg.showwarning("输入错误", "粘贴的内容包含非法值") return False def column_header_change(self): r, c = self.sheet.get_currently_selected() col_name = sd.askstring("用户输入", "请输入列名:") if col_name is not None and col_name.strip() != "": self.sheet.headers[c] = col_name self.sheet.redraw_header() def check_input(value): return msg.askyesno("校验模拟","输入是否通过校验?") test = demo() lst = ["hello", "world"] test.sheet.insert_column(values=lst) lst = [0, "hello", "yourself"] test.sheet.insert_column(values=lst) test.mainloop()
内容的提问来源于stack exchange,提问作者Ilan Sharon
相关产品推荐
相关产品推荐

