需要帮助解决Tkinter位置参数错误-错误创建框架

时间:2018-08-02 05:35:12

标签: python tkinter

我正在尝试在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()

1 个答案:

答案 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没有任何关系的事实并不意味着您不能将其作为参数而只是忽略它。