Tkinter 和 Python 相对较新.所以请多多包涵.
我正在尝试显示以下 GUI,并希望在 Frame2 中有一个滚动条,以一次仅显示 5x5 个按钮.看起来 Tkinter 框架不支持滚动条,因此在父框架FMas"中添加了一个画布(框架嵌入其中)和一个滚动条.但由于某种原因,滚动条会转到屏幕的右端并且不进行任何滚动.
画布不应该在 Frame2 的边缘结束并且滚动条就在它旁边吗?此外,我尝试使用 rowspan 来增加滚动条的高度以匹配 5x5 按钮的高度.这也行不通.
代码(使用Python3.2):
从 tkinter 导入 *将 tkinter.ttk 导入为 ttkmGui = Tk()mGui.geometry("630x600")mGui.configure(背景="灰色")mGui.columnconfigure(0, weight=1)mGui.rowconfigure(0, weight=1)FMas = Frame(mGui, bg="灰色")FMas.grid(粘性=(N,E,S,W))FMas.columnconfigure(0, weight=1)L1 = 标签(FMas, text="第 1 帧内容")L1.grid(行=0,列=0,pady=5,粘性=(N,W))F1 = 框架(FMas,bg="Green",bd=2,浮雕=GROOVE)F1.grid(行=1,列=0,粘性=(N,W))ChkBox1=IntVar()CB1 = Checkbutton(F1, text="StartCheckBox", variable=ChkBox1)CB1.grid(行=0,列=0,padx=2)L2 = 标签(FMas, text="第 2 帧内容")L2.grid(行=2,列=0,pady=5,粘性=(N,W))Can1 = Canvas(FMas, bg="黄色")Can1.grid(行=3,列=0,粘性=(N,W))F2 = 框架(Can1,bg="蓝色",bd=2,浮雕=GROOVE)F2.grid(行=0,列=0,粘性=(N,W))行 = 10对于范围内的 i(1,行):对于范围(1,6)中的 j:button = Button(F2, padx=7, pady=7, text="[%d,%d]" % (i,j))button.grid(行=i,列=j,粘性='新闻')vsbar = 滚动条(FMas, orient="vertical", command=Can1.yview)vsbar.grid(行=3,列=1)Can1.configure(yscrollcommand=vsbar.set, scrollregion=Can1.bbox("all"))L3 = 标签(FMas, text="第 3 帧内容")L3.grid(行=4,列=0,pady=5,粘性=(N,W))F3 = 框架(FMas,bg="Red",bd=2,浮雕=GROOVE)F3.grid(行=5,列=0,粘性=(N,W))ChkBox2=IntVar()CB2 = Checkbutton(F3, text="EndCheckBox", variable=ChkBox2)CB2.grid(行=0,列=0,padx=2)mGui.mainloop()sys.exit()
你的滚动条的高度与按钮框架的高度不匹配,因为你没有告诉它坚持南北 .grid(...,sticky='ns')
然后,您想要实现的滚动行为在此处描述:
将 tkinter 导入为 tk根 = tk.Tk()root.grid_rowconfigure(0, weight=1)root.columnconfigure(0, weight=1)frame_main = tk.Frame(root, bg=灰色")frame_main.grid(sticky='新闻')label1 = tk.Label(frame_main, text=标签 1", fg=绿色")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')# 为画布创建一个具有非零行列权重的框架frame_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)# 将 grid_propagate 设置为 False 以允许稍后调整 5×5 按钮的大小frame_canvas.grid_propagate(假)# 在该帧中添加一个画布canvas = tk.Canvas(frame_canvas, bg=黄色")canvas.grid(行=0,列=0,粘性=新闻")# 将滚动条链接到画布vsb = tk.Scrollbar(frame_canvas, orient="vertical", command=canvas.yview)vsb.grid(行=0,列=1,粘性='ns')canvas.configure(yscrollcommand=vsb.set)# 创建一个框架来包含按钮frame_buttons = tk.Frame(canvas, bg=蓝色")canvas.create_window((0, 0), window=frame_buttons, anchor='nw')# 向框架添加 9×5 按钮行 = 9列 = 5按钮 = [[tk.Button() for j in range(columns)] for i in range(rows)]对于我在范围内(0,行):对于范围内的 j(0,列):按钮[i][j] = tk.Button(frame_buttons, text=("%d,%d" % (i+1, j+1)))按钮[i][j].grid(row=i, column=j,sticky='news')# 更新按钮帧空闲任务让 tkinter 计算按钮大小frame_buttons.update_idletasks()# 调整画布框架的大小以准确显示 5×5 按钮和滚动条first5columns_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(),高度=first5rows_height)# 设置画布滚动区域canvas.config(scrollregion=canvas.bbox(全部"))# 启动图形用户界面root.mainloop()
Relatively new to Tkinter and Python. So kindly bear with me.
I am trying to display the following GUI and want to have a scrollbar in Frame2 to display only 5x5 buttons at a time. Looks like Tkinter Frames don't support scrollbar and hence added a canvas (within which the frame is embedded) and a scrollbar in the parent frame 'FMas'. But for some reason the scroll bar goes to the right end of the screen and doesn't do any scrolling.
Shouldn't the canvas end at the edge of the Frame2 and the scroll bar be right next to it? Also, I tried rowspan to increase the height of the scrollbar to match the height of 5x5 buttons. That too doesn't work.
CODE (Using Python3.2):
from tkinter import *
import tkinter.ttk as ttk
mGui = 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 = 10
for 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()
The height of your scrollbar didn't match the buttons frame height because you did't tell it to stick North and South .grid(..., sticky='ns')
Then, the scrolling behavior you want to achieve is described here: Adding a Scrollbar to a group of widgets
See also @martineau's answer for a more general object-oriented solution with 2D scrolling (horizontal & vertical)
import tkinter as tk
root = 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 weights
frame_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 later
frame_canvas.grid_propagate(False)
# Add a canvas in that frame
canvas = tk.Canvas(frame_canvas, bg="yellow")
canvas.grid(row=0, column=0, sticky="news")
# Link a scrollbar to the canvas
vsb = 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 buttons
frame_buttons = tk.Frame(canvas, bg="blue")
canvas.create_window((0, 0), window=frame_buttons, anchor='nw')
# Add 9-by-5 buttons to the frame
rows = 9
columns = 5
buttons = [[tk.Button() for j in range(columns)] for i in range(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 sizes
frame_buttons.update_idletasks()
# Resize the canvas frame to show exactly 5-by-5 buttons and the scrollbar
first5columns_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 region
canvas.config(scrollregion=canvas.bbox("all"))
# Launch the GUI
root.mainloop()
这篇关于带有网格的 tkinter 画布滚动条?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!