GUI - tkinter : how to access parameters of specific buttons?

删除回忆录丶 提交于 2020-01-25 07:29:07

问题


Like many other python beginners, I am playing around with GUIs (tkinter). For my little project, I wanted to create a grid of 5x5 buttons, that is 25 buttons in total, and interact with them: when you click on any of those 25 buttons, some buttons will change around the clicked button. I won't go into much details about what I want the final result to be, unless you think it is relevant. You will find bellow a code snippet that was adapted for this question in particular.

The question, btw, is:

How to make some specific buttons react to the event of another button being pressed in this situation?

Added more information about this situation, I'll formulate my question like this :

Given an array of 25 buttons generated by for loops, how to target specific buttons in order to interact with their parameters (for example: the parameter 'bg'. One button is cliked, another changes colours), considering that those buttons were not stored into variables that would allow an explicit access (for example: butt = tk.Button(...). Changing parameters of butt would be easy because the widget was explicitly assigned to a variable. Here, no variable assignment, just an iterative creation of widgets)

I tried looking for answers for a long time without success, and that is certainly because I am looking in the wrong direction.

If you run the code bellow, you will get a 5x5 button grid. What I want is that for example all the surrounding buttons change their background colour to green if I click on any button.

import tkinter as tk

# --- functions ---

def draw_board():
    frame_board = tk.Frame(root)
    frame_board.pack()

    def callback(button):
        button['relief'] = 'sunken'
        button['bg'] = 'lightgrey'
        button['state'] = 'disabled'

    def draw_tile(container, number):
        tile_1 = tk.Button(container,
                           text='1',
                           width=6,
                           height=3,
                           relief='sunken',
                           bg='lightgrey',
                           state='disabled')
        tiles = tk.Button(container,
                          text='?',
                          command=lambda: callback(tiles),
                          width=6,
                          height=3)
        if number == 1:
            return tile_1
        else:
            return tiles

    r, c = 0, 0

    for i in range(1,26):
        c += 1
        if i in range(1,26,5):
            r += 1
            c = 0
            draw_tile(frame_board, i).grid(row=r,
                                           column=c,
                                           sticky='wens',
                                           padx=10,
                                           pady=10)
        else:
            draw_tile(frame_board, i).grid(row=r,
                                           column=c,
                                           sticky='wens',
                                           padx=10,
                                           pady=10)
# --- main ---

root = tk.Tk()
root.geometry('400x400')

start_button = tk.Button(root,
                         text='START',
                         command=draw_board)
start_button.place(relx=.5,
                   rely=.5,
                   anchor='center')

root.mainloop()

This is my first question on SO so please tell me if it was not complete, or if it needed more precisions. I tried to make the code lighter than the one I am working on, but I can make it even more simple if needed (I think)

Thank you !

EDIT: if you see anything in my code that SHOULD be modified for the sake of clarity/effectiveness/usage etc. please tell me, even if it does not answer my twisty question.


回答1:


I actually asked a question similar to this a few years ago when I was starting out:

tkinter: changing button attributes for buttons created in loop

It would be much easier if you store the buttons somewhere when they are created:

(I removed some redundant code as well.)

import tkinter as tk

# --- functions ---

def draw_board(buttons):
    frame_board = tk.Frame(root)
    frame_board.pack()

    def surround(buttons, num):
        edges = {'N': list(range(0,5)), 'E': list(range(4,25,5)),
                       'S': list(range(20,25)), 'W': list(range(0,25,5))}

        encircle = {'N':-5, 'NE':-4, 'E':1, 'SE':6, 'S':5, 'SW':4, 'W':-1, 'NW':-6}
        for direction in edges:
           # determine if selected button is on an edge
           if num in edges[direction]:
              # if button is on an edge, set encircle direction False
              for d in encircle:
                 if direction in d:
                    encircle[d] = False

        for key, val in encircle.items():
           if val: # check that its not False
              buttons[num + val].config(bg = 'green')

    def callback(buttons, num):
        buttons[num].config(relief = 'sunken', bg = 'lightgrey', state = 'disabled')
        surround(buttons, num)

    def draw_tile(container, buttons, number):
        tile = tk.Button(container, text='?', width=6, height=3,
                                 command=lambda num=number: callback(buttons, num))
        return tile

    r, c = 0, 0
    for i in range(0,25):
        c += 1
        buttons.append(draw_tile(frame_board, buttons, i)) # append button 
        if i in range(0,25,5):
            r += 1
            c = 0
        # grid last button in list
        buttons[-1].grid(row=r, column=c, sticky='wens', padx=10, pady=10)

# --- main ---

root = tk.Tk()
root.geometry('400x400')

buttons = [] # declare list

start_button = tk.Button(root, text='START',
                                      command=lambda:draw_board(buttons))
start_button.place(relx=.5, rely=.5, anchor='center')

root.mainloop()

Now buttons is a list containing each button, and you can edit their properties using the buttons[0].config() method



来源:https://stackoverflow.com/questions/59305047/gui-tkinter-how-to-access-parameters-of-specific-buttons

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!