Python tkinter中的循环按钮和功能分配
我已经能够使用此代码在tkinter中生成按钮Python tkinter中的循环按钮和功能分配,python,excel,tkinter,Python,Excel,Tkinter,我已经能够使用此代码在tkinter中生成按钮 for i in range(0, num_sheets): an_sheet = ttk.Button(self, text = "%s" % sh_names[i], command = partial(load_sheets)) an_sheet.grid(row = 1, column = i+1, sticky='w', pady = 10, padx = 10) 现在,这些按钮已根据ex
for i in range(0, num_sheets):
an_sheet = ttk.Button(self, text = "%s" % sh_names[i], command = partial(load_sheets))
an_sheet.grid(row = 1, column = i+1, sticky='w', pady = 10, padx = 10)
现在,这些按钮已根据excel工作表中的工作表数量生成,并已指定它们所代表的工作表的名称。但是,有一个函数可以打印所表示的每张图纸的内容
def load_sheets():
for i,sheetname in enumerate(sh_names) :
xl_sheet = wb.sheet_by_name(sh_names[i])
print()
print(sheetname)
row = xl_sheet.row(0)
for idx, cell_obj in enumerate(row):
cell_type_str = ctype_text.get(cell_obj.ctype, 'unknown type')
row = xl_sheet.nrows
for col_idx in range(0, xl_sheet.ncols):
print ('Column: %s' % col_idx)
for row_idx in range(0, row):
cell_obj = xl_sheet.cell(row_idx, col_idx)
print ('Row: [%s] cell_obj: [%s]' % (row_idx, cell_obj))
现在的挑战是将函数绑定到按钮,以便在单击时打印出自己的内容。例如,单击名为“工作表1”的按钮时,应打印工作表1的内容
下面是代码的完整结构
class MainMenu(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
fname = join(dirname(dirname(abspath('C:/Users/qanda/OneDrive/Documents/Python Scripts/PEN'))), 'Python Scripts/PEN', 'Book1.xlsx')
wb = xlrd.open_workbook(fname)
sh_names = wb.sheet_names()
num_sheets = len(sh_names)
def load_sheets():
for i,sheetname in enumerate(sh_names) :
xl_sheet = wb.sheet_by_name(sh_names[i])
print()
print(sheetname)
row = xl_sheet.row(0)
for idx, cell_obj in enumerate(row):
cell_type_str = ctype_text.get(cell_obj.ctype, 'unknown type')
row = xl_sheet.nrows
for col_idx in range(0, xl_sheet.ncols):
print ('Column: %s' % col_idx)
for row_idx in range(0, row):
cell_obj = xl_sheet.cell(row_idx, col_idx)
print ('Row: [%s] cell_obj: [%s]' % (row_idx, cell_obj))
for i in range(0, num_sheets):
an_sheet = ttk.Button(self, text = "%s" % sh_names[i], command = partial(load_sheets))
an_sheet.grid(row = 1, column = i+1, sticky='w', pady = 10, padx = 10)
那么您想知道如何迭代一组函数并分配它们 你可以用字典 我的A级计算课程作业中的示例
self.screen_info = {"Email Customer": {"button_names": ["Enter Email"], "commands": [self.email_from_email]},
"Text Customer": {"button_names": ["Enter Number"], "commands": [self.text_from_number]},
"Backup Database": {"button_names": ["Choose Location"], "commands": [backup_database.backup]},
"Export Database": {"button_names": ["As .txt", "As .csv"], "commands": [lambda: export.main("txt"), lambda: export.main("csv")]}}
def populate(self):
for key in self.screen_info.keys():
self.screen_info[key]["parent"] = tk.Frame(self.screens, width = 300, height = 300, bg = "#E6E6FA")
self.screen_info[key]["parent"].place(relx = 0.5, rely = 0.5, anchor = tk.CENTER)
for num in range(len(self.screen_info[key]["button_names"])):
self.screen_info[key]["button_names"][num] = tk.Button(self.screen_info[key]["parent"],
width = 20,
text = self.screen_info[key]["button_names"][num],
font = ("Ariel", 11, "bold"),
command = self.screen_info[key]["commands"][num])
self.screen_info[key]["button_names"][num].place(relx = 0.5, y = 60 + num * 40, anchor = tk.CENTER)
因此,这将遍历字典,创建所有内容并分配命令。我将lambda用于“导出数据库”,因为该函数需要一个参数,如果我没有使用lambda,则该函数将在程序启动后立即运行
编辑我用关联的小部件覆盖字典中的每个键值,但如果您不再次引用它们,您甚至不需要设置变量,为它们设置键值定义一个函数来打印一张图纸的内容,将图纸编号作为参数。然后,使用functools.partial将命令与每个按钮关联:
def print_sheet(sheet_number):
...
for i in range(0, num_sheets):
an_sheet = ttk.Button(..., command = partial(print_sheet, i))
...
下面是一个在循环中创建按钮的简短但完整的示例:
import tkinter as tk
from tkinter import ttk
from functools import partial
root = tk.Tk()
def print_sheet(i):
print("printing sheet %d" % i)
for i in range(0, 5):
button = ttk.Button(root, text="Button %d" % i,
command=partial(print_sheet, i))
button.pack()
root.mainloop()
什么是functools.partial?听起来很有趣useful@JoshuaNixon:我以为你知道,因为你发布的代码正在使用它。至少,我假设当您在代码中使用
partial
时,您使用的是functools.partial
,即使您使用的不正确。如果您不知道它的作用,请查找它。@BryanOakley,我已经知道partial,但是,我尝试了您的建议,但没有效果,它将最后一张工作表的文件位置指定给了所有按钮。因此,当点击按钮时,打印出最后一张工作表的文件位置。@JoshuaNixon:partial一词确实在您的代码中:command=partial(load_sheets)
。至于它不起作用,我可以向你保证,它在我的回答中使用时会起作用。我已经更新了我的答案,包括一个完整的例子,这样你就可以看到它是如何工作的。。谢谢你@BryanOakley