【问题标题】:Expand Python Tkinter Object Types展开 Python Tkinter 对象类型
【发布时间】:2021-06-02 23:24:11
【问题描述】:

发现现有类型有这个问题:

但是,我刚刚开发了一些工具提示(气球),我已经分配给了一些按钮,并且希望能够将它们全部作为一种独特的类型来调用。此外,我还想手工制作画布对象,这些对象将像带有<enter><leave><active><press><release> 事件的伪按钮一样操作。我如何为他们声明一个新的对象类型?

【问题讨论】:

    标签: python tkinter object-tag object-type s3-object-tagging


    【解决方案1】:

    如果我正确理解您的问题,您想检查创建的实例是否是自定义类的实例,可以使用isinstance 直接完成:

    class CustomTooltip():
        pass
    
    cwidget = CustomTooltip()
    btn     = tk.Button(root)
    
    print(isinstance(cwidget, CustomTooltip)) # True
    print(isinstance(b, CustomTooltip)) # False
    
    print(type(cwidget) == CustomTooltip) # Not recommended
    

    建议使用isinstance 而不是type,来自文档:

    建议使用isinstance() 内置函数来测试对象的类型,因为它考虑了子类。


    我没有完全得到你的第二个问题,而且最好将一个问题集中在一个主要问题上,而不是问多个问题。

    【讨论】:

    • 感谢您提供isinstance() 文档。我真的没有问第二个关于如何将矩形按钮转换为画布类型的圆形按钮的问题。我只是想给出一个简短的项目概述来解释为什么我需要获取 python tkinter 自定义对象类型。事后看来,我应该说目的是跟踪所有气球悬停提示并在 1/2 秒后将它们淡入并在 5 秒后将它们淡出。
    • @WinEunuuchs2Unix 酷,我过去也做过同样的事情~比如this。现在我对它进行了改进,使其变得圆润并增加了等待时间和更多额外的功能。简而言之,我认为我正确回答了您的问题?
    • 我检查了您指向MPlayer 的链接,我的应用程序名为mserve Music Server。尚无代码,但您可以单击Issues 以查看示例屏幕。我认为您的答案是正确的,但想等几天看看网络上还有哪些其他答案。
    • @WinEunuuchs2Unix 那是巧合,我的意思是让你看一下工具提示,无论如何都是很棒的项目:D 希望尽快看到源代码
    • “很快”是一个相对术语。我已经在mserve 上工作了一年,我想它很快就会在一两年内完成。当我学习 SQL 之类的新东西时,我回过头来重写函数,这些函数具有来自 MusicBrainz 的音频 CD 曲目列表的泡菜。通过 SSH 访问文件服务器的音乐或通过 WiFi 访问手机音乐之类的事情我已经知道需要进行重大重写 sigh。我确实看过你的代码,我希望我在两天前看到它,因为我刚刚在 500 毫秒延迟后淡入工具提示并在 5 秒后淡出。感谢您帮助我的几次!
    【解决方案2】:

    面向对象的编程可能是解决方案。

    如果我想创建一个“新类型”的 tkinter 按钮,我可以对它进行子类化。

    class MySpecialButton(tkinter.Button):
        pass
    

    目前这并没有做任何特别的事情,但会给它一个独特的类型(如果它正确理解了你的解释)

    我的另一个答案中的以下示例创建了一个具有自定义行为的特殊按钮,用于将鼠标悬停在按钮上

    class HoverButton(tk.Button):
        def __init__(self, master, **kw):
            tk.Button.__init__(self,master=master,**kw)
            self.defaultBackground = self["background"]
            self.bind("<Enter>", self.on_enter)
            self.bind("<Leave>", self.on_leave)
    
        def on_enter(self, e):
            self['background'] = self['activebackground']
    
        def on_leave(self, e):
            self['background'] = self.defaultBackground
    

    关于画布对象,您显然也可以为它们创建类,其中可以包含移动/调整对象大小的方法。至于如何为这些创建自定义事件,您可以使用tag_bind(item, event=None, callback=None, add=None) 将回调绑定到画布对象。下面是一个简单的例子

    import tkinter as tk
    
    class CanvasShape:
        def __init__(self, canvas, callback = None):
            self.canvas = canvas
            self.id = canvas.create_oval(10,10,50,50,fill='blue')
            self.canvas.tag_bind(self.id,'<Button-1>',callback)
    
    def clicked(e):
        print("You clicked on a shape")
    
    root = tk.Tk()
    c = tk.Canvas(root,width=200,height=200)
    c.grid()
    shape = CanvasShape(c,callback=clicked)
    
    root.mainloop()
    

    这将创建一个圆圈,当您单击该圆圈时将触发clicked 函数接收到的事件。

    【讨论】:

    • 我认为这不能回答问题
    • @CoolCloud 感谢您的反馈。您觉得哪些方面没有得到解答?
    • 我已经在使用你的HoverButton 课程了。问题是我如何找到 20 个悬停按钮并通过搜索它们的对象类型来循环遍历它们?
    • @WinEunuuchs2Unix 找到 20 个悬停按钮?这似乎是一个 XY 问题,您为什么不提出一个新问题来解释您实际尝试做的事情并包含一些自定义类的代码
    • @CoolCloud 我猜这可能是一个 XY 问题。我找到了一种比解析对象类型更简单的解决方案。我只是在创建对象时将它们注册到列表中。然后要查找该类型的所有对象,我只需遍历列表即可。比使用 Tkinter 调用在父 Tk.TopLevel 和所有子 Tk.TopLevel 子中查找给定类型的所有对象类型(包括带有工具提示的 Tk.Frame)要简单得多。几天后提醒我,如果没有出现另一个答案,我会接受其中一个。谢谢。
    猜你喜欢
    • 2015-02-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-03
    • 1970-01-01
    • 2012-11-11
    • 1970-01-01
    • 2016-05-17
    • 2022-01-07
    相关资源
    最近更新 更多