在Python中触发来自不同类的Tkinter事件

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Python中触发来自不同类的Tkinter事件相关的知识,希望对你有一定的参考价值。

所以我一直试图在我的tkinter项目中使用类,但我似乎无法准确理解类如何交互。特别是涉及tkinter时。我可以访问变量和值并传递它们,但我似乎无法弄清楚如何做触发器。

我目前的问题是尝试从不同的类触发事件。这个问题的一个简单版本是这样的:

from tkinter import *

class Area:
    def __init__(self):
        self.can = Canvas(width=100, height=100, bg="green")
        self.can.pack(in_=window)
        self.can.bind("<Button-3>", self.test)
        self.square = self.can.create_rectangle(25, 25, 75, 75)

    def test(self, event):
        self.can.delete("all")

class Trigger:
    def __init__(self):
        self.button = Button(text="click me", command=?)
        self.button.pack(in_=window)

window = Tk()
Area()
Trigger()
window.mainloop()

它创造了一个绿色的画布,中间有一个正方形。右键单击画布时,将删除正方形。然后我尝试从一个不同的类触发相同的行为,这里用一个按钮演示。

问题是,我不能为我的生活弄清楚什么作为按钮上的命令。

我试过command=Area.test,但后来我得到了“

TypeError:test()缺少2个必需的位置参数:'self'和'event'“

我试过command=Area.test(Area, "event")command=Area.test(self, "event"),但他们回来了:

AttributeError:类型对象'Area'没有属性'can'

AttributeError:类型对象'Area'没有属性'can'

我也尝试了Area().test("event),它没有给出任何错误,但给了我2个画布实例,一个带方形,一个没有。按钮什么也没做。

看看继承,所以我尝试将Area作为继承在Trigger类上,然后做command=self.test("event")然后得到:

AttributeError:'Trigger'对象没有属性'can'

所以我没有想法..我在做__init__part错了吗?

答案

首先,如果要将函数既作为事件的目标又作为command属性的值,则应使event参数可选。你可以通过给它一个默认值None来做到这一点:

def test(self, event=None):
    self.can.delete("all")

其次,需要为Trigger对象提供Area对象的实例,以便它可以调用该对象上的方法。有几种方法可以做到这一点,但最直接的方法是在创建对象时传入它。这意味着你需要修改Trigger.__init__来接受参数,然后你需要在创建对象时传入它。

这是如何修改__init__方法:

class Trigger:
    def __init__(self, area):
        self.button = Button(text="click me", command=area.test)
        self.button.pack(in_=window)

这是如何将Area对象传递给Trigger对象:

area=Area()
Trigger(area)

以上是关于在Python中触发来自不同类的Tkinter事件的主要内容,如果未能解决你的问题,请参考以下文章

在 python tkinter 中每次连续单击后都会触发双击事件

python编程,使用Tkinter中的文本框显示系统时间

Tkinter GUI 中的多线程,不同类中的线程

python tkinter中的事件绑定

Python:GUI之tkinter学习笔记3事件绑定

在python tkinter中调用事件时,变量不更新的标签