有没有办法点击我在 tkinter 中点击并拖动鼠标的所有按钮

Is there a way to click all the buttons on which i clicked and dragged my mouse in tkinter

我创建了一个按钮网格,我需要通过单击并拖动来更改按钮的背景颜色。 这是因为网格非常大,单独单击每个按钮很乏味。

我假设您使用 range() 函数循环以创建所有网格化按钮。

在下面的 OOP 代码中,您可以一键更改所有内容, 并将鼠标悬停在每种颜色上并更改颜色:

注意:

  • 单击白色按钮会将所有内容更改为绿色
  • 将鼠标悬停在每种颜色上会将其变为蓝色
from tkinter import *


root = Tk()


def change_myself(button,color_in_hex):
    button.configure(bg = color_in_hex)


class MyButtons():
    def __init__(self,current_color,new_color,button_amount):
        super(MyButtons,self).__init__()
        self._current_color = current_color
        self._new_color = new_color
        self._button_amount = button_amount
        self._buttons_list = list(range(self._button_amount))


    @property
    def buttons_list(self):
        return self._buttons_list

    def __getitem__(self, item):
        return item

    def __setitem__(self, key, value):
        self._buttons_list = value


    def create_buttons(self):
        for a in range(self._button_amount):
            self.buttons_list[a] = Button(root,bg = self._current_color,text = 'Button Number {0}'.format(a))
            print(self.buttons_list[a])
            self.buttons_list[a].grid(row = a,column = 0)
            self.buttons_list[a].bind('<Enter>',lambda event,current_button_index = a: self._buttons_list[current_button_index].configure(bg = '#0000FF'))

        special_button = Button(root,bg = '#FFFFFF',text = 'Changer!')
        special_button.grid(row = 0,column = 1)
        special_button.bind('<Button-1>',lambda event: self.change_everything())

    def change_everything(self):
        for button in self.buttons_list:
            button.configure(bg = self._new_color)

implementation = MyButtons(current_color = '#FF0000',new_color = '#00FF00',button_amount = 10)
implementation.create_buttons()

root.mainloop()

结果如下:

您可以在 <B1-Motion> 上绑定以在拖动鼠标时捕获事件。在绑定函数中,您可以使用 winfo_containing 方法来确定哪个小部件在光标下。

示例:

import tkinter as tk

root = tk.Tk()
for row in range(20):
    for column in range(20):
        f = tk.Frame(root, width=20, height=20, bd=1, relief="raised")
        f.grid(row=row, column=column, sticky="nsew")

root.grid_columnconfigure("all", weight=1)
root.grid_rowconfigure("all", weight=1)

def paint(event):
    widget = event.widget.winfo_containing(event.x_root, event.y_root)
    if widget:
        widget.configure(bg="green")

root.bind("<B1-Motion>", paint)
root.mainloop()

编辑: 我在几个小时前做到了,但我不得不做一些不同的事情,同时 Bryan Oakley 展示了同样的想法 :) 现在我知道这是个好主意。

但此方法会选择所有小部件 - 即使您不想要它 - 所以我添加了自己的 属性 selectable 并使用 hasattr() 因此只能选择一些小部件。


我在 root 上使用 <B1-Motion> 到 运行 函数,该函数使用鼠标位置和 winfo_containing 来识别小部件并更改其背景。

import tkinter as tk

def select(event):
    widget = root.winfo_containing(event.x_root, event.y_root)
    if widget and hasattr(widget, 'selectable'):
        widget['bg'] = 'red'

root = tk.Tk()

for i in range(9):
    for e in range(9):
        b = tk.Button(root, text="X")
        b.selectable = True
        b.grid(row=e, column=i)

root.bind('<B1-Motion>', select)

l = tk.Label(root, text="Label which can't be selected")
l.grid(row=9, column=0, columnspan=9)
b = tk.Button(root, text="Button which can't be selected")
b.grid(row=10, column=0, columnspan=9)
e = tk.Entry(root)
e.insert('end', "Entry which can't be selected")
e.grid(row=11, column=0, columnspan=9)

root.mainloop()