树视图表上的 Tkinter 滚动条在调整大小时消失

问题描述 投票:0回答:1

我使用

Treeview
编写了一个表类:

class SimpleDataTable(tk.Frame):
    def __init__(self, parent, colHeadings, colWidths, height):
        tk.Frame.__init__(self, parent)
        self.parent = parent
        self.colHeadings = colHeadings
        self.colWidths = colWidths
        self.height = height
        self.dataDict = {}

        self.tree = None
        self.vsb = None
        self.hsb = None

        self.setupUI()

    def setupUI(self):
        self.tree = ttk.Treeview(self, columns=self.colHeadings, show="headings", height=self.height)
        self.tree.grid(column=0, row=0, sticky='news')

        self.vsb = ttk.Scrollbar(self, orient="vertical", command=self.tree.yview)
        self.tree.configure(yscrollcommand=self.vsb.set)
        self.vsb.grid(column=1, row=0, sticky='ns')

        self.hsb = ttk.Scrollbar(self, orient="horizontal", command=self.tree.xview)
        self.tree.configure(xscrollcommand=self.hsb.set)
        self.hsb.grid(column=0, row=1, sticky='ew')

        for i in range(2):
            self.grid_columnconfigure(i, weight=1)
            self.grid_rowconfigure(i, weight=1)

        self.setupColumns()
        self.populateData()

        # TODO: motion binding callbacks when the user resizes row/column
        #  self.tree.bind("<Configure>", self.onTreeviewConfigure) --> this doesn't work
        # TODO: A way to delete data [and delete from the report]

    def addData(self, key, values: List[Any]):
        self.dataDict[key] = self.processValuesForDisplay(values)
        self.updateData()

    def setupColumns(self):
        for i,col in enumerate(self.colHeadings):
            self.tree.heading(col, text=col, anchor=tk.CENTER)
            self.tree.column(col, width=self.colWidths[i], anchor=tk.CENTER)
    
    def processValuesForDisplay(self, values: List[Any]) -> List[Any]:
        for i,val in enumerate(values):
            if isinstance(val, float):
                values[i] = round(val, 2)
        return values

    def populateData(self):
        for key, values in self.dataDict.items():
            self.tree.insert("", "end", values=tuple(values), text=str(key))

    def updateData(self):
        # When new data is added, the whole table gets re-wriiten. Works with simple cases with a few rows and cols
        # Clear the existing data, self.tree.get_children() returns a tuple which we'd need to unpacks
        self.tree.delete(*self.tree.get_children()) 
        self.populateData()
    
    def selectRowByKey(self, key):
        for item in self.tree.get_children():
            if self.tree.item(item, 'text') == str(key):
                self.tree.selection_set(item)
                self.tree.focus(item)
                self.tree.tag_configure('selected', background='lightblue')  # Change the background color to light blue
                self.tree.item(item, tags=('selected',))
                break

    def onTreeviewConfigure(self, event):
        # Resize columns when the treeview is configured (e.g., on window resize)
        for i, col in enumerate(self.colHeadings):
            width = self.tree.column(col, option="width")
            self.colWidths[i] = width
        self.resizeColumns()

    def resizeColumns(self):
        # Resize the columns based on stored widths
        for i, col in enumerate(self.colHeadings):
            width = self.colWidths[i]
            print(width)
            self.tree.column(col, width=width, anchor=tk.CENTER)

我通过以下代码将此表放入框架中:

self.dataTable = SimpleDataTable(self, colHeadings = table_titles, colWidths = [350] * len(table_titles)  ,height = 3)
        self.dataTable.grid(row=5, column=0, columnspan=12, pady=10, padx=(20, 10))

最初,表格具有预期的外观。列数是动态的。如果列超过框架大小,滚动条就会激活,我可以使用它来查看所有列。 现在,如果用户想要调整任何单个列的大小,滚动条就会消失,并且所有列都会缩小到父框架大小内。 我尝试了不同类型的回调(在代码中显示),因此当事件发生时会重新绘制表格,但什么也没有发生。我能做些什么? 我希望用户调整列宽并且滚动条仍然保持活动状态。

请注意,所有网格均在相关框架中配置。

python tkinter treeview scrollbar
1个回答
0
投票

设置宽度时我必须添加

stretch=0
self.tree.column(col, width=self.colWidths[i], anchor=tk.CENTER, stretch=0)

© www.soinside.com 2019 - 2024. All rights reserved.