将右键单击绑定到按钮数组 tkinter

Bind right click to array of buttons tkinter

我正在 python 使用 tkinter 制作扫雷游戏,需要将右键单击绑定到我的按钮,以便我可以标记炸弹。

现在左键可以看到按钮被按下但是没有执行功能,右键也看不到被按下的按钮。我觉得可能是 click(ind) 函数搞砸了,但是当我删除它时,ind 到处都是红色下划线。

如何正确地将右键单击绑定到这组按钮?

from tkinter import *


def play():
    win = Tk()

    main_frame = Frame(win)
    main_frame.pack()

    btn_grid = list()
    i = 0
    for row in range(8):
        for col in range(8):
            btn_grid.append(Button(main_frame, height=1, width=1, font="Verdana", relief='groove',
                               command=lambda c=i: click(c)))
            btn_grid[i].grid(row=row, column=col, sticky="news", ipadx=20, ipady=15)
            i = i + 1

    def click(ind):
        def left(event):
            btn_grid[ind].config(text='L')

        def right(event):
            btn_grid[ind].config(text='R')

        btn_grid[ind].bind("<Button-1>", left)
        btn_grid[ind].bind("<Button-3>", right)

    win.mainloop()

play()

当我执行您的代码时,我观察到以下情况:

  1. Left-click 后跟另一个 left-click 将文本更改为 L
  2. Left-click 后跟 right-click 将文本更改为 R.

原因是 click 函数仅在您 left-click 按钮后执行。一旦为特定按钮执行了 click 函数,它就会像您期望的那样响应左键和右键单击。

因此,直接解决问题的方法是在定义按钮本身时执行click,以便为左右单击做好准备.


工作代码 1:

from tkinter import *


def play():
    
    def click(ind):
        def left(event):
            btn_grid[ind].config(text='L')

        def right(event):
            btn_grid[ind].config(text='R')

        btn_grid[ind].bind("<Button-1>", left)
        btn_grid[ind].bind("<Button-3>", right)

    win = Tk()

    main_frame = Frame(win)
    main_frame.pack()

    btn_grid = list()
    i = 0
    for row in range(8):
        for col in range(8):
            btn_grid.append(Button(main_frame, height=1, width=1, font="Verdana", relief='groove',
                               command=lambda c=i: click(c)))
            btn_grid[i].grid(row=row, column=col, sticky="news", ipadx=20, ipady=15)
            click(i)
            i = i + 1
            
    
    win.mainloop()

play()

但是有更好的解决办法。您可以直接将按钮绑定到 leftright 而不是以这种方式执行 click,而无需经过 click.

工作代码 2(改进):

from tkinter import *


def play():
    
    def left(ind):
        btn_grid[ind].config(text='L')

    def right(ind):
        btn_grid[ind].config(text='R')
    
    win = Tk()
    main_frame = Frame(win)
    main_frame.pack()

    btn_grid = list()
    i = 0
    for row in range(8):
        for col in range(8):
            btn_grid.append(Button(main_frame, height=1, width=1, font="Verdana", relief='groove'))
            btn_grid[i].grid(row=row, column=col, sticky="news", ipadx=20, ipady=15)
            
            btn_grid[i].bind("<Button-1>", lambda e,c=i: left(c))
            btn_grid[i].bind("<Button-3>", lambda e,c=i: right(c))
    
            i = i + 1
            
    win.mainloop()

play()

最好将两个事件绑定在 for 循环中:

def play():
    def left(event):
        event.widget.config(text='L')

    def right(event):
        event.widget.config(text='R')

    win = Tk()

    main_frame = Frame(win)
    main_frame.pack()

    btn_grid = list()
    for row in range(8):
        for col in range(8):
            btn_grid.append(Button(main_frame, height=1, width=1, font="Verdana", relief='groove'))
            btn_grid[-1].grid(row=row, column=col, sticky="news", ipadx=20, ipady=15)
            btn_grid[-1].bind("<Button-1>", left)
            btn_grid[-1].bind("<Button-3>", right)

    win.mainloop()

我更愿意使用 Label 而不是 Button