【问题标题】:Tkinter function range issueTkinter 函数范围问题
【发布时间】:2020-05-20 15:39:41
【问题描述】:

我正在 tkinter 中创建一个井字游戏,由按钮组成的 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

【问题讨论】:

  • 我运行了您的代码,但无法重现您的问题。
  • 我编辑了代码以包含打印功能。当我运行代码并单击右下角的按钮时,未打印“已删除”,表明该功能在此按钮上不起作用。当我将第二个参数更改为 len(self.flattenedButtons) 时,我收到一个错误。

标签: python loops tkinter indexing


【解决方案1】:

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

          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)

你会看到变化。

【讨论】:

    猜你喜欢
    • 2011-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-25
    • 2016-12-20
    • 2016-03-04
    • 1970-01-01
    相关资源
    最近更新 更多