【问题标题】:Something wrong without any error - Includes Tkinter没有任何错误的错误 - 包括 Tkinter
【发布时间】:2011-11-26 15:38:37
【问题描述】:

我没有收到任何错误,但代码没有按照我的意愿执行,因此代码中一定有我犯了错误的地方。我想要做的是,如果单词匹配,那么单词必须是一对,并且两个选择的单元格应保持“self.hidden = False”,因此单元格仍应显示两个单元格后面的单词。否则,如果单词不匹配,则单元格应为“self.hidden = True”,两个单元格应显示“---”。

以下是重要部分:

from tkinter import *
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 """
        if self.hidden == True:
            self.hidden = False
        else:
            self.hidden = True

        self.button["text"] = str(self)

        if mem.choice1 == None:
            mem.choice1 = [self.word, self.hidden]
        else:
            mem.choice2 = [self.word, self.hidden]
            self.check(mem.choice1, mem.choice2)

    def check(self, choice1, choice2):
        """ Checks if the chosen words are a pair """
        tries = 0
        if choice1 == choice2:
            pass
        else:
            self.show_word

        tries += 1

    def __str__(self):
        """ Displays or hides the word """
        if self.hidden == True:
            return "---"
        else:
            return 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
        self.choice1 = None
        self.choice2 = None

    def readShuffle(self):
        """ Creates and organizes (shuffles) the pairs in a list """
        # reads the file and creates a list of the words
        words_file = open("memo.txt","r")
        row = words_file.readline()
        words = list()
        while row != "":
            row = row.rstrip('\n')
            words.append(row)
            row = words_file.readline()
        words_file.close()

        # shuffles the words in the list
        random.shuffle(words)

        # creates 18 pairs of words in a new list
        the_pairs = list()
        for i in range(18):
            the_pairs.append(Cell(words[i],True))
            the_pairs.append(Cell(words[i],True))

        # shuffles the words in the new list
        random.shuffle(the_pairs)

        return the_pairs

    def create_widgets(self):
        """ Create 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
        column = 0
        row = 1
        the_pairs = self.readShuffle()
        for index in range(36):
            temp = Button(self,
                   text = the_pairs[index],
                   width = "7",
                   height = "2",
                   relief = GROOVE,
                   command = lambda x = index: Cell.show_word(the_pairs[x])
                   )
            temp.grid(row = row, column = column, padx = 1, pady = 1)
            column += 1
            the_pairs[index].button = temp
            if column == 6:
                column = 0
                row += 1

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

        # a quit button
        Button(self,
               text = "Quit",
               font = ("Helvetica", 10, "bold"),
               width = "25",
               height = "1",
               command = self.quit
               ).grid(row = 8, column = 0, columnspan = 7, pady = 5)

##    def update_tries(self):
##        """ Increase tries count and display new total. """
##        self.tries += 1
##        self.label["text"] = "Total Tries: " + str(self.tries)

    def quit(self):
        """ Ends the memory game """
        global root
        root.destroy()

# main
root = Tk()
root.title("Memory")
root.geometry("365x355")
mem = Memory(root)
root.mainloop()

【问题讨论】:

  • 我是 python 新手,所以我不知道你所说的“初始化”是什么意思。我不是在这里做的吗? def __init__(self, word, hidden): self.word = word self.hidden = hidden
  • 如果你要让别人为你调试你的代码,那么至少让它成为一个独立的例子。 “重要位”遗漏了许多其他重要位。您正在做很多没有意义的事情(例如,Cell.check 中的 tries始终0。)您还有 很多多余的 if/else 语句。 (例如,Cell.show_word 中的第一个 if/else 等效于 self.hidden = not self.hidden 并且整个 Cell.check 函数根本没有意义。)
  • 我当然会犯很多错误,因为我是 python 新手。如果我在代码中的某个地方想错了,我希望 ppl 能帮助我。
  • 寻求帮助是可以的,但是当您的代码引用了很多未在您发布的代码 sn-p 中定义的内容时,很难遵循您的思路。调试一个没有足够信息运行的 sn-p 本身就更难了。
  • 我现在已经编辑了我的帖子,所以你可以运行代码。问题是 ppl 之前告诉过我,我不应该发布程序的整个代码,而应该只发布重要的部分。

标签: python python-3.x tkinter


【解决方案1】:

直接的问题是您没有在Cell.check 的第136 行调用self.show_word

def check(self, choice1, choice2):
    """ Checks if the chosen words are a pair """
    tries = 0
    if choice1 == choice2:
        pass
    else:
        self.show_word

    tries += 1

(您也应该在这里只使用!=,而不是在您的if 子句中使用pass 语句。此外,tries 在这里没有做任何事情... )

但是,即使你调用它(即self.show_word() 而不是self.show_word),你也会遇到更大的问题,因为一旦你调用的单词不一样,你就会设置一个无限循环。

check 将调用 show_word,然后再调用 check 等等。

您需要做的是在Cell.check 中的else 语句中重置choice1choice2 以及它们各自的按钮。

但是,要执行此操作,您需要有权访问相关单元格对象。实际上,您只传递它们的文本值以及它们是否被隐藏。

快速解决方法是传递单元格对象本身。

不过,首先,让我们稍微清理一下你的函数......你有这个:

def show_word(self):
    """ Shows the word behind the cell """
    if self.hidden == True:
        self.hidden = False
    else:
        self.hidden = True

    self.button["text"] = str(self)

    if mem.choice1 == None:
        mem.choice1 = [self.word, self.hidden]
    else:
        mem.choice2 = [self.word, self.hidden]
        self.check(mem.choice1, mem.choice2)

def check(self, choice1, choice2):
    """ Checks if the chosen words are a pair """
    tries = 0
    if choice1 == choice2:
        pass
    else:
        self.show_word

    tries += 1

这相当于:

def show_word(self):
    """ Shows the word behind the cell """
    self.hidden = not self.hidden
    self.button["text"] = str(self)

    if mem.choice1 is None:
        mem.choice1 = [self.word, self.hidden]
    else:
        mem.choice2 = [self.word, self.hidden]
        self.check(mem.choice1, mem.choice2)

def check(self, choice1, choice2):
    """ Checks if the chosen words are a pair """
    if choice1 != choice2:
        self.show_word() # Infinite recursion!!

现在,让我们传递 Cell 实例本身,以便我们可以重置它们的显示值。

def show_word(self):
    """ Shows the word behind the cell """
    self.hidden = not self.hidden
    self.button["text"] = str(self)

    if mem.choice1 is None:
        mem.choice1 = self
    else:
        mem.choice2 = self
        self.check(mem.choice1, mem.choice2)

def check(self, choice1, choice2):
    """ Checks if the chosen words are a pair """
    mem.choice1, mem.choice2 = None, None
    if choice1.word != choice2.word:
        for cell in (choice1, choice2):
            cell.hidden = True
            cell.button['text'] = str(cell)

现在,一切都会如您所愿。但是,如果第二个选项与第一个选项不匹配,则永远不会显示第二个选项。 (事实上​​,我们可以在这个版本中完全删除mem.choice2 属性。)

因此,我们只在第三次点击时重置这两个值,如果它们不匹配的话。

def show_word(self):
    """ Shows the word behind the cell """
    self.hidden = not self.hidden
    self.button["text"] = str(self)

    if mem.choice1 is None:
        mem.choice1 = self
    elif mem.choice2 is None:
        mem.choice2 = self
    else:
        choice1, choice2 = mem.choice1, mem.choice2
        mem.choice1, mem.choice2 = self, None
        self.check(choice1, choice2)

def check(self, choice1, choice2):
    """ Checks if the chosen words are a pair """
    if choice1.word != choice2.word:
        for cell in (choice1, choice2):
            cell.hidden = True
            cell.button['text'] = str(cell)

现在,事情或多或少会按照你的意愿行事。

from tkinter import *
import random

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

    def show_word(self):
        """ Shows the word behind the cell """
        self.hidden = not self.hidden
        self.button["text"] = str(self)

        if mem.choice1 is None:
            mem.choice1 = self
        elif mem.choice2 is None:
            mem.choice2 = self
        else:
            choice1, choice2 = mem.choice1, mem.choice2
            mem.choice1, mem.choice2 = self, None
            self.check(choice1, choice2)

    def check(self, choice1, choice2):
        """ Checks if the chosen words are a pair """
        if choice1.word != choice2.word:
            for cell in (choice1, choice2):
                cell.hidden = True
                cell.button['text'] = str(cell)

    def __str__(self):
        """ Displays or hides the word """
        if self.hidden == True:
            return "---"
        else:
            return 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
        self.choice1 = None
        self.choice2 = None

    def readShuffle(self):
        """ Creates and organizes (shuffles) the pairs in a list """
        # reads a list of words from the file
        with open('memo.txt', 'r') as infile:
            words = [line.strip() for line in infile]

        # creates 18 pairs of words in a new list
        the_pairs = list()
        for i in range(18):
            the_pairs.extend([Cell(words[i]), Cell(words[i])])

        # shuffles the words in the new list
        random.shuffle(the_pairs)

        return the_pairs

    def create_widgets(self):
        """ Create 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
        column = 0
        row = 1
        the_pairs = self.readShuffle()
        for index in range(36):
            temp = Button(self,
                   text = the_pairs[index],
                   width = "7",
                   height = "2",
                   relief = GROOVE,
                   command = the_pairs[index].show_word
                   )
            temp.grid(row = row, column = column, padx = 1, pady = 1)
            column += 1
            the_pairs[index].button = temp
            if column == 6:
                column = 0
                row += 1

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

        # a quit button
        Button(self,
               text = "Quit",
               font = ("Helvetica", 10, "bold"),
               width = "25",
               height = "1",
               command = self.quit
               ).grid(row = 8, column = 0, columnspan = 7, pady = 5)


    def quit(self):
        """ Ends the memory game """
        global root
        root.destroy()

# main
root = Tk()
root.title("Memory")
root.geometry("365x355")
mem = Memory(root)
root.mainloop()

但是,您仍然可以进行大量清理和重构。让Memory 类句柄检查点击等会更有意义。另外,看看新的readShuffle 函数。您正在以一种惊人复杂的方式阅读文件。您可能应该阅读一些在 python 中使用文件的基本示例。它比您想象的要简单得多

【讨论】:

  • 感谢您的宝贵时间。现在一切都变得更有意义了:)
  • 有一个错误。当你按下一个已经选择的单元格时,单元格会被隐藏,我希望它保持不隐藏。我怀疑self.hidden = not self.hidden 行与它有关。我尝试了不同的方法来更改self.hidden = not self.hidden,但我似乎无法让它正常工作。
  • 这不是错误。这是当前代码的故意设计。这正是你最初让它做的事情。如果您希望它保持可见,则需要设置某种标志(例如cell.frozen = True),然后在更改cell.hidden 时检查该标志。例如。 self.hidden = not self.hidden if not cell.frozen else True(尽管此时使用多行 if 语句变得更具可读性。)
  • 我是 python 新手,所以我没有 100% 理解你。我试图将self.hidden = not self.hidden 更改为if self.hidden: self.hidden = False else: self.hidden = False。但这只是有时有效,而且细胞的行为非常奇怪。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-01-24
  • 2016-09-05
  • 1970-01-01
  • 2020-05-17
  • 2020-11-24
  • 2013-10-21
  • 2011-08-27
相关资源
最近更新 更多