首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Python的Tksheet小部件中设置单个列标题/以相同的方式回滚更改

在Python的Tksheet小部件中设置单个列标题/以相同的方式回滚更改
EN

Stack Overflow用户
提问于 2021-10-23 08:22:10
回答 1查看 539关注 0票数 0

我正在为一个接受表格数据的模拟程序编写一个UI。我所需要的基本功能是用户能够通过直接键入或粘贴数据(通常是从excel表)在单元格中输入/更改数据。程序检查此数据,并在运行模拟之前接受或拒绝该数据。我还想让用户为表输入自己的列标题。

Tksheet是一个令人敬畏的Tkinter插件,它为输入框架提供了一个像excel一样的“感觉”,但是它的文档仍然有很多需要改进的地方。(例如:每个事件生成一个不同的事件-信息数组-参见下面两个事件处理例程的代码-但它没有指定这些参数是什么。这是留给用户发现使用试用和错误,或试图读取源代码--这也没有记录)。

我有两个具体问题:

  1. 有没有办法不提交或回滚对表的更改?如果数据测试失败,如何防止将潜在有害的用户输入输入到表中?显然,我可以(而且确实)添加一个begin_***事件,在该事件中,我可以保留原始值的副本,如果end_***事件的数据测试失败,则重新设置表值,但这是浪费和不雅的。我觉得set_data_ref_on_destroy属性与这种功能有关,但是文档没有解释这个参数是什么,也没有解释如何使用它。

  1. 如何一次更改单个列标题?.headers属性似乎只适用于从列0开始的完整的标题列表(如果我运行self.sheet.headers( single_value,index = i),它再次忽略索引参数并在列0中插入single_value),我可以在init中将列标题设置为某种非默认的内容,并保留所有标头的运行列表,以便在每次更改时重置所有标头,但这是浪费和不雅的。

在下面的代码示例中,我设置了一个简单的表,并绑定了三个用户生成的事件:一个用于向单元格键入值,一个用于粘贴值块,另一个用于向列标题的右键菜单中添加一个选项,以允许用户向列键入名称。

代码语言:javascript
运行
复制
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)  # This configures the window's escalators
        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=[[]])  # set up empty table
        self.sheet.grid(row=0, column=0, sticky="nswe")
        self.sheet.enable_bindings(bindings=  # enable table behavior
                                   ("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",  # rc = right click
                                    "copy",
                                    "cut",
                                    "paste",
                                    "delete",
                                    "undo",
                                    "edit_cell"
                                    ))
        # Note that options that change the structure/size of the table (e.g. insert/delete col/row) are disabled

        # make sure that pasting data won't change table size
        self.sheet.set_options(expand_sheet_if_paste_too_big=False)
        # bind specific events to my own functions
        self.sheet.extra_bindings("end_edit_cell", func=self.cell_edited)
        self.sheet.extra_bindings("end_paste", func=self.cells_pasted)
        label = "Change column name"  # Add option to the right-click menu for column headers
        self.sheet.popup_menu_add_command(label, self.column_header_change, table_menu=False, index_menu=False, header_menu=True)

    # Event functions
    def cell_edited(self, info_tuple):
        r, c, key_pressed, updated_value = info_tuple  # break the info about the event to individual variables
        if check_input(updated_value):
            pass  # go do stuff with the updated table
        else:
            msg.showwarning("Input Error", "'" + updated_value + "' is not a legal value")
            pass  # what do I do here? How do I make tksheet *not* insert the change to the table?

    def cells_pasted(self, info_tuple):
        key_pressed, rc_tuple, updated_array = info_tuple  # break the info about the event to individual variables
        r, c = rc_tuple  # row & column where paste begins
        if check_input(updated_array):
            pass  # go do stuff with the updated table
        else:
            msg.showwarning("Input Error", "pasted array contains illegal values")
            pass  # what do I do here? How do I make tksheet *not* insert the change to the table?

    def column_header_change(self):
        r, c = self.sheet.get_currently_selected()
        col_name = sd.askstring("User Input", "Enter column name:")
        if col_name is not None and col_name != "":  # if user cancelled (or didn't enter anything), do nothing
            self.sheet.headers([col_name], index=c)  # This does not work - it always changes the 1st col
            self.sheet.redraw()


# from here down is test code
def check_input(value):  # instead of actual data testing we let the tester choose a pass/fail response
    return msg.askyesno("Instead of input checking","Did input pass entry checks?")


test = demo()
lst = ["hello", "world"]
test.sheet.insert_column(values=lst)
lst = [0, "hello", "yourself"]
test.sheet.insert_column(values=lst)
test.mainloop()
EN

回答 1

Stack Overflow用户

发布于 2022-03-30 00:20:18

我意识到最初的帖子现在已经有5个月的历史了,我是一个相对的n00b,但我希望这会有所帮助。

给定已填充标头["A"."B"."C"]的tksheet实例“sheet”,下面的工作可以将头"B"更改为"NEW"

代码语言:javascript
运行
复制
sheet.headers()[1]="NEW"

希望这能有所帮助。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69686342

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档