Python buttons targeting

时间:2019-03-19 14:41:57

标签: python tkinter

I am trying to create a function that auto creates buttons. This i have done easily, but how do i create these buttons in a loop that have a special name for when a button is clicked the function knows what button is clicked and can change the TEST of that buttons? I've put thus far

from tkinter import Tk, Label, Button
import random as rdn

x_user = 'X'
o_user = 'O'

window = Tk()
window.resizable(False, False)

def button_pressed():
    Button = 'Test'

for rows in range(3):
    button_number = 1
    for colums in range(3):
        Button (window, text='-', width='5', height='5', command=button_pressed) .grid(row=rows, column=colums)
        button_number += 1

window.mainloop()

2 个答案:

答案 0 :(得分:0)

I would say this is the limitation of tkinter that when the button is pressed, the function it executes will give you no clue what caused it.

However, in Python, you can generate a function on the fly to work around such limitation. My example is as follows:

def sayit(s):
    def f():
        print("Button %s is pressed" % s)
    return f

for rows in range(3):
    button_number = 1
    for colums in range(3):
        Button (window, text='-', width='5', height='5', command=sayit(button_number)) .grid(row=rows, column=colums)
        button_number += 1

The sayit() function accepts one parameter and returns a function which takes no argument. When I create a button, I assign this generated-on-the-fly function as the command.

If you want to make this a tic-tac-toe game, you need also to have something to hold all button text and associate with your button number (e.g., a list) so that you can reset the text of each button when clicked. Like below:

from tkinter import Tk, Label, Button, StringVar
import random as rdn

x_user = 'X'
o_user = 'O'
who = 'X'

window = Tk()
window.resizable(False, False)

def click(n):
    def f():
        global who
        buttons[n].set(who)
        who = 'O' if who == 'X' else 'X'
    return f

buttons = []
button_number = 0
for rows in range(3):
    for colums in range(3):
        s = StringVar()
        s.set("-")
        buttons.append(s)
        Button(window, textvariable=s, width='5', height='5', command=click(button_number)).grid(row=rows, column=colums)
        button_number += 1

window.mainloop()

答案 1 :(得分:0)

最简单的方法是重新定义函数button_pressed()来接受一个参数,该参数是被单击的按钮。然后将按钮的command选项设置为lambda函数,在该函数中以按钮本身作为函数参数调用button_pressed()。下面是示例代码:

from tkinter import *

window = Tk()
window.resizable(False, False)

marks = ['X', 'O']
colors = ['red', 'green']
player = 0

def button_pressed(btn):
    global player
    # change the button text and make it not clickable
    btn.config(text=marks[player], disabledforeground=colors[player], state='disabled')
    player = 1 - player # change player

for row in range(3):
    for col in range(3):
        btn = Button(window, text='', font=('', 24, 'bold'), width=3)
        btn.config(command=lambda b=btn: button_pressed(b))
        btn.grid(row=row, column=col)

window.mainloop()