【问题标题】:Accessing variable from another function in a function while using class() method使用 class() 方法从函数中的另一个函数访问变量
【发布时间】:2020-08-20 11:59:20
【问题描述】:

我想知道是否有任何方法可以通过不同的函数访问变量?下面是我的代码,在 isWinner() 内部,我想访问按钮的文本。怎么可能?

class ttt():
    master = 0
    player1 = 0
    player2 = 0
    bclick = True
    buttonCounter = 1
    win = 0
    lose = 0

    def boardDisplay(self):
        button1 = tk.Button(self.master, text=" ", command=lambda: self.buttonClick(button1), height=4, width=10)
        button1.place(x=275, y=150)
        button2 = tk.Button(self.master, text=" ", command=lambda: self.buttonClick(button2), height=4, width=10)
        button2.place(x=355, y=150)
        button3 = tk.Button(self.master, text=" ", command=lambda: self.buttonClick(button3), height=4, width=10)
        button3.place(x=435, y=150)
        button4 = tk.Button(self.master, text=" ", command=lambda: self.buttonClick(button4), height=4, width=10)
        button4.place(x=275, y=230)
        button5 = tk.Button(self.master, text=" ", command=lambda: self.buttonClick(button5), height=4, width=10)
        button5.place(x=355, y=230)
        button6 = tk.Button(self.master, text=" ", command=lambda: self.buttonClick(button6), height=4, width=10)
        button6.place(x=435, y=230)
        button7 = tk.Button(self.master, text=" ", command=lambda: self.buttonClick(button7), height=4, width=10)
        button7.place(x=275, y=310)
        button8 = tk.Button(self.master, text=" ", command=lambda: self.buttonClick(button8), height=4, width=10)
        button8.place(x=355, y=310)
        button9 = tk.Button(self.master, text=" ", command=lambda: self.buttonClick(button9), height=4, width=10)
        button9.place(x=435, y=310)

    def buttonClick(self, button):
        if button["text"] == " " and self.bclick == True:
            button["text"] = "X"
            self.bclick = False
            self.isWinner()
            self.buttonCounter += 1
        elif button["text"] == " " and self.bclick == False:
            button["text"] = "O"
            self.bclick = True
            self.isWinner()
            self.buttonCounter += 1
        else:
            tk.messagebox.showinfo("Tic Tac Toe", "Button is clicked already!")

    def isWinner(self): 

【问题讨论】:

  • 声明一个self变量
  • @r0ei 我试过它返回一个错误。所以在我的 isWinner() 函数中,我尝试编写 self.button1["text"] == "X" 或 self.boardDisplay().button1["text"] 它不会以某种方式工作

标签: python class tkinter


【解决方案1】:

您必须在按钮之前每次写上self。当您第一次在self 上声明某些内容时,它实际上会在self.__dict__ 中实例化。调用 self 只是简写。话虽如此,当您制作按钮时,您并没有将它们粘贴在__dict__ 中,因此它们不存在。如果您想知道自己是否搞砸了self,只需print(self.__dict__)。如果它不存在,那么您没有在self 上声明它。我说的是instances 而不是methods。换句话说,button9 是一个实例,boardDisplay 不是。

class ttt():
    master = 0
    player1 = 0
    player2 = 0
    bclick = True
    buttonCounter = 1
    win = 0
    lose = 0

    def boardDisplay(self):
        self.button1 = tk.Button(self.master, text=" ", command=lambda: self.buttonClick(button1), height=4, width=10)
        self.button1.place(x=275, y=150)
        self.button2 = tk.Button(self.master, text=" ", command=lambda: self.buttonClick(button2), height=4, width=10)
        self.button2.place(x=355, y=150)
        self.button3 = tk.Button(self.master, text=" ", command=lambda: self.buttonClick(button3), height=4, width=10)
        self.button3.place(x=435, y=150)
        self.button4 = tk.Button(self.master, text=" ", command=lambda: self.buttonClick(button4), height=4, width=10)
        self.button4.place(x=275, y=230)
        self.button5 = tk.Button(self.master, text=" ", command=lambda: self.buttonClick(button5), height=4, width=10)
        self.button5.place(x=355, y=230)
        self.button6 = tk.Button(self.master, text=" ", command=lambda: self.buttonClick(button6), height=4, width=10)
        self.button6.place(x=435, y=230)
        self.button7 = tk.Button(self.master, text=" ", command=lambda: self.buttonClick(button7), height=4, width=10)
        self.button7.place(x=275, y=310)
        self.button8 = tk.Button(self.master, text=" ", command=lambda: self.buttonClick(button8), height=4, width=10)
        self.button8.place(x=355, y=310)
        self.button9 = tk.Button(self.master, text=" ", command=lambda: self.buttonClick(button9), height=4, width=10)
        self.button9.place(x=435, y=310)

    def buttonClick(self, button):
        if button["text"] == " " and self.bclick == True:
            button["text"] = "X"
            self.bclick = False
            self.isWinner()
            self.buttonCounter += 1
        elif button["text"] == " " and self.bclick == False:
            button["text"] = "O"
            self.bclick = True
            self.isWinner()
            self.buttonCounter += 1
        else:
            tk.messagebox.showinfo("Tic Tac Toe", "Button is clicked already!")

    def isWinner(self):
        print(self.button9['text'])

您应该将boardDisplay 重命名为__init__。类通常具有所谓的constructor。在 python 中__init__ 是您声明构造函数的方式。这样当你实例化ttt() 时,你真正在做的就是将它称为__init__

真的你的代码应该是这样的:

import tkinter as tk

#tell this class that it is an extension of tk.Tk ~ the root
class App(tk.Tk):
    #class constructor ~ hit when you do App()
    def __init__(self):
        #init the class that App extended ~ this is also know as the superclass
        tk.Tk.__init__(self)

        self.player1 = 0
        self.player2 = 0
        self.bclick = True
        self.buttonCounter = 1
        self.win = 0
        self.lose = 0

        #make all of your stuff
        #notice ------------------v ~ the master of this button is now the root
        self.button1 = tk.Button(self, text=" ", height=4, width=10)
        #you should let it finish creating itself before you dump it in a lambda
        self.button1.configure(command=lambda: self.buttonClick(self.button1))
        self.button1.place(x=275, y=150)

        #etc....

    def buttonClick(self, button):
        if button["text"] == " " and self.bclick == True:
            button["text"] = "X"
            self.bclick = False
            self.isWinner()
            self.buttonCounter += 1
        elif button["text"] == " " and self.bclick == False:
            button["text"] = "O"
            self.bclick = True
            self.isWinner()
            self.buttonCounter += 1
        else:
            tk.messagebox.showinfo("Tic Tac Toe", "Button is clicked already!")

    def isWinner(self):
        print(self.button9['text'])


if "__main__" == __name__:
    app = App()
    app.title("Tic-Tac-Toe")
    app.mainloop()

您可以将其用作任何 OOP tkinter 应用程序的基本模板。

import tkinter as tk


class App(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)


if __name__ == "__main__":
    app = App()
    app.title("My Application")
    app.geometry('800x600')
    app.mainloop()           

【讨论】:

  • self.button1 = tk.Button(self.master, text=" ", command=lambda: self.buttonClick(button1), height=4, width=10) NameError: name 'button1'未定义它仍然返回错误
  • @AlexHu ~ 阅读我的编辑并相应地重组您的代码。我知道你是新人,事情很混乱,但你的出发点是错误的。
  • 谢谢!我是初学者,实际上需要时间来理解!但大有帮助!
  • @AlexHu ~ 我添加了一个编辑。阅读我帖子的最底部
  • @AlexHu - 如果你想看看在 tkinter 中使用 OOP 制作的全功能井字游戏是什么样的,请参阅下面的链接。我以一种易于理解的方式使用了一堆概念,可以帮助你变得更好。 stackoverflow.com/a/63149190/10292330
【解决方案2】:

您可以为 buttonClick 函数添加一个按钮传递

   def buttonClick(self, button):
    if button["text"] == " " and self.bclick == True:
        button["text"] = "X"
        self.bclick = False
        self.isWinner(button)
        self.buttonCounter += 1
    elif button["text"] == " " and self.bclick == False:
        button["text"] = "O"
        self.bclick = True
        self.isWinner(button)
        self.buttonCounter += 1
    else:
        tk.messagebox.showinfo("Tic Tac Toe", "Button is clicked already!")

您还可以将传递的按钮添加到 isWinner 函数中

def isWinner(self, button):

【讨论】:

  • 对不起,我没有明确我的问题,所以我有 9 个按钮,每次我在我创建的程序中单击一个按钮时,它都会添加一个“X”或一个“O” ”,三人一排将决出胜负,所以,我无法一一查看。这是一个井字游戏程序
  • 你能告诉我点击按钮时会发生什么
  • 它将在按钮上添加一个“X”或一个“O”。
  • 对不起,我要走了,我稍后再联系你
【解决方案3】:

为您的按钮定义一个子类,该子类定义了单击时要调用的方法。在ttt 中完成的大部分工作也可以委托给子类。子类的每个实例都保留一个对“容器”的引用(在本例中,是ttt 的一个实例)。

class ttt():
    master = 0
    player1 = 0
    player2 = 0
    bclick = True
    buttonCounter = 1
    win = 0
    lose = 0

    def boardDisplay(self):
        button1 = MyButton(self, x=275, y=150)
        button2 = MyButton(self, x=355, y=150)
        button3 = MyButton(self, x=435, y=150)
        button4 = MyButton(self, x=275, y=230)
        button5 = MyButton(self, x=355, y=230)
        button6 = MyButton(self, x=435, y=230)
        button7 = MyButton(self, x=275, y=310)
        button8 = MyButton(self, x=355, y=310)
        button9 = MyButton(self, x=435, y=310)


class MyButton(tk.Button):
    def __init__(self, container, x, y, h=4, w=10):
        super().__init__(container.master, " ", command=self.onClick, height=h, width=w)
        self.container = container
        self.place(x, y)

    def onClick(self):
        if self["text" != " ":
            tk.messagebox.showinfo("Tic Tac Toe", "Button is clicked already!")
        elif self.container.bclick:
            self["text"] = "X"
            self.container.bclick = False
            self.container.isWinner()
            self.container.buttonCounter += 1
        else:
            self["text"] = "O"
            self.container.bclick = True
            self.container.isWinner()
            self.container.buttonCounter += 1


            

【讨论】:

  • 我想知道我是否可以在一堂课上做到这一点,说实话,我是一个python初学者,我觉得你的代码很难理解,没有冒犯。根据我现在拥有的代码,有什么方法可以做到吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多