【问题标题】:TKinter/TTK: Multiple elements in a clickable areaTKinter/TTK:可点击区域中的多个元素
【发布时间】:2021-06-05 04:49:02
【问题描述】:

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

ttk.Button 似乎采用文本或图像。

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

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

【问题讨论】:

  • 您想在按钮内添加可点击的元素吗?
  • 我想要一个大的可点击元素,里面有 8 个文本项和 2 个图像。
  • 您可以创建框架或画布并将其绑定到按钮单击
  • @Sujay 代码示例?

标签: python python-3.x tkinter python-3.9 tkinter-button


【解决方案1】:

使用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

【讨论】:

  • 谢谢!我认为这些反应让事情朝着正确的方向发展,但我在让项目实际显示时遇到了一些问题。你介意看看上面。代码运行,但项目没有放在画布上。我猜我的代码结构导致项目更新出现问题。
  • @eat-sleep-code 你的无限 while 循环和 time.sleep 必须阻塞 tkinter 主循环。我建议您将其作为另一个问题提出。更改这个问题会使这篇文章让其他读者感到困惑。
  • 认为如果我发布另一个问题会更加令人困惑,因为我原来的问题仍然可能是开放的。删除while Truetime.sleep 只会导致程序在显示浅灰色屏幕后退出。 app.update() 应该足以更新屏幕。
  • @eat-sleep-code 您的代码不可重现。创建一个最小的、可重现的示例并将其粘贴到 pastebin 或创建一个准确描述您的问题的新帖子,如果您这样做,您更有可能获得帮助。人们在他们的程序中使用time.sleep 或无限while 循环时遇到问题是很常见的,特别是在开始使用GUI 框架时。您是否考虑过使用 widget.after ,这可能是您正在寻找的。​​span>
  • @eat-sleep-code 您是否介意将我的答案标记为已接受,因为您似乎正在使用我的解决方案?
【解决方案2】:

您可以做的是获取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() 进行绑定。但是,这将绑定窗口中的所有内容。

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()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多