[英]How to implement tkinter scrollbars?
我正在努力使用我的代碼來實現水平和垂直滾動條來顯示數據框的值。 我有兩個框架/畫布,第一個用於標題,第二個用於值。
到目前為止,我的代碼顯示了數據框,但我無法正確完成滾動條。 此外,我希望我的水平滾動條同時影響兩個 Canevas,以便我的值和標題一起滾動。 但顯然標題不能隨垂直滾動條滾動(標題應始終保持可見)。
順便說一句:如果有一個比 tkinter 更好的庫來實現一個完全可操作的網格,以及它周圍的所有常用功能,我很感興趣:)
這是我的代碼:
import tkinter as tk
import pandas as pd
df = pd.DataFrame(columns=["header_"+str(i+1) for i in range(10)],
data=[["value_"+str(j*10+i+1) for i in range(10)] for j in range(10)])
root = tk.Tk()
root.geometry("1000x500+300+300")
label = tk.Label(root, text="My Label")
label.grid(row=0, column=0, padx=2, sticky=tk.NW)
frame1 = tk.Frame(root)
frame1.grid(row=1, column=0, sticky=tk.NW)
frame2 = tk.Frame(root)
frame2.grid(row=2, column=0, sticky=tk.NW)
canvas1 = tk.Canvas(frame1)
canvas1.grid(row=0, column=0)
canvas2 = tk.Canvas(frame2)
canvas2.grid(row=0, column=0)
# Headers in canvas1
for i in range(df.shape[1]):
label = tk.Label(canvas1, padx=7, pady=7, borderwidth=1, relief=tk.SOLID, width=10, height=2, text=df.columns[i])
label.grid(row=0, column=i, sticky='news')
# Values in canvas2
for i in range(df.shape[0]):
for j in range(df.shape[1]):
label = tk.Label(canvas2, padx=7, pady=7, borderwidth=1, relief=tk.SOLID, width=10, height=2, text=df.iloc[i, j])
label.grid(row=i, column=j, sticky='news')
# Create a horizontal scrollbar linked to canvas2
hsbar = tk.Scrollbar(canvas2, orient=tk.HORIZONTAL, command=canvas2.xview)
hsbar.grid(row=1, column=0, sticky=tk.EW)
canvas2.configure(xscrollcommand=hsbar.set)
# Create a vertical scrollbar linked to canvas2
vsbar = tk.Scrollbar(canvas2, orient=tk.VERTICAL, command=canvas2.yview)
vsbar.grid(row=0, column=1, sticky=tk.NS)
canvas2.configure(yscrollcommand=vsbar.set)
root.mainloop()
編輯:我取得了一些進展。 tk.Scrollbar的第一個參數有錯誤(canvas2代替frame2,固定兩行)我還在代碼中添加了最后一塊,用canvas2窗口管理和bbox。 它正在工作,但我需要更多時間和解釋才能完全理解它。 歡迎對代碼的最后一部分發表任何評論。
代碼現在是:
import tkinter as tk
import pandas as pd
df = pd.DataFrame(columns=["header_"+str(i+1) for i in range(10)],
data=[["value_"+str(j*10+i+1) for i in range(10)] for j in range(10)])
root = tk.Tk()
root.geometry("1000x500+300+300")
root.title("Scrollable Canvas")
label = tk.Label(root, text="My Label")
label.grid(row=0, column=0, padx=2, sticky=tk.NW)
frame1 = tk.Frame(root)
frame1.grid(row=1, column=0, sticky=tk.NW)
canvas1 = tk.Canvas(frame1)
canvas1.grid(row=0, column=0)
# Headers in canvas1
for i in range(df.shape[1]):
label = tk.Label(canvas1, padx=7, pady=7, borderwidth=1, relief=tk.SOLID, width=10, height=2, text=df.columns[i])
label.grid(row=0, column=i, sticky='news')
# Create a frame for the canvas2 and scrollbars
frame2 = tk.Frame(root)
frame2.grid(row=2, column=0, sticky=tk.NW)
# Add a canvas2 in that frame
canvas2 = tk.Canvas(frame2)
canvas2.grid(row=0, column=0)
# Create a vertical scrollbar linked to canvas2
vsbar = tk.Scrollbar(frame2, orient=tk.VERTICAL, command=canvas2.yview)
vsbar.grid(row=0, column=1, sticky=tk.NS)
canvas2.configure(yscrollcommand=vsbar.set)
# Create a horizontal scrollbar linked to canvas2
hsbar = tk.Scrollbar(frame2, orient=tk.HORIZONTAL, command=canvas2.xview)
hsbar.grid(row=1, column=0, sticky=tk.EW)
canvas2.configure(xscrollcommand=hsbar.set)
# Create a frame on canvas2 to contain the labels
labels_frame = tk.Frame(canvas2)
# Add the labels to this frame
for i in range(df.shape[0]):
for j in range(df.shape[1]):
label = tk.Label(labels_frame, padx=7, pady=7, borderwidth=1, relief=tk.SOLID, width=10, height=2, text=df.iloc[i, j])
label.grid(row=i, column=j, sticky='news')
# Create canvas2 window to hold the label_frame
canvas2.create_window((0,0), window=labels_frame, anchor=tk.NW)
labels_frame.update_idletasks() # Needed to make bbox info available
bbox = canvas2.bbox(tk.ALL) # Get bounding box of canvas2
w, h = bbox[2]-bbox[1], bbox[3]-bbox[1]
canvas2.configure(scrollregion=bbox, width=min(800, w), height=min(400, h))
root.mainloop()
我終於想出了一個全新的解決方案,樹視圖。 代碼並不完美,但它可以運行並且非常有前途:
import tkinter as tk
import pandas as pd
df = pd.DataFrame(columns=["header_"+str(i+1) for i in range(20)],
data=[["value_"+str(j*20+i+1) for i in range(20)] for j in range(100)])
win = tk.Tk()
win.geometry("1000x500+300+300")
frame = tk.Frame()
frame.pack(fill='both', expand=True)
# Create a Treeview with dual Scrollbars
tree = tk.ttk.Treeview(frame, show="headings", columns=df.columns)
hsb = tk.Scrollbar(frame, orient="horizontal", command=tree.xview)
vsb = tk.Scrollbar(frame, orient="vertical", command=tree.yview)
tree.configure(xscrollcommand=hsb.set, yscrollcommand=vsb.set)
tree.grid(column=0, row=0, sticky=tk.NSEW)
vsb.grid(column=1, row=0, sticky=tk.NS)
hsb.grid(column=0, row=1, sticky=tk.EW)
frame.grid_columnconfigure(0, weight=1)
frame.grid_rowconfigure(0, weight=1)
for i, header in enumerate(df.columns):
tree.column(i, width=100, anchor='center')
tree.heading(i, text=header)
for row in range(df.shape[0]):
tree.insert('', 'end', values=list(df.iloc[row]))
win.mainloop()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.