用 tkinter 做一种 Excel 表格

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

我想用 tkinter 显示一个表格,其中:

  • 窗口大小根据内容调整
  • 如果行太多,建议垂直滚动
  • 可以使用表格内的滚轮进行垂直滚动(如在 Excel 中)
  • 可以复制一个单元格的值(右键单击该单元格)

这篇文章(在 Tkinter 中向一组小部件添加滚动条)有助于理解使用 tkinter 进行滚动...但不满足上述所有要求。

user-interface tkinter scroll tkinter-canvas
1个回答
0
投票

主要技巧是:

  • 只有少数 tkinter 对象是可滚动的(Canvas 是可滚动的)
  • 在画布内部,不要使用网格或包(你会失去可滚动性),但专用于画布的方法称为“create_window”
  • 在画布内创建一个框架...就像在框架内一样,您可以很好地使用包/网格方法。
  • 根据内容调整画布大小....每次将内容添加到画布中时(事件)
  • 捕获鼠标滚轮事件的方式取决于您的操作系统(在下面的示例中适用于 Windows)
  • 我们会中断滚动条中的任何鼠标滚轮事件(以免与 yopu 编程的鼠标滚轮事件冲突)
# Standard libraries
import tkinter as tk


class ResultWindow(tk.Tk):

    def __init__(self):

        # Initialize the GUI
        super().__init__()

        # Create the main widgets
        self.canvas = tk.Canvas(self)
        self.vsb = tk.Scrollbar(self, orient="vertical", width=25)
        self.frame = tk.Frame(self.canvas)

        # Add them to the toplevel layout
        # Only create_window method will allow scroll inside a canvas
        self.canvas.pack(side="left", fill="y")
        self.vsb.pack(side="right", fill="y")
        self.canvas.create_window((0, 0), window=self.frame, anchor="nw")

        # Bind events to the widgets
        self.canvas.bind_all("<MouseWheel>", self.on_mousewheel)
        self.vsb.bind("<MouseWheel>", lambda event: "break")
        self.frame.bind("<Configure>", self.on_frame_configure)

        # Link Canvas scroll with Scrollbar
        self.canvas.configure(yscrollcommand=self.vsb.set)
        self.vsb.configure(command=self.canvas.yview)

        # Add the frame to define the way
        self.l_cell = None

        # Instantiate the tasker with the results
        self.add_content(200, 5)
        
    def add_content(self, rows, cols):
        
        # Declare functions to manage code labels highlighting
        set_color = lambda event: event.widget.config(bg="grey")
        reset_color = lambda event: event.widget.config(bg="SystemButtonFace")
        
        for col in range(cols):
            for row in range(rows):
                # Add the cells to the gris
                text = f"row: {row}, col: {col}"
                self.l_cell = tk.Label(self.frame, text=text, relief="solid")
                self.l_cell.grid(row=row, column=col, sticky="nsew")
                
                # Bind each cell to events
                self.l_cell.bind("<Enter>", set_color)
                self.l_cell.bind("<Leave>", reset_color)
                self.l_cell.bind("<Button-3>", self.on_click)
                
    def on_frame_configure(self, event):
        # Resize the canvas to fit with the content
        self.canvas.config(width=self.canvas.bbox("all")[2],
                           height=self.canvas.bbox("all")[3])

        # Adjust the scrollable scope to the new size of the canvas
        self.canvas.configure(scrollregion=self.canvas.bbox("all"))

    def on_mousewheel(self, event):
        # Update teh scroll according to the mousewheel scroll size
        self.canvas.yview_scroll(int(-1 * (event.delta / 120)), "units")

    def on_click(self, event):
        # Copy the label text to the clipboard
        self.clipboard_clear()
        # Get the Label widget code and add it to the clipboard
        self.clipboard_append(event.widget.cget("text"))
        
app = ResultWindow()
app.mainloop()
© www.soinside.com 2019 - 2024. All rights reserved.