How to get grid information from pressed Button in tkinter?

Question:

I need to create table of buttons using Tkinter in Python 2.7, which has n rows and n columns, and has no button in bottom right corner.

Problem is that when I press a button, in its place, I need to create free space and move that button to space that was empty before, and I cannot do that because I don’t know how to get grid (x and y axes) information of pressed button to use it to create free space.

This is my current code:

from Tkinter import *

#Input:
n=int(raw_input("Input whole positive number: "))
L = range(1,n+1)
k = n
m = n

#Program:
root = Tk()
for i in L:
    for j in L:
        frame = Frame(root)
        frame.grid(row = i, column = j)
        if j == k and i == m:
            pass
        else:
            button = Button(frame)
            button.grid(row = i, column = j)


root.mainloop()

It would be something like this, where I wanted to get button grid position, and use it to change k and m variables to make empty space in position where pressed button was.

Answers:

Could you do something like create the grid of buttons up front, but include a hidden button in the blank space? Then when the button is clicked hide the clicked one and display the hidden one. Then you don’t have to worry about moving buttons around, unless you need the actual button object to move for some reason.

Edit to enhance answer from comments:

Below is a simple example of hiding a button and it shows how to track the buttons as well, unless I screwed up moving it to the editor. This can be translated to a list or dictionary of buttons or whatever need be. You’d also need to determine find a way to register the local buttons or add some context to know which one to show or hide.

from Tkinter import Button, Frame, Tk


class myButton(Button):

    def __init__(self, *args, **kwargs):
        Button.__init__(self, *args, command=self.hideShowButton,
                        ** kwargs)
        self.visible = True

    def hideShowButton(self):
        self.visible = False
        self.pack_forget()

window = Tk()
frame = Frame(window)
frame.pack()
b1 = myButton(window, text="b1")
b1.pack()
b2 = myButton(window, text="b2")
b2.pack()
b3 = myButton(window, text="b3")
b3.pack()
window.wait_window(window)
print "At the end of the run b1 was %s, b2 was %s, b3 was %s" % (str(b1.visible), str(b2.visible), str(b3.visible))
Answered By: Ryan

This is the way I tried to do this and problem is that I still don’t know how to get row and column of pressed button…

from Tkinter import *

#Input:
n = int(raw_input("Input whole positive number: "))
L = range(1,n+1)
k = n
m = n
#Try putting values for k and m which are less then n and you will see what   i need to get

#Moving:
def Move():
    #This i cant fill
    return k,m

#Program:
root = Tk()
for i in L:
    for j in L:
        frame = Frame(root)
        frame.grid(row = i,column = j)
        if i == int(k) and j == int(m):
            pass
        else:
            button = Button(frame, command = lambda: Move())
            button.pack()

root.mainloop()

So by changing k and m values gap is created on other place…

You can pass the row and column by using a lambda expression for the button:

button = Button(..., command=lambda row=i, column=j: doSomething(row, column))
Answered By: Bryan Oakley
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.