使用 Tkinter 遍历问题列表,并使用单选按钮记录答案

问题描述

我正在使用 python 创建一个 tkinter GUI 来询问问题列表(存储在 excel 中),并计划将所选按钮的结果保存在 .csv 中以提取到 PBI 仪表板中。但是,我在两件事上遇到了困难:1)遍历问题列表,以及 2)创建一个“下一个”按钮来导航到下一个问题(链接到我的第一个问题)。我是 python/Tkinter 的新手,所以任何建议/建议表示赞赏。

from tkinter import ttk
from openpyxl.workbook import Workbook
from openpyxl import load_workbook
global root1
global response
#initiate the main window
root1 = Tk()
#create main window label
label1=Label(root1,text="Question Tool")
#define exit button
def Exit():
    root1.destroy()
#define get value
def selection():
    selection=print("User Selected  " + str(response.get()))
#read governance questions
wb=Workbook()
wb=load_workbook('Questions.xlsx')
ws=wb.active
questions=ws['A']
#def start and stop buttons
def Start_Button():
    global response
    root1.destroy()
    root=Tk()
    root.title("Question Tool")
    tabControl = ttk.Notebook(root)
    tab1 = ttk.Frame(tabControl)
    tab2 = ttk.Frame(tabControl)
    tab3 = ttk.Frame(tabControl)
    tab4 = ttk.Frame(tabControl)
    tab5 = ttk.Frame(tabControl)
    tabControl.add(tab1,text ='1) Governance')
    tabControl.add(tab2,text ='2) Eligibility')
    tabControl.add(tab3,text ='3) Operations')
    tabControl.add(tab4,text ='4) Monitoring')
    tabControl.add(tab5,text ='5) Continuing Improvment')
    tabControl.pack(expand = 1,fill ="both")
    #apply the questions as labels
    ttk.Label(tab1,text=questions[10].value).grid(column = 0,row = 0,padx = 30,pady = 30)
    response=StringVar()
    RB1=ttk.Radiobutton(tab1,text="Yes",value="YES",variable=response)
    RB1.grid(column=0,row=5,padx=10,pady=10)
    RB2=ttk.Radiobutton(tab1,text="No",value="NO",variable=response)
    RB2.grid(column=0,row=10,pady=10)
    x=response.get()
    ttk.Button(tab1,text="Next",command=selection).grid(column=0,row=20,pady=10)
    ttk.Label(tab2,text ="Eligibility radio buttons/questions here").grid(column = 0,pady = 30)
    ttk.Label(tab3,text ="Operations radio buttons/questions here").grid(column = 0,pady = 30)
    ttk.Label(tab4,text ="Monitoring radio buttons/questions here").grid(column = 0,pady = 30)
    ttk.Label(tab5,text ="Continuing Improvment radio buttons/questions here").grid(column = 0,pady = 30)
    root.mainloop()
#add the lable to the root window
label1.pack()
#Add start and stop buttons
Start_Button=Button(root1,text="Click to Begin",pady=10,command=Start_Button)
Start_Button.pack()
Exit_Button=Button(root1,text="Exit",command=Exit)
Exit_Button.pack()
#call main loop
root1.mainloop()

解决方法

您可以在创建此标签后更改标签的 text or other standard options

在此示例中,我正在操作与按钮(响应)关联的变量的值。 Radiobuttons 也有 select()deselect() 之类的命令。


from tkinter import *
from tkinter import ttk
# from openpyxl.workbook import Workbook
# from openpyxl import load_workbook


# initiate variables
global root1
global response
# answers to be saved somewhere
answers = {"governance": [],"eligibility": [],"operations": [],"monitoring": [],"continuing_improvement": []
           }
# prepared question lists
questions = {"governance": ['A','B'],"eligibility": ['C','D'],"operations": ['E','F'],"monitoring": ['G','H'],"continuing_improvement": ['I','J']
             }

# initiate the main window
root1 = Tk()
# create main window label
label1 = Label(root1,text="Question Tool")
# add the lable to the root window
label1.pack()


# define exit button
def Exit():
    root1.destroy()


def selection(parent,label_obj):
    global response
    global questions
    global answers
    user_choice = response.get()
    if user_choice == "":
        # do something if no answer is selected
        print("No answer selected!")
    else:
        print("User Selected:  " + label_obj["text"])
        print("User Selected:  " + user_choice)
        # get question category
        label_obj_name = label_obj.winfo_name()
        # update answers
        answers[label_obj_name].append({label_obj["text"]: user_choice})
        # check if we have run out of questions
        if len(answers[label_obj_name]) == len(questions[label_obj_name]):
            # clear parent tab
            for i in parent.winfo_children():
                i.destroy()
            msg = ttk.Label(parent,text="Done")
            msg.grid(column=0,row=0,padx=30,pady=30)
            print(answers[label_obj_name])
            print(answers)
            # optional: reset response for new tab
            response.set("")
        else:
            # iterating through the list of questions
            # The questions must be different or not repeated in the same category.
            # get the next question in the list
            next_question = questions[label_obj_name][len(answers[label_obj_name])]
            # get next question text
            label_obj["text"] = next_question
            # optional: reset response for next question
            response.set("")
            # or set default selection
            # response.set("YES")


def create_labels_and_buttons(parent,label_text,label_name):
    """Create a separate label and buttons for each tab.

    The response object is global to all tabs.
    Added a label name to distinguish which category the question belongs to.
    """
    global response
    lb = ttk.Label(parent,text=label_text,name=label_name)
    lb.grid(column=0,pady=30)
    rb1 = ttk.Radiobutton(parent,text="Yes",value="YES",variable=response)
    rb1.grid(column=0,row=5,padx=10,pady=10)
    rb2 = ttk.Radiobutton(parent,text="No",value="NO",variable=response)
    rb2.grid(column=0,row=10,pady=10)
    # you can pass the arguments to the function like here
    ttk.Button(parent,text="Next",command=lambda: selection(parent,lb)).grid(column=0,row=20,pady=10)
    

def Start_Button():
    global response
    global questions
    global answers
    root1.destroy()
    root = Tk()
    root.title("Question Tool")
    tabControl = ttk.Notebook(root)
    tab1 = ttk.Frame(tabControl)
    tab2 = ttk.Frame(tabControl)
    tab3 = ttk.Frame(tabControl)
    tab4 = ttk.Frame(tabControl)
    tab5 = ttk.Frame(tabControl)
    tabControl.add(tab1,text='1) Governance')
    tabControl.add(tab2,text='2) Eligibility')
    tabControl.add(tab3,text='3) Operations')
    tabControl.add(tab4,text='4) Monitoring')
    tabControl.add(tab5,text='5) Continuing Improvement')
    tabControl.pack(expand=1,fill="both")
    # response for buttons
    response = StringVar()
    # apply the questions as labels
    create_labels_and_buttons(parent=tab1,label_text=questions["governance"][0],label_name="governance")
    create_labels_and_buttons(parent=tab2,label_text=questions["eligibility"][0],label_name="eligibility")
    create_labels_and_buttons(parent=tab3,label_text=questions["operations"][0],label_name="operations")
    create_labels_and_buttons(parent=tab4,label_text=questions["monitoring"][0],label_name="monitoring")
    create_labels_and_buttons(parent=tab5,label_text=questions["continuing_improvement"][0],label_name="continuing_improvement")

    root.mainloop()


# add start and stop buttons
Start_Button = Button(root1,text="Click to Begin",pady=10,command=Start_Button)
Start_Button.pack()
Exit_Button = Button(root1,text="Exit",command=Exit)
Exit_Button.pack()
# call main loop
root1.mainloop()