Невозможно изменить цвет кнопки, нажав на нее, каждая кнопка была создана функцией - PullRequest
0 голосов
/ 18 октября 2019

Мы хотим изменить цвет кнопки при нажатии, но проблема в том, что она меняет цвет только последней кнопки, потому что мы создали их все с помощью функции. Вопрос будет в том, есть ли возможность решить эту проблему?

from tkinter import *

main = Tk()
main.title("HANGMAN")
main.configure(width="800", height="400")
main.geometry("800x800")

def check(Event):
    lbutton.config(state="disabled", background="red")

def letter(x, gc, gr):
    global lbutton
    c = "lightblue"
    lbutton = Button(frame2, text = x, width="3", height="2", bg=c, activebackground="lightblue")
    lbutton.grid(row=gr,column=gc)
    return lbutton

main.resizable(FALSE,FALSE)
frame1 = Frame(main, width="600",height="600")
frame1.grid(row=0, sticky=E)
frame2 = Frame(main,bg="grey",width="200")
frame2.grid(row=1, sticky=E)

letter("A", 1, 0).bind("<ButtonRelease-1>", check)
letter("B", 2, 0).bind("<ButtonRelease-1>", check)
letter("C", 3, 0).bind("<ButtonRelease-1>", check)
letter("D", 4, 0).bind("<ButtonRelease-1>", check)
letter("E", 5, 0).bind("<ButtonRelease-1>", check)
letter("F", 6, 0).bind("<ButtonRelease-1>", check)
letter("G", 7, 0).bind("<ButtonRelease-1>", check)
letter("H", 8, 0).bind("<ButtonRelease-1>", check)
letter("I", 9, 0).bind("<ButtonRelease-1>", check)
letter("J", 10, 0).bind("<ButtonRelease-1>", check)
letter("K", 11, 0).bind("<ButtonRelease-1>", check)
letter("L", 12, 0).bind("<ButtonRelease-1>", check)
letter("M", 13, 0).bind("<ButtonRelease-1>", check)
letter("N", 1, 1).bind("<ButtonRelease-1>", check)
letter("O", 2, 1).bind("<ButtonRelease-1>", check)
letter("P", 3, 1).bind("<ButtonRelease-1>", check)
letter("Q", 4, 1).bind("<ButtonRelease-1>", check)
letter("R", 5, 1).bind("<ButtonRelease-1>", check)
letter("S", 6, 1).bind("<ButtonRelease-1>", check)
letter("T", 7, 1).bind("<ButtonRelease-1>", check)
letter("U", 8, 1).bind("<ButtonRelease-1>", check)
letter("V", 9, 1).bind("<ButtonRelease-1>", check)
letter("W", 10, 1).bind("<ButtonRelease-1>", check)
letter("X", 11, 1).bind("<ButtonRelease-1>", check)
letter("Y", 12, 1).bind("<ButtonRelease-1>", check)
letter("Z", 13, 1).bind("<ButtonRelease-1>", check)

main.mainloop()

Мы не можем решить эту проблему, потому что такой информации в Интернете нет. Будем признательны, если вы поможете нам.

Ответы [ 2 ]

1 голос
/ 18 октября 2019

Ваша функция letter() назначает каждой кнопке одно и то же имя переменной, поэтому, естественно, последняя назначенная кнопка будет единственной, которую можно редактировать, поскольку все предыдущие назначения были перезаписаны.

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

Работая со списком для непосредственного редактирования кнопки, мы также можем работать с буквойвыбирается путем ссылки на кнопки ['text'] в той же функции check, а затем поработаем с этой буквой для вашей игры палача.

Обратите внимание, что приведенный ниже код примерно на 20 строк короче вашего кода, потому что нам удаетсяbind или command внутри цикла вместо строки за строкой. Это достигается путем простого перебора строки алфавита в верхнем регистре и использования enumerate для получения значения индекса списка, которое может напрямую переводиться в тот же индекс списка, который использовался для хранения кнопок.

import tkinter as tk


root = tk.Tk()
btn_list = []
root.title("HANGMAN")
root.geometry("800x800")


def check(ndex):
    # Index used to work with the button directly in list
    btn_list[ndex].config(state="disabled", background="red")
    # example to show we can get the letter from the buttons text field.
    print(btn_list[ndex]['text'])


def create_buttons():
    row = 0  # tracking the row for our grid statement
    col = 1  # tracking the column for our grid statement
    for ndex, char in enumerate('ABCDEFGHIJKLMNOPQRSTUVWXYZ'):
        btn_list.append(tk.Button(frame2, text=char, width="3", height="2", bg="lightblue",
                                  activebackground="lightblue", command=lambda ndex=ndex: check(ndex)))
        btn_list[-1].grid(row=row, column=col)
        # Simple math to manage button placement for row and column
        if col <= 12:
            col += 1
        else:
            col = 1
            row += 1


frame1 = tk.Frame(root, width="600", height="600")
frame2 = tk.Frame(root, bg="grey", width="200")
frame1.grid(row=0, sticky='e')
frame2.grid(row=1, sticky='e')
create_buttons()
root.resizable(False, False)
root.mainloop()

Результаты:

enter image description here

1 голос
/ 18 октября 2019

Самое простое решение - использовать event.widget в своей функции check вместо:

def check(event):
    event.widget.config(state="disabled", background="red")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...