我试图了解Python类如何工作以能够遵循OOP的四个支柱。
我正在尝试设置一个Controller类,该类将设置一些UI类并响应输入。当前,Controller类初始化一个框架,该框架初始化一些Button。控制器将click(x,y)函数传递给UI类以监听点击。该部分目前正在运行,但我似乎无法弄清楚控制器类如何访问其子类以对UI进行更改。
这是我到目前为止获得的代码。我的问题是Controller中的Click(x,y)函数似乎找不到在 main 中创建的“游戏”对象。
Controller.py:
from GameButtons import GameButtons
from tkinter import *
class GameFrame(object):
global gameButtons
def __init__(self, params, click):
frame = Tk()
gameButtons= GameButtons(frame,click)
frame.mainloop()
def changeColor(self, x, y):
gameButtons.buttons[x][y].configure(bg = "green")
GameFrame.py:
from tkinter import *
class GameButtons(object):
global buttons
buttons = [[0 for x in range(8)]for x in range(8)]
def __init__(self, frame, click):
for x in range(8):
for y in range(8):
b = Button(frame, text = " x ", command = lambda row = x, col = y: click(row, col))
b.grid(row = x, column = y)
global buttons
buttons[x][y] = b
GameButtons.py:
{{1}}
单击按钮正确地从click(x,y)函数输出行/列,但随后给我一个NameError:尝试运行game.changeColor(x,y)时未定义名称“ game”
将非常感谢您为解决此问题提供的任何帮助,或者对我为什么要实现的目标一开始是一个坏主意的任何解释。
答案 0 :(得分:1)
问题在于,您永远不会给GameFrame
一个完成初始化的机会,因为mainloop
在窗口被销毁之前不会返回。因此,由于初始化从未完成,game
没有正确初始化。
简单的解决方法是将调用移至初始化函数之外的mainloop
,以便可以正确地初始化对象。您的主要代码应如下所示:
if __name__ == '__main__':
game = GameFrame("title", click)
game.start()
然后,您需要在start
中定义一个GameFrame
方法。这将要求您拥有对根窗口的引用。我会这样写:
class GameFrame(object):
def __init__(self, params, click):
self.root = Tk()
gameButtons = GameButtons(self.root, click)
def start(self):
self.root.mainloop()
注意:如果您的目标是真正的面向对象,则需要删除对全局变量的依赖。
这是您的代码,因此它不使用全局变量,除了game
本身就是全局性的:
from tkinter import *
class GameButtons(object):
def __init__(self, frame, click):
self.buttons = [[None for x in range(8)] for x in range(8)]
for x in range(8):
for y in range(8):
b = Button(frame, text = " x ", command = lambda row = x, col = y: click(row, col))
self.buttons[x][y] = b
b.grid(row = x, column = y)
class GameFrame(object):
def __init__(self, params, click):
self.root = Tk()
self.gameButtons= GameButtons(self.root,click)
def changeColor(self, x, y):
self.gameButtons.buttons[x][y].configure(bg = "green")
def start(self):
self.root.mainloop()
def click(x, y):
print("%s %s" %(x,y))
game.changeColor(x, y)
if __name__ == '__main__':
game = GameFrame("title", click)
game.start()