目前,我正在使用 tkinter 画布来尝试滚动按钮。我在画布上放置了二十个按钮,但没有一个按钮像我预期的那样滚动。
import tkinter as tk
from tkinter import *
from tkinter import ttk
from random import randint, choice
window = tk.Tk()
window.geometry('600x400')
window.title('Scrolling Buttons')
canvas = tk.Canvas(window, scrollregion = (0,0,2000,5000))
for i in range(20):
Button(window, text = "Start", width = 10, bg = "#b5e2ff", activebackground = "#03c04a", activeforeground = "white", font = ("Helevetica", 10)).pack()
canvas.pack(expand = True, fill = 'both')
canvas.bind('<MouseWheel>', lambda event: canvas.yview_scroll(-int(event.delta / 60), "units"))
scrollbar = ttk.Scrollbar(window, orient = 'vertical', command = canvas.yview)
canvas.configure(yscrollcommand = scrollbar.set)
scrollbar.place(relx = 1, rely = 0, relheight = 1, anchor = 'ne')
window.mainloop()
首先,您已将这些按钮创建为
window
的子级,而不是 canvas
,因此它们不会放置在画布内。
实现目标的方法之一是在画布内创建一个框架并将这些按钮放入该框架内。然后使用
.create_window(...)
将该框架放入画布内。
下面是一个简单的例子:
import tkinter as tk
window = tk.Tk()
window.geometry('600x400')
window.title('Scrolling Buttons')
canvas = tk.Canvas(window)
scrollbar = tk.Scrollbar(window, orient='vertical', command=canvas.yview)
canvas.config(yscrollcommand=scrollbar.set)
scrollbar.pack(side='right', fill='y')
canvas.pack(side='left', fill='both', expand=1)
# frame for those buttons
frame = tk.Frame(canvas)
canvas.create_window(0, 0, window=frame, anchor='nw', tags=('frame',))
# set the width of the frame to the same as that of the canvas
canvas.bind('<Configure>', lambda e: canvas.itemconfig('frame', width=e.width))
# update canvas scrollregion whenever the frame is resized
frame.bind('<Configure>', lambda e: canvas.config(scrollregion=canvas.bbox('all')))
frame.bind('<MouseWheel>', lambda e: canvas.yview_scroll(-e.delta//60, 'units'))
# add buttons to the frame
for i in range(20):
tk.Button(frame, text=f'Start {i+1}', width=10, bg='#b5e2ff',
activebackground='#03c04a', activeforeground='white',
font=('Helvetica', 10)).pack(pady=2)
window.mainloop()
结果: