有没有一种方法可以让我在Tkinter中使用for循环创建按钮,同时又给每个按钮一个不同的命令?

时间:2019-04-22 00:03:21

标签: python-3.x tkinter

我正在为学校制作一个修订系统,我希望它能够使用模块化数量的主题,以防万一某个主题被添加到系统中,所以我需要一种方法来制作一些带有不同的主题名称,并能够使用tkinter区分这些按钮。因此,例如,如果他们单击“数学”按钮,则会将他们带到另一段特别适合于数学的代码中(尽管它不能仅适用于数学,因为那时我需要为那些不需要甚至还没有添加)

首先,我只是尝试将命令设置为“ print(subjectnames [subcount-1])”,以为它会打印按钮的名称,但是即使不按下按钮,也可以立即打印出两个名称。然后我尝试根据按钮的名称更改变量名,这是我没想到的,我只是感到沮丧而绝望

在这里我开始设置定义

def chooseQuiz():
    clearWindow()
    subjectnames=[]
    button=[]

这可能并不重要,只是标题和间距的标签

    Label(mainWindow, text="Which quizzes would you like to take?", bg='purple3', font=('constantia',25,"bold")).grid(row=0, column=0, padx=100, pady=0)
    Label(mainWindow, bg='purple3').grid(row=1, column=0, padx=0, pady=15)

在这里,我从SQL表中提取数据以获取所有主题的所有主题名称,这也许也不重要,但这是大多数变量的制作位置

    c.execute("SELECT Subject_name FROM topics")
    for row in c.fetchall():
        if row[0] in subjectnames:
            pass
        elif row[0] not in subjectnames:
            subjectnames.append(row[0])
        else:
            messagebox.showerror("Error", "subjectnames are not appending")
            chooseQuiz()

这是这个问题的主要部分,在这里我试图用不同的命令来形成数量众多的按钮,但无济于事


    for subcount in range(len(subjectnames)):
        button.append(Button(mainWindow, text=str(subjectnames[subcount-1]), bg='grey', fg='black', font=('cambria',15), width=25, command=(subject==subjectnames[subcount-1])))
        button[-1].grid(row=subcount+2,column=0, padx=0, pady=15)

我希望subject变量与我按下的按钮相同,但仍保持为0(原始值)。我认为这是由于我在tkinter中错误使用了命令功能。按钮仍然显示良好(目前只有2个主题,数学和物理,都显示良好)。

1 个答案:

答案 0 :(得分:2)

是的,有可能。

下面的示例创建一个带有重置按钮的窗口;单击“重置”后,将在一个框架中填充按钮,这些按钮对应于从可能的主题中随机选择的按钮的随机数量。每个按钮都有一个调用display函数的命令,该函数将调用重定向到适当的主题,为简化示例,该主题又将其主题的名称打印到控制台。您可以轻松创建与每个主题相对应的函数/类,以封装更复杂的行为。

添加主题就像在key-value中添加SUBJECTS对一样简单

再按一次reset,将删除当前按钮,并将其替换为随机选择的新按钮。

import random
import tkinter as tk
from _tkinter import TclError


SUBJECTS = {'Maths': lambda:print('Maths'), 
            'Physics': lambda:print('Physics'),
            'Chemistry': lambda:print('Chemistry'),
            'Biology': lambda:print('Biology'),
            'Astronomy': lambda:print('Astronomy'),
            'Petrology': lambda:print('Petrology'),}

topics = []


def topic_not_implemented():
    print('this topic does not exist')


def get_topics():
    """randomly creates a list of topics for this example
    """
    global topics
    topics = []
    for _ in range(random.randrange(1, len(SUBJECTS))):
        topics.append(random.choice(list(SUBJECTS.keys())))
    return topics


def reset_topics():
    global topics_frame

    try:
        for widget in topics_frame.winfo_children():
            widget.destroy()
        topics_frame.forget()
        topics_frame.destroy()
    except UnboundLocalError:
        print('error')
    finally:
        topics_frame = tk.Frame(root)
        topics_frame.pack()
    for topic in get_topics():
        tk.Button(topics_frame, text=topic, command=lambda topic=topic: display(topic)).pack()


def display(topic):
    """redirects the call to the proper topic
    """
    SUBJECTS.get(topic, topic_not_implemented)()


root = tk.Tk()
reset = tk.Button(root, text='reset', command=reset_topics)
reset.pack()
topics_frame = tk.Frame(root)
topics_frame.pack()
root.mainloop()