индекс вне диапазона со списком кнопок tkinter - PullRequest
0 голосов
/ 25 февраля 2019

Я пытаюсь адаптировать код, написанный на python, к программе, использующей tkinter.Я сделал список для каждого символа на доске (X и O) и список кнопок.каждая кнопка при нажатии должна обновлять свой текст с «» на «X» или «O» в зависимости от ситуации.Остальной код еще не создан, но это не проблема.

Я использую marcar(i,j,texto) в качестве функции для обновления текста кнопки, используя в качестве ссылки положение кнопки в списке кнопок.но в строке 25 появляется ошибка «индекс списка вне диапазона».Я использую ту же команду в строке 31. Я предполагаю, что это потому, что в строке 29, где я создаю кнопки, одной из вещей, используемых для их создания, является метод marcar(), и поскольку он еще не был создандругой в списке, я не могу сослаться на это.

Я не могу найти решения для создания кнопки, которая при нажатии использует метод, который ссылается на ту же кнопку, потому что для ее создания мне нужна функция.

from tkinter import *

lista = [[" ", " ", " "],
         [" ", " ", " "],
         [" ", " ", " "]]

buttons = [[], [], []]

vitx = 0
vito = 0

root = Tk()

turno = Label(root, text="Turno de X",font=("Arial",15))
turno.grid(row = 1,column = 1)

vitoriasx = Label(root, text="Vitórias de X:"+str(vitx), font=("Arial",8))
vitoriasx.grid(row = 1,column = 0)

vitoriaso = Label(root, text="Vitórias de O:"+str(vito), font=("Arial",8))
vitoriaso.grid(row = 1,column = 2)

def marcar(i,j,texto):
    lista[i][j] = texto
    buttons[i][j].config(text= texto)

for i in range(0,3):
    for j in range(0,3):
        buttons[i].append(Button(root,text=lista[i][j],command = marcar(i,j,"x")))
        buttons[i][j].grid(row = i+2,column = j)
        buttons[i][j].config(height=6, width=13)


root.mainloop()

Ответы [ 2 ]

0 голосов
/ 25 февраля 2019

Вам необходимо создать правильную лямбда-функцию для этого набора циклов, чтобы кнопки отправляли правильную информацию в функцию и не заставляли команду выполняться при инициализации.

В python, когда вам нужночтобы сохранить ссылку на функцию, у вас есть 2 варианта.

Для функций, которые не принимают аргументов, вы можете оставить скобку (), чтобы сохранить ссылку на функцию или, если вам нужно передать аргументы, вы можетеиспользуйте лямбда-выражение.

Если вы используете лямбда-выражение и у вас есть переменные в вашем цикле, как вы делаете здесь, тогда вам нужно определить, что является каждым аргументом для цикла, иначе все эти значения будут равнысамые последние значения циклов.

Например, если вы просто используете лямбду, не определяя переменные в каждом цикле, вы получите кнопки, которые отправляют одни и те же данные.

Вот пример:

import tkinter as tk


root = tk.Tk()

def marcar(i, j, texto):
    print(i, j, texto)

for i in range(0, 3):
    for j in range(0, 3):
        tk.Button(root, text='button {}.{}'.format(i, j), command=lambda: marcar(i, j, "x")).grid(row=i, column=j)

root.mainloop()

Результаты:

enter image description here

Однако если выУточняя значения в лямбда-выражении каждого цикла, вы получите правильные значения для каждой кнопки.

Пример:

import tkinter as tk


root = tk.Tk()

def marcar(i, j, texto):
    print(i, j, texto)

for i in range(0, 3):
    for j in range(0, 3):
        tk.Button(root, text='button {}.{}'.format(i, j), command=lambda i=i, j=j: marcar(i, j, "x")).grid(row=i, column=j)

root.mainloop()

Результаты:

enter image description here

0 голосов
/ 25 февраля 2019

Проблема в том, что вы не можете передавать аргументы в command, как это.Вы должны изменить command=marcar(i,j,"x") на command=lambda: marcar(i, j, "x").Пояснения вы можете найти здесь и здесь .Попробуйте следующий код:

from tkinter import *

lista = [[" ", " ", " "],
         [" ", " ", " "],
         [" ", " ", " "]]

buttons = [[], [], []]

vitx = 0
vito = 0

root = Tk()

turno = Label(root, text="Turno de X", font=("Arial", 15))
turno.grid(row=1, column=1)

vitoriasx = Label(root, text="Vitórias de X:"+str(vitx), font=("Arial", 8))
vitoriasx.grid(row=1, column=0)

vitoriaso = Label(root, text="Vitórias de O:"+str(vito), font=("Arial", 8))
vitoriaso.grid(row=1, column=2)

def marcar(i, j, texto):
    lista[i][j] = texto
    buttons[i][j].config(text=texto)

for i in range(0, 3):
    for j in range(0, 3):
        buttons[i].append(Button(root, text=lista[i][j], command=lambda: marcar(i, j, "x")))
        buttons[i][j].grid(row=i+2, column=j)
        buttons[i][j].config(height=6, width=13)

root.mainloop()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...