Tkinter和Python相对较新.亲切地忍受我.
我试图显示以下GUI,并希望在Frame2中有一个滚动条,一次只显示5×5按钮.看起来Tkinter Frames不支持滚动条,因此添加了一个画布(嵌入了框架)和父框架’FMas’中的滚动条.但由于某种原因,滚动条会移到屏幕的右端,不会进行任何滚动.
画布不应该在Frame2的边缘结束,滚动条就在它旁边吗?此外,我尝试使用rowspan来增加滚动条的高度以匹配5×5按钮的高度.那也行不通.
代码(使用Python3.2):
from tkinter import *import tkinter.ttk as ttkmGui = Tk()mGui.geometry("630x600")mGui.configure(background="Gray")mGui.columnconfigure(0, weight=1)mGui.rowconfigure(0, weight=1)FMas = Frame(mGui, bg="Gray")FMas.grid(sticky=(N,E,S,W))FMas.columnconfigure(0, weight=1)L1 = Label(FMas, text="Frame 1 Contents")L1.grid(row=0, column=0, pady=5, sticky=(N,W))F1 = Frame(FMas, bg="Green", bd=2, relief=GROOVE)F1.grid(row=1, column=0, sticky=(N,W))ChkBox1=IntVar()CB1 = Checkbutton(F1, text="StartCheckBox", variable=ChkBox1)CB1.grid(row=0,column=0,padx=2)L2 = Label(FMas, text="Frame 2 Contents")L2.grid(row=2, column=0, pady=5, sticky=(N,W))Can1 = Canvas(FMas, bg="Yellow")Can1.grid(row=3, column=0, sticky=(N,W))F2 = Frame(Can1, bg="Blue", bd=2, relief=GROOVE)F2.grid(row=0, column=0, sticky=(N,W))rows = 10for i in range(1,rows): for j in range(1,6): button = Button(F2, padx=7, pady=7, text="[%d,%d]" % (i,j)) button.grid(row=i, column=j, sticky="news")vsbar = Scrollbar(FMas, orient="vertical", command=Can1.yview)vsbar.grid(row=3, column=1)Can1.configure(yscrollcommand=vsbar.set, scrollregion=Can1.bbox("all"))L3 = Label(FMas, text="Frame 3 Contents")L3.grid(row=4, column=0, pady=5, sticky=(N,W))F3 = Frame(FMas, bg="Red", bd=2, relief=GROOVE)F3.grid(row=5, column=0, sticky=(N,W))ChkBox2=IntVar()CB2 = Checkbutton(F3, text="EndCheckBox", variable=ChkBox2)CB2.grid(row=0,column=0,padx=2)mGui.mainloop()sys.exit()解决方法:
滚动条的高度与按钮框架高度不匹配,因为你没有告诉它坚持北和南.grid(…,sticky =’ns’)
然后,您要实现的滚动行为在此处描述:Adding a Scrollbar to a group of widgets
另请参阅@martineau的答案,了解更加通用的面向对象的2D滚动解决方案(水平和垂直)
import tkinter as tkroot = tk.Tk()root.grid_rowconfigure(0, weight=1)root.columnconfigure(0, weight=1)frame_main = tk.Frame(root, bg="gray")frame_main.grid(sticky="news")label1 = tk.Label(frame_main, text="Label 1", fg="green")label1.grid(row=0, column=0, pady=(5, 0), sticky="nw")label2 = tk.Label(frame_main, text="Label 2", fg="blue")label2.grid(row=1, column=0, pady=(5, 0), sticky="nw")label3 = tk.Label(frame_main, text="Label 3", fg="red")label3.grid(row=3, column=0, pady=5, sticky="nw")# Create a frame for the canvas with non-zero row&column weightsframe_canvas = tk.Frame(frame_main)frame_canvas.grid(row=2, column=0, pady=(5, 0), sticky="nw")frame_canvas.grid_rowconfigure(0, weight=1)frame_canvas.grid_columnconfigure(0, weight=1)# Set grid_propagate to False to allow 5-by-5 buttons resizing laterframe_canvas.grid_propagate(False)# Add a canvas in that framecanvas = tk.Canvas(frame_canvas, bg="yellow")canvas.grid(row=0, column=0, sticky="news")# Link a scrollbar to the canvasvsb = tk.Scrollbar(frame_canvas, orient="vertical", command=canvas.yview)vsb.grid(row=0, column=1, sticky="ns")canvas.configure(yscrollcommand=vsb.set)# Create a frame to contain the buttonsframe_buttons = tk.Frame(canvas, bg="blue")canvas.create_window((0, 0), window=frame_buttons, anchor="nw")# Add 9-by-5 buttons to the framerows = 9columns = 5buttons = [[tk.Button() for j in xrange(columns)] for i in xrange(rows)]for i in range(0, rows): for j in range(0, columns): buttons[i][j] = tk.Button(frame_buttons, text=("%d,%d" % (i 1, j 1))) buttons[i][j].grid(row=i, column=j, sticky="news")# Update buttons frames idle tasks to let tkinter calculate buttons sizesframe_buttons.update_idletasks()# Resize the canvas frame to show exactly 5-by-5 buttons and the scrollbarfirst5columns_width = sum([buttons[0][j].winfo_width() for j in range(0, 5)])first5rows_height = sum([buttons[i][0].winfo_height() for i in range(0, 5)])frame_canvas.config(width=first5columns_width vsb.winfo_width(), height=first5rows_height)# Set the canvas scrolling regioncanvas.config(scrollregion=canvas.bbox("all"))# Launch the GUIroot.mainloop()来源:/content-1-474401.html
如果觉得《python – tkinter带网格的画布滚动条?》对你有帮助,请点赞、收藏,并留下你的观点哦!