Tkinter功能范围问题

时间:2020-05-20 15:39:41

标签: python loops tkinter indexing

我正在tkinter中创建一个TicTacToe游戏,该游戏由一个由按钮组成的3x3网格组成。

在下面的代码中,一旦玩家在图块上绘制(单击按钮),程序便应从“ self.flattenedButtons”列表中删除该图块。这是为了防止计算机(玩家2)在同一图块上绘制。

进行此检查的方法是self.add_move()。这适用于除右下角以外的所有按钮,我认为这是因为我从结束范围中减去了1。如果我不这样做,则会收到“超出范围”错误。

我如何更改我的方法,使其适用于所有按钮?

代码:

from tkinter import *
from functools import partial
from itertools import *
import random

class Window(Frame):
    def __init__(self, master = None): # init Window class
        Frame.__init__(self, master) # init Frame class
        self.master = master # allows us to refer to root as master
        self.rows = 3
        self.columns = 3
        self.guiGrid = [[None for x in range(self.rows)] for y in range(self.columns)] # use this for the computer's moves
        self.buttonText = StringVar(value = '')
        self.buttonText2 = StringVar(value = 'X')
        self.buttonText3 = StringVar(value = 'O')
        self.button_ij = None
        self.flattenedButtons = []
        self.create_window()
        self.add_buttons()

    def create_window(self):
        self.master.title('Tic Tac Toe')
        self.pack(fill = BOTH, expand = 1)
        for i in range(0,3):
            self.grid_columnconfigure(i, weight = 1)
            self.grid_rowconfigure(i, weight = 1)


    def add_buttons(self): 
        rows = 3
        columns = 3

        for i in range (rows):
            for j in range(columns):
                self.button_ij = Button(self, textvariable = self.buttonText, command = lambda i=i, j=j: self.add_move(i,j))
                self.guiGrid[i][j] = self.button_ij # place button into 2d array to access later on
                self.flattenedButtons.append(self.button_ij)
                self.button_ij.grid(row = i,column = j, sticky =E+W+S+N)

    def add_move(self, i,j):
          pressedButton = self.guiGrid[i][j]
          self.guiGrid[i][j].config(textvariable =self.buttonText2)

          for i in range(0, len(self.flattenedButtons)-1):
              if (self.flattenedButtons[i] == pressedButton):
                  self.flattenedButtons.remove(self.flattenedButtons[i])
                  print('removed')
              else:
                  pass


root = Tk() # creating Tk instance

rootWidth = '500'
rootHeight = '500'
root.geometry(rootWidth+'x'+rootHeight)

ticTacToe = Window(root) # creating Window object with root as master

root.mainloop() # keeps program running

1 个答案:

答案 0 :(得分:2)

不建议在迭代列表时对其进行操作。 如果您的代码是:

          for i in range(0, len(self.flattenedButtons)-1):

              if (self.flattenedButtons[i] == pressedButton):
                  self.flattenedButtons.remove(self.flattenedButtons[i])
                  print('removed')
              else:
                  pass
          print(self.flattenedButtons)

您将看到按钮9永远不会被移除。

将for循环更改为简单的列表理解:

self.flattenedButtons = [i for i in self.flattenedButtons if i != pressedButton]
print(self.flattenedButtons)

您将看到更改。