我正在尝试在Tkinter中创建一个简单的多项选择测验。目标是拥有多个测验类别,每个类别中都有多个问题。为此,我尝试使用命名元组,并将其传递给测验类和方法。运行该程序时,我收到以下回溯消息:
Traceback (most recent call last):
File "/home/daniel/pythonfiles/tkquizradio.py", line 124, in <module>
app = SimpleTkinter()
File "/home/daniel/pythonfiles/tkquizradio.py", line 31, in __init__
frame = F(house, self)
TypeError: __init__() takes 2 positional arguments but 3 were given
奇怪的是,在编辑MathQuiz类并尝试创建按钮和getDecision方法之前,我没有收到此错误。初始帧显示正常,我可以选择想要的测验。真的不确定为什么会这样。如果您对我有任何建议,关于此问题,我们将不胜感激。
"""import any necessary modules"""
import tkinter as tk
from collections import namedtuple
from tkinter import *
qtuple = namedtuple("question", "question, correct")
atuple = namedtuple("answer", "answer1, answer2, answer3, answer4")
FONT = ("Verdana", 12)
""""create tkinter frames"""
class SimpleTkinter(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
house = tk.Frame(self)
house.pack(side = "top", fill = "both", expand = True)
house.grid_rowconfigure(0, weight = 1)
house.grid_columnconfigure(0, weight = 1)
self.frames = {}
for F in (StartPage, QuizChoice, MathQuiz):
frame = F(house, self)
self.frames[F] = frame
frame.grid(row = 0, column = 0, sticky = "nsew")
self.show_frame(StartPage)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
"""create startpage"""
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text = "Multiple Choice Quiz", font=FONT)
label.pack(pady=10,padx=10)
startbutton = tk.Button(self, text="Click to start quiz",
command=lambda: controller.show_frame(QuizChoice))
startbutton.pack()
"""main logic"""
class QuizChoice(tk.Frame):
def __init__(self, parent, controller):
"""get input""""
tk.Frame.__init__(self, parent)
v = tk.IntVar()
label = tk.Label(self, text = "Please choose a category:", justify = tk.LEFT,font = FONT)
label.pack(pady=10, padx=10)
button1 = tk.Radiobutton(self, text="Math", variable=v, value=1,
command=lambda: controller.show_frame(MathQuiz))
button1.pack()
button2 = tk.Radiobutton(self, text="Animals", variable=v, value=2)
button2.pack()
button3 = tk.Radiobutton(self, text="History", variable=v, value=3)
button3.pack()
"""def different quizzes"""
class MathQuiz(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
v = tk.IntVar()
"""create label containing question"""
"""create radiobuttons with options"""
"""set score"""
score = 0
quiz = [qtuple("What is 1 + 4", {"5"}), """"..."""]
answers = [atuple("3", "4", "5", "6")]
for question in quiz:
label1 = tk.Label(self, text=question.question, font=FONT)
label1.pack(pady=10, padx=10)
for answer in answers:
button1 = tk.Radiobutton(self, text=answer.answer1, variable=answer.answer1, value=1)
button1.pack()
button2 = tk.Radiobutton(self, text=answer.answer2, variable=v, value=2)
button2.pack()
button3 = tk.Radiobutton(self, text=answer.answer3, variable=v, value=3)
button3.pack()
submit = tk.Button(self, text='Submit', command=getDecision)
submit.grid()
def getDecision(self):
if v.get() == quiz.correct:
messagebox.showinfo('Congrats', message='You Are Correct.Score is {}'.format(score))
else:
messagebox.showinfo('Lose', message='You Are Wrong.')
class history_quiz():
questions = [qtuple("What is", "answer", ["choices"], {"correct"})]
class animal_quiz():
questions = [qtuple("What is", "answer", ["choices"], {"correct"})]
app = SimpleTkinter()
app.mainloop()
答案 0 :(得分:2)
您的前两个框架类采用三个参数:
class StartPage(tk.Frame):
def __init__(self, parent, controller):
class QuizChoice(tk.Frame):
def __init__(self, parent, controller):
...但是您的最后一个只需要两个:
class MathQuiz(tk.Frame):
def __init__(self, parent):
__init__
方法与其他任何方法一样,只能接受您声明要采用的参数。当您尝试使用该额外参数构造MathQuiz
时,它不知道如何处理它,因此会抱怨。
最小的解决方法是仅添加另一个参数,因此它与其他类匹配:
class MathQuiz(tk.Frame):
def __init__(self, parent, controller):
现在它们都具有相同的签名,因此都可以以相同的方式使用它们,因此您的代码可以正常工作。与controller
没有任何关系的事实并不意味着您不能将其作为参数而只是忽略它。