我如何允许在python tkinter中的任何地方使用函数?

时间:2020-06-13 04:55:44

标签: python tkinter

我有2个班级,当我运行第一个班级时,它可以正常工作,但是到第二个班级时,我得到一个错误,提示AttributeError: 'Question2' object has no attribute 'correct'。我如何使函数在两个类中都能工作?我的缩进有问题吗?请帮助我修复此代码,谢谢: 编辑:我在使用self时遇到问题,如果我将self从无法正常工作的功能中删除,如果我缩进它不属于课程的一部分,它仍然无法正常工作,self会变成白色

class Question1:
    def __init__ (self, master):
        x = random.randint(5, 12)
        y = random.randint(5, 12)
        self.master = master
        self.user_choice = StringVar()
        self.user_choice.set("")
        self.frame = Frame(master, padx=200, pady=200)
        self.frame.grid()
        self.q = Label(self.frame, text="What is {} + {} ?".format(x, y))
        self.q.grid(row=0)
        self.ans = Entry(self.frame, width=50, textvariable=self.user_choice)
        self.ans.grid(row=1)
        self.answer = x+y
        self.sub = Button(self.frame, text="submit", command=self.correct)
        self.sub.grid(row=3)

    def correct(self):
        global p
        if int(self.user_choice.get()) == self.answer:
            cor = Label(self.frame,text="Correct!")
            cor.grid(row=5, pady=20)
            p += 1
            if p >= 3:
               Question2(self.master)
            else:
                self.sub.destroy()
                nex = Button(self.frame, text="Next", command=self.necs)
                nex.grid(row=4)
        else:
            inc = Label(self.frame,text="incorrect")
            inc.grid(row=5, pady=20)
            self.sub.destroy()
            nex = Button(self.frame, text="Next", command=self.necs)
            nex.grid(row=4)
            self.frame.destroy()
            Question1(self.master)

    def necs(self):
        self.frame.destroy()
        Question1(self.master)


class Question2:
    def __init__(self, master):
        x = random.randint(2, 2)
        y = random.randint(2, 3)
        self.master = master
        self.user_choice = StringVar()
        self.user_choice.set("")
        self.frame = Frame(master, padx=200, pady=200)
        self.frame.grid()
        self.q = Label(self.frame, text="What is {} x {} ?".format(x, y))
        self.q.grid(row=0)
        self.ans = Entry(self.frame, width=50, textvariable=self.user_choice)
        self.ans.grid(row=1)
        self.answer = x * y
        self.sub = Button(self.frame, text="submit", command=self.correct)
        self.sub.grid(row=3)

2 个答案:

答案 0 :(得分:1)

您可以通过将Question1的属性继承到Question2来实现: 可以是:

class Question2(Question1):
    #you can access that by:
    self.correct()

其他方法是您可以在两个类之外定义全局函数,并且可以轻松访问它。 示例:

#somewhere globally:
def correct():
    #some code

class Question1():
    correct()

class Question2():
    correct()

我认为您可以使用多个类需要的函数来开发更多此类想法。

答案 1 :(得分:1)

@JenilDave回答,您需要在类外部定义函数,从其他类继承。明确调用类。

即对于最后一种情况:

class Question1:
    def correct():
        <codes>

class Question2:
    q1 = Question1()
    q1.correct()

    or

    Question1.correct(<Question1 instance>)

但是,由于您的“正确”功能在很大程度上依赖于Question1,因此您无法使用任何一种方法来重构代码。

以下工作示例:


与其将每个问题生成一个问题类别,不如将问题列表发送到一个类别。

每次第三次成功时,您都将通过弹出之前提供的列表来继续下一个问题。

当列表为空时,pop()导致IndexError并关闭程序。

...

由于我无法获得变量“ p”代表的意思,所以我猜想它是成功(通过)的次数。

完整代码:

import random
from tkinter import Frame, Label, Entry, Button, StringVar, Tk


class QuestionFrame(Frame):
    def __init__(self, master, question_answer):
        super().__init__(master)

        self.x, self.y = 0, 0

        self.master = master
        self.entries = question_answer
        self.question, self.answer = self.entries.pop(0)

        self.success = 0

        self.user_choice = StringVar()

        self.frame = Frame(master)
        self.frame.grid()

        self.quest_label = Label(self.frame)
        self.ans = Entry(self.frame, width=50, textvariable=self.user_choice)
        self.sub = Button(self.frame)

        self.quest_label.grid(row=0)
        self.ans.grid(row=1)
        self.sub.grid(row=3)

        self.reload_question()

    def reload_question(self):
        self.x, self.y = random.sample(range(5, 12), 2)

        next_quest = f"What is {self.question.format(self.x, self.y)} ?"

        self.quest_label.configure(text=next_quest)
        self.ans.delete(0, 'end')
        self.sub.configure(text="submit", command=self.correct)

    def next(self):
        print(self.success)
        if self.success == 3:
            # loads next entry
            try:
                self.question, self.answer = self.entries.pop(0)
            except IndexError:
                self.master.destroy()
            else:
                self.success = 0
                self.reload_question()
        else:
            self.reload_question()

    def correct(self):

        self.sub.configure(text="Next", command=self.next)
        if int(self.user_choice.get()) == self.answer(self.x, self.y):
            self.quest_label['text'] = "Correct!"
            self.success += 1

        else:
            self.quest_label['text'] = "Incorrect!"


if __name__ == '__main__':
    # Passing questions with list of (question, answer) tuples.
    tests = [("{} x {}", lambda x, y: x*y),
             ("{} - {}", lambda x, y: x-y)]

    root = Tk()
    root.title(f'Some fancy title')
    window = QuestionFrame(root, tests)
    window.mainloop()