我正在创建一个基本的石头剪刀游戏,以熟悉python和tkinter。我想创建一个gui和一个逻辑类来分隔两者。但是,我似乎无法找到一个在python中都有效且对我有意义的代码布局。
我希望Gui
类只知道小部件并更新它们。
class Gui:
def setup(self):
root = Tk.Tk()
root.geometry("370x170")
root.resizable(width=False, height=False)
root.title("Rock, Paper, Scissors")
root.iconbitmap("Play.ico")
rock_button = Tk.Button(root, text="Rock", command=rock_clicked)
rock_button.place(width=100, height=30, x=10, y=30)
paper_button = Tk.Button(root, text="Paper", command=paper_clicked)
paper_button.place(width=100, height=30, x=10, y=70)
scissors_button = Tk.Button(root, text="Scissors", command=scissors_clicked)
scissors_button.place(width=100, height=30, x=10, y=110)
score_font = font.Font(family="Helvetica", size=20)
own_score_lbl = Tk.Label(root, text="0", relief=Tk.RIDGE, font=score_font)
own_score_lbl.place(width=50, height=110, x=120, y=30)
ai_score_lbl = Tk.Label(root, text="0", relief=Tk.RIDGE, font=score_font)
ai_score_lbl.place(width=50, height=110, x=200, y=30)
ai_choice = Tk.Label(root, relief=Tk.RIDGE)
ai_choice.place(width=100, height=110, x=260, y=30)
root.mainloop()
gui = Gui()
gui.setup()
在其他语言中,我习惯在gui类中使用逻辑成员变量,反之亦然。这在这里不起作用。由于self
参数,单击处理程序函数不能是逻辑类的成员。所以我试着将它们声明为模块级,并从那些中调用逻辑类的方法,这些方法也没有用。
理想情况下,在单击事件之后,我会期望调用逻辑类方法,然后进行计算,并调用适当的gui方法,即set_label_text()
。
如何通过OO设计实现这一目标?
答案 0 :(得分:2)
我绝对不是Tkinter专家,这是我的第一个Tkinter应用程序。
但是我的建议是如何使用Python类继承来组织您的解决方案。
代码运行
import Tkinter
import tkFont as font
class Gui(Tkinter.Tk):
def __init__(self, logic):
Tkinter.Tk.__init__(self)
self.logic = logic
self.geometry("370x170")
self.resizable(width=False, height=False)
rock_button = Tkinter.Button(self, text="Rock", command=self.rock_clicked)
rock_button.place(width=100, height=30, x=10, y=30)
paper_button = Tkinter.Button(self, text="Paper", command=self.paper_clicked)
paper_button.place(width=100, height=30, x=10, y=70)
scissors_button = Tkinter.Button(self, text="Scissors", command=self.scissors_clicked)
scissors_button.place(width=100, height=30, x=10, y=110)
score_font = font.Font(family="Helvetica", size=20)
own_score_lbl = Tkinter.Label(self, text="0", relief=Tkinter.RIDGE, font=score_font)
own_score_lbl.place(width=50, height=110, x=120, y=30)
ai_score_lbl = Tkinter.Label(self, text="0", relief=Tkinter.RIDGE, font=score_font)
ai_score_lbl.place(width=50, height=110, x=200, y=30)
ai_choice = Tkinter.Label(self, relief=Tkinter.RIDGE)
ai_choice.place(width=100, height=110, x=260, y=30)
self.render_title()
def render_title(self):
logic = self.logic
templ = "Rock({logic.rock_counter}), Paper({logic.paper_counter}), Scissors({logic.scissors_counter})"
title = templ.format(logic=logic)
self.title(title)
def rock_clicked(self):
self.logic.play_rock()
self.render_title()
def paper_clicked(self):
self.logic.play_paper()
self.render_title()
def scissors_clicked(self):
self.logic.play_scissors()
self.render_title()
class GameLogic():
def __init__(self):
self.rock_counter = 0
self.paper_counter = 0
self.scissors_counter = 0
def play_rock(self):
self.rock_counter += 1
def play_paper(self):
self.paper_counter += 1
def play_scissors(self):
self.scissors_counter += 1
logic = GameLogic()
game = Gui(logic)
game.mainloop()
Tkinter.Tk
mainloop
__init__
构造函数首先,我们要求我们的父类初始化,这是Tkinter.Tk。 init (self)
然后我们将之前的root
称为self
。
Logic
作为独立类实现,它知道前端的注意事项,它只需要调用它的方法。
我们提前实例化logic
并将其传递给Gui constructore。
必须有合同,Logic将提供哪些方法和属性。
当Gui发现时,有一些与逻辑相关的事件,它可以调用logic
的方法。
在更改逻辑之后,经常需要(使用Gui方法)重新渲染。
这应该是下面的模式:
翻译成Python:
logic = GameLogic()
game = Gui(logic)
game.mainloop()