TKinter/TTK: 可点击区域中的多个元素

TKinter/TTK: Multiple elements in a clickable area

我很好奇是否可以创建包含多个元素的可点击元素?

ttk.Button 似乎在拍摄文字或图片。

我想要一个可点击的元素,其中包含 8 个文本项和 2 个图像。单击该元素中的任意位置将触发相同的后端方法。

任何代码示例都会有所帮助,因为仍在涉猎 TKinter —— 只有我的第二个项目使用它。

使用 bindtags 并为您希望可点击的所有小部件提供相同的标签,然后使用 bind_class 绑定所有小部件。

这是一个例子

import tkinter as tk

def clicked(event):
    print("Clicked !")


class ClickableElement(tk.Frame):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        
        self.bindtags('Click')  # or pass a list if you want to have multiple tag names

        for x in range(8):
            lbl = tk.Label(self, text=f"Text {x}")
            lbl.bindtags('Click')
            lbl.pack()
        

root = tk.Tk()
root.geometry("200x200")


frame = ClickableElement(root) # or tk.Frame(root, class_='Click')
frame.pack(fill='both', expand=True)


frame2 = tk.Frame(root, bg='red')
frame2.pack(expand=True, fill='both')


root.bind_class('Click', "<Button-1>", clicked)
root.mainloop()

以上示例将使文本和框架都可点击。您可以对此进行扩展以包括图像。或者,您可以在框架内的每个小部件上使用 bind

您可以做的是获取 tk.Frame 的子项并将它们绑定到一个函数。

from tkinter import *
from tkinter import messagebox
class ClickFrame:
    def __init__(self,root):
        self.root = root
        self.root.geometry("700x500")
        Label(self.root,text="Clickable Frame!",font=("arial",15)).pack(fill=X,side=TOP)
        self.Frame1 = Frame(self.root,bg="light grey")
        self.Frame1.pack(fill=BOTH,expand=1,padx=100,pady=100)
        for  i in range(8):
            Label(self.Frame1,text=f"This is Label {i}").pack(pady=5,anchor="w",padx=5)
        self.Frame1.bind("<Button-1>",self.detect_click)
        for wid in self.Frame1.winfo_children():
            wid.bind("<Button-1>",self.detect_click)
    def detect_click(self,event,*args):
        
        messagebox.showerror("Clicked",f"Clicked  the widget {event.widget}")
        print(event.widget,type(event.widget))
        
        
root=Tk()
ob=ClickFrame(root)
root.mainloop()

您也可以使用bind_all()绑定。但是,这将绑定 window.

中的所有内容
from tkinter import *
from tkinter import messagebox
class ClickFrame:
    def __init__(self,root):
        self.root = root
        self.root.geometry("700x500")
        Label(self.root,text="Clickable Frame!",font=("arial",15)).pack(fill=X,side=TOP)
        self.Frame1 = Frame(self.root,bg="light grey")
        self.Frame1.pack(fill=BOTH,expand=1,padx=100,pady=100)
        for  i in range(8):
            Label(self.Frame1,text=f"This is Labe {i}").pack(pady=5,anchor="w",padx=5)
        self.Frame1.bind_all("<Button-1>",self.detect_click)
    def detect_click(self,event,*args):
        messagebox.showerror("Clicked",f"Clicked  the widget {event.widget}")
        
root=Tk()
ob=ClickFrame(root)
root.mainloop()