You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 12:24:08