2011-11-17 87 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的回答正是你需要的。尽管如此,我希望自己有教育意义。 –