2011-11-17 85 views
1

我正在嘗試使用python 3和tkinter製作記憶遊戲。我是python的新手,所以這很難。我的問題是,我試圖從「Memory」類的「Cell」類中調用方法「show_word」,但我不知道如何去做。Python中的記憶遊戲與Tkinter

記憶遊戲:

def create_widgets(self): 
     """ Create widgets to display the Memory game """ 
     # buttons to show the words 
     column = 0 
     row = 1 
     the_pairs = self.readShuffle() 
     for index in range(36): 
      Button(self, 
        text = "hidden", 
        width = "7", 
        height = "2", 
        relief = GROOVE, 
        command = WHAT SHOULD I WRITE HERE??? 
        ).grid(row = row, column = column, padx = 1, pady = 1) 

      column += 1 
      if column == 6: 
       column = 0 
       row += 1 
+0

那麼,究竟何時/在什麼條件下你想調用'show_word'?此外,請刪除與您的問題無關的部分代碼(未來,請不要一次性編寫太多代碼 - 先做一件小事,然後逐步構建)。 –

+0

亞馬遜,我發佈了修復的'show_word'版本,以防萬一。 – senderle

回答

3

你已經運行到一個微妙的範圍界定問題。當您創建一個引用來自包含範圍的變量的函數時,這些變量的值在函數定義時並不固定,但在函數執行時爲。換句話說,當你這樣做:

command = lambda: print(index) 

你告訴Python來打印任何的index當函數被調用。通過用戶按下這些按鈕中的一個,引起功能被稱爲時間,index值是35

要在功能定義的時間修正值,你必須使用默認值,比如所以:

command = lambda x=index: print(x) 

我敢肯定,你可以計算出相應的show_word修復,但以防萬一:

command = lambda x=index: Cell.show_word(the_pairs[x]) 
+0

還有其他方法可以解決這個問題,但當然沒有一個優雅。無論如何,他似乎想在這裏使用'show_cell'方法,所以你也應該顯示。 –

0

我需要一個答案對我的評論之前,我可以幫你directl y,但是與此同時,這裏提供了一些更優雅地編寫代碼的提示:

from tkinter import * 
# `tkinter` is meant to be used that way, but `random` isn't really - the names 
# can be confusing without an explicit module reference. So instead: 
import random 

class Cell: 
    def __init__(self, word, hidden): 
     self.word = word 
     self.hidden = hidden 

    def show_word(self): 
     """ Shows the word behind the cell """ 
     self.hidden = not self.hidden 
     # no need to take this logic apart into cases 
     self.button.set(str(self)) 

    def __str__(self): 
     """ Displays or hides the word """ 
     # A simpler form of conditional; also, don't compare things 
     # explicitly to True or False 
     return "---" if self.hidden else self.word 

class Memory(Frame): 
    """ GUI application that creates a Memory game """ 
    def __init__(self, master): 
     super(Memory, self).__init__(master) 
     self.grid() 
     self.create_widgets() 
     self.tries = 0 

    def readShuffle(self): 
     """ Creates and organizes (shuffles) the pairs in a list """ 
     # The modern idiom for handling files and ensuring they are closed 
     with open("memo.txt","r") as words_file: 
      # The file can be iterated over directly, and is treated as 
      # a list of lines. Since we just want all the rstrip()ped 
      # lines, we can do the file processing all at once with a list 
      # comprehension. 
      # Let's also grab 18 random words while we're at it. We don't 
      # really want to *shuffle* the words, but instead *sample* them - 
      # we don't care about the words that we didn't select. 
      words = random.sample(
       [line.rstrip('\n') for line in words_file], 18 
      ) 

     # Instead of making 18 pairs of cells, we can make 18 cells and then 
     # pair them up. The set of 18 cells can also be made easily with a 
     # list comprehension. Notice how we get to iterate directly now, 
     # instead of messing around with indices into lists. 
     the_pairs = [Cell(word, True) for word in words] * 2 
     shuffle(the_pairs) 
     return the_pairs 

    def create_widgets(self): 
     """ Creates widgets to display the Memory game """ 
     # instruction text 
     Label(self, 
       text = "- The Memory Game -", 
       font = ("Helvetica", 12, "bold"), 
      ).grid(row = 0, column = 0, columnspan = 7) 

     # buttons to show the words 
     the_pairs = self.readShuffle() 
     self.buttons = [] 
     # Again, we can iterate in a more Pythonic way. 
     for i, pair in enumerate(the_pairs): 
      # Instead of having extra counters to work out the row and column, 
      # we can simply do math on the index value. 
      column, row = i % 6, i // 6 
      temp = StringVar() 
      temp.set(str(pair)) 
      # Instead of adding the button to a list and then reaching into the 
      # list to configure it, get everything set up first. 
      button = Button(self, 
        textvariable = temp, 
        width = "7", 
        height = "2", 
        relief = GROOVE, 
        command = lambda: print(index) 
        )) 
      button.grid(row = row, column = column, padx = 1, pady = 1) 
      buttons.append(button) 
      pair.button = temp 

     # total tries 
     self.label = Label(self) # Don't abbreviate! 
     Label(self, 
       text = "Total tries: 0", 
       font = ("Helvetica", 11, "italic") 
      ).grid(row = 7, columnspan = 7, pady = 5) 

     # ... 
+0

呃。我最終明白了你的意思,而senderle的回答正是你需要的。儘管如此,我希望自己有教育意義。 –