0
votes

I am attempting to work with Tkinter, and the mouse events should change the text of the button clicked.

Through testing, this works with right click () and middle click (). However, (left click) uses a function, which should find the "coordinates" of the widget in the array (I need these numbers for later calculations). The bottom row of the grid works, but any other button leads to the bottom-right button being selected.

from tkinter import *
from random import *

win = Tk()
win.geometry("380x410")
win.grid()

buttons = []

def search(event):
    for j in range(10):
        for i in range(10):
            #print(event.widget)
            if buttons[j][i] == event.widget:
                break
    print(i,j)
    buttons[j][i].config(text="1")

for y in range(10):
    temp = []
    for x in range(10):
        button = Button(win,text="",width=4,height=2)
        button.grid(row=y,column=x)
        button.bind("<Button-1>",search)
        button.bind("<Button-2>",lambda event: event.widget.config(text=""))
        button.bind("<Button-3>",lambda event: event.widget.config(text="R"))
        temp.append(button)
    buttons.append(temp)

I have tried messing about with lambdas, but I believe the problem lies within the function.

Any help would be appreciated.

3
Your break, breaks only the inner for i .... Either use a flag or move your to do to the break and return. - stovfl
Why are you using a bind on a button? Just use the command. - Mike - SMT

3 Answers

0
votes

Question: Finding widgets in an array Tkinter

Simpler solution

import tkinter as tk

class App(tk.Tk):
    def __init__(self):
        super().__init__()

        for y in range(10):
            for x in range(10):
                button = tk.Button(self, text="", width=4, height=2)

                button._coords = x, y

                button.grid(row=y, column=x)
                button.bind("<Button-1>", self.on_button_1_click)

    def on_button_1_click(self, event):
        print('on_button_1_click:{}'.format(event.widget._coords))


if __name__ == '__main__':
    App().mainloop()
0
votes

Maybe this is somewhat close to what you're looking for:

from tkinter import *
from random import *

win = Tk()
win.geometry("380x410")
win.grid()

buttons = []

def search(event):
    i2 = 0
    j2 = 0
    for j in range(10):
        for i in range(10):
            #print(event.widget)
            if buttons[j][i] == event.widget:
                i2 = i
                j2 = j
                event.widget.config(text="1")
                break
    print(i2,j2)
    #buttons[j][i].config(text="1")

for y in range(10):
    temp = []
    for x in range(10):
        button = Button(win,text="",width=4,height=2)
        button.grid(row=y,column=x)
        button.bind("<Button-1>", lambda event: search(event))
        button.bind("<Button-2>",lambda event: event.widget.config(text=""))
        button.bind("<Button-3>",lambda event: event.widget.config(text="R"))
        temp.append(button)
    buttons.append(temp)

win.mainloop()
0
votes

Are you sure you need coordinates or just the index of the Button in the buttons list?

If you just need to accurately interact with each button try using the index value in a lambda.

from tkinter import *

win = Tk()
win.geometry("380x410")
buttons = []


def search(btn, ndex):
    if btn == '1':
        buttons[ndex].config(text='1')
    if btn == '2':
        buttons[ndex].config(text='')
    if btn == '3':
        buttons[ndex].config(text='R')


for y in range(10):
    for x in range(10):
        buttons.append(Button(win, text="", width=4, height=2))
        ndex = len(buttons) - 1
        buttons[-1].bind("<Button-1>", lambda e, z=ndex: search('1', z))
        buttons[-1].bind("<Button-2>", lambda e, z=ndex: search('2', z))
        buttons[-1].bind("<Button-3>", lambda e, z=ndex: search('3', z))
        buttons[-1].grid(row=y, column=x)

win.mainloop()