Tkinter是一个Python的GUI可视化界面库,提供了很多方法,此次就聊一下Tkinter如何无限创建Button。
主要思想:先创建一个Canvas画布,再在Canvas上面创建一层Frame,最后在创建Button时,每个Button都创建在一个Frame上,并且这个Frame放在Canvas上面那层Frame上。(一共4层【Canvas-->Frame-->Frame-->Button】)
原因:Canvas用于创建滚轮,使得Button超出Tkinter界面时可以滚动查看Button,第一层Frame可以防止第二层Frame的创建导致Canvas滚轮失效。第二层Frame的作用是包裹主要Button和更改Button内容的Button,作用是可以使得Button位置得以合理排布,而且不会导致无法创建多个Button的问题。
主要方法:
1、先创建一个Canvas和第一层Frame
self.canvas = tkinter.Canvas(self.root)
self.canvas.pack(side='left', fill='both', expand=True)
self.scrollbar = tkinter.Scrollbar(self.root, command=self.canvas.yview)
self.scrollbar.pack(side='right', fill='y')
self.canvas.configure(yscrollcommand=self.scrollbar.set)
self.canvas.bind('<MouseWheel>', self.on_mousewheel)
self.button_frame = tkinter.Frame(self.canvas)
self.canvas.create_window((0, 0), window=self.button_frame, anchor='nw')
其中,Canvas的滚轮函数on_mousewheel代码如下:
def on_mousewheel(self, event):
# 向上滚动
if event.delta < 0:
self.canvas.yview_scroll(1, 'units')
# 向下滚动
elif event.delta > 0:
self.canvas.yview_scroll(-1, 'units')
2、创建添加Button的添加按钮,并且初始化位置参数,从而实现每个创建出来的Button的位置的合理性
# 添加按钮
button_plus = tkinter.Button(self.root, cursor='arrow', text='增添按钮', command=self.plus, width=10)
button_plus.pack(side='top', pady=10)
# 位置参数
self.row1 = 0
self.column1 = 0
self.padx1 = 5
self.pada1 = 5
self.column_per_row = 2
其中,该添加按钮的功能代码
# 当添加按钮被单击时,创建两个按钮,一个是执行按钮,一个是更改执行按钮用处的按钮
def plus(self):
frame = tkinter.Frame(self.button_frame)
frame.grid(row=self.row1, column=self.column1, padx=self.padx1, pady=self.pada1)
self.frames.append(frame)
self.button = tkinter.Button(frame, text="", width=50, height=6)
self.button.grid(row=0, column=0, sticky="w")
self.button2 = tkinter.Button(frame, text='更改按钮设置', width=10, height=5)
self.button2.grid(row=0, column=1, sticky='w')
sor2 = []
for i in self.frames:
if i != 0:
sor2.append(i)
for i, frame in enumerate(sor2):
row = self.row1 + i // self.column_per_row
column = self.column1 + i % self.column_per_row
frame.grid(row=row, column=column, padx=self.padx1, pady=self.pada1)
# 更新canvas
self.layout()
在这个代码中,“self.frames”这个列表是用于给每个Frame添加一个索引,以此在后面更改按钮Button的设置可以传递给实现Button。而layout是刷新界面用的,代码如下:
# 添加按钮的创建
def layout(self):
self.button_frame.update_idletasks()
self.canvas.configure(scrollregion=self.canvas.bbox('all'))
整体代码如下:
import tkinter
class test(object):
def __init__(self):
self.root = tkinter.Tk()
self.root.title('收藏夹')
self.root.minsize(1000, 650)
self.root.maxsize(1000, 650)
screenWidth = self.root.winfo_screenwidth() # 获取显示区域的宽度
screenHeight = self.root.winfo_screenheight() # 获取显示区域的高度
width = 1000 # 设定窗口宽度
height = 650 # 设定窗口高度
self.left = (screenWidth - width) / 2
self.top = (screenHeight - height) / 2
self.root.geometry("%dx%d+%d+%d" % (width, height, self.left, self.top))
self.canvas = tkinter.Canvas(self.root)
self.canvas.pack(side='left', fill='both', expand=True)
self.scrollbar = tkinter.Scrollbar(self.root, command=self.canvas.yview)
self.scrollbar.pack(side='right', fill='y')
self.canvas.configure(yscrollcommand=self.scrollbar.set)
self.canvas.bind('<MouseWheel>', self.on_mousewheel)
# 创建一个frame,将其置于canvas中
self.button_frame = tkinter.Frame(self.canvas)
self.canvas.create_window((0, 0), window=self.button_frame, anchor='nw')
# 添加按钮
button_plus = tkinter.Button(self.root, cursor='arrow', text='增添按钮', command=self.plus, width=10)
button_plus.pack(side='top', pady=10)
# 位置参数
self.row1 = 0
self.column1 = 0
self.padx1 = 5
self.pada1 = 5
self.column_per_row = 2
# 按钮
self.layout()
# 存放button
self.frames = []
self.root.mainloop()
# 鼠标滚轮
def on_mousewheel(self, event):
# 向上滚动
if event.delta < 0:
self.canvas.yview_scroll(1, 'units')
# 向下滚动
elif event.delta > 0:
self.canvas.yview_scroll(-1, 'units')
# 添加按钮的创建
def layout(self):
self.button_frame.update_idletasks()
self.canvas.configure(scrollregion=self.canvas.bbox('all'))
# 当添加按钮被单击时,创建两个按钮,一个是执行按钮,一个是更改执行按钮用处的按钮
def plus(self):
frame = tkinter.Frame(self.button_frame)
frame.grid(row=self.row1, column=self.column1, padx=self.padx1, pady=self.pada1)
self.frames.append(frame)
self.button = tkinter.Button(frame, text="", width=50, height=6)
self.button.grid(row=0, column=0, sticky="w")
self.button2 = tkinter.Button(frame, text='更改按钮设置', width=10, height=5)
self.button2.grid(row=0, column=1, sticky='w')
sor2 = []
for i in self.frames:
if i != 0:
sor2.append(i)
for i, frame in enumerate(sor2):
row = self.row1 + i // self.column_per_row
column = self.column1 + i % self.column_per_row
frame.grid(row=row, column=column, padx=self.padx1, pady=self.pada1)
# 更新canvas
self.layout()
test1=test()
效果如下: