2014-05-11 103 views
0

我正在創建一個基本的搖滾紙剪刀遊戲來熟悉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設計來實現?

回答

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

  • 繼承我們得到了所有從Tk的方法,含。 mainloop

使用桂__init__構造

首先,我們要求我們的父類的初始化,這是Tkinter.Tk。 init(self)

然後我們把前面的root稱爲self

添加邏輯桂

Logic實現爲獨立的階級,它知道注意到對前端,只希望調用它的方法。

我們事先實例化logic並將它傳遞給Gui構造。

必須有一個契約,邏輯將提供什麼方法​​和屬性。

從桂

使用邏輯

當桂發現,有一些邏輯相關的事件,它可以調用的logic方法。

邏輯改變後,經常需要(用桂方法)重新渲染一些東西。

啓動了

這應是行話遵循:

  1. 實例化邏輯
  2. 創建圖形用戶界面,通過該邏輯
  3. 讓它運行

翻譯到Python:

logic = GameLogic() 
game = Gui(logic) 
game.mainloop() 
+0

我從你的答案中得到了一些想法,但仍然這樣,邏輯代碼將在名爲Gui的類中定義。這是我試圖避免的事情之一。 – Innkeeper

+0

@Innkeeper我會嘗試通過使用Mixins來解決它 –

+0

@Innkeeper我沒有通過mixins(運行到無窮循環)來管理它,但通過將'logic'對象傳遞給Gui構造函數來管理它。這可能會更容易閱讀mixin。 –