【问题标题】:Tkinter create_image() retains PNG transparency but Button(image) does notTkinter create_image() 保留 PNG 透明度,但 Button(image) 不
【发布时间】:2019-04-22 09:20:27
【问题描述】:

TkVersion = 8.6,Python 版本 3.7.3

我正在尝试使用 PNG 图像在 python 中使用 tkinter 创建一个按钮。图像的透明角是否透明取决于我使用的小部件。看来canvas.create_image 是唯一保留透明度的小部件。

首先,我使用 create_image(0,0, image=button) 在画布上添加了图像,效果很好 - 圆角是透明的。

但是当我尝试使用Button()create_window() 小部件将其实现为实际按钮时,角落被白色填充。

button = ImageTk.PhotoImage(file="button.png")

canvas = tk.Canvas(width=200, heigh=200, borderwidth=0, highlightthickness=0)
canvas.grid()
canvas.create_rectangle(0,0,199,199, fill="blue")

canvas.create_image(0,0, image=button, anchor="nw")

[]

button = ImageTk.PhotoImage(file="button.png")

canvas = tk.Canvas(width=200, heigh=200, borderwidth=0, highlightthickness=0)
canvas.grid()
canvas.create_rectangle(0,0,199,199, fill="blue")

buttonWidget = tk.Button(root, image=button)
canvas.create_window(0,0, window=buttonWidget, anchor="nw")

如何使 PNG 按钮的角透明?

这也是按钮图像:

【问题讨论】:

  • 使用图像而不是Button 作为您的按钮。将"<Button-1>" 事件绑定到图像。
  • 你能说得更具体点吗?我重命名了按钮小部件以使其更清晰。

标签: python tkinter transparency tkinter-canvas


【解决方案1】:

您可以创建自己的自定义按钮类继承自画布,并像使用Button() 一样使用它。我为你做了一个,希望对你有帮助。

自定义按钮类:

将这个类保存在一个单独的文件中作为imgbutton.py,然后将它导入到您的主文件中。还要确保它与主文件位于同一目录中。或者您可以在导入后将其保留在主文件的顶部。

import tkinter as tk

class Imgbutton(tk.Canvas):

    def __init__(self, master=None, image=None, command=None, **kw):

        # Declared style to keep a reference to the original relief
        style = kw.get("relief", "groove")        

        if not kw.get('width') and image:
            kw['width'] = image.width()
        else: kw['width'] = 50

        if not kw.get('height') and image:
            kw['height'] = image.height()
        else: kw['height'] = 24

        kw['relief'] = style
        kw['borderwidth'] = kw.get('borderwidth', 2)
        kw['highlightthickness'] = kw.get('highlightthickness',0)

        super(Imgbutton, self).__init__(master=master, **kw)

        self.set_img = self.create_image(kw['borderwidth'], kw['borderwidth'], 
                anchor='nw', image=image)

        self.bind_class( self, '<Button-1>', 
                    lambda _: self.config(relief='sunken'), add="+")

        # Used the relief reference (style) to change back to original relief.
        self.bind_class( self, '<ButtonRelease-1>', 
                    lambda _: self.config(relief=style), add='+')

        self.bind_class( self, '<Button-1>', 
                    lambda _: command() if command else None, add="+")

这是一个如何使用它的示例

import tkinter as tk
from imgbutton import Imgbutton    # Import the custom button class

root = tk.Tk()
root['bg'] = 'blue'

but_img = tk.PhotoImage(file='button.png')

but = Imgbutton(root, image=but_img, bg='blue', 
            command=lambda: print("Button Image"))
but.pack(pady=10)

root.mainloop()

【讨论】:

  • 您是否在style = kw.get('relief', 'groove') 中设置按钮样式? 'relief' 不是 kw 字典的键和 'groove' 对应的值吗?为什么kw.get('relief') 不够用?
  • 只是为了保留relief 的引用,以便程序知道在按钮释放事件发生时切换回之前的relief 是什么
  • 抱歉,现在我知道'groove' 是style = kw.get('relief', 'groove') 中'relief' 的默认值。我是编码的初学者,我想完全理解您使用的语法:)
  • 没关系,如果你想了解更多关于 Tkinter 的信息,请查看link
  • 这是因为默认情况下,画布与按钮相比相当大,因此我将大小设置为类似于按钮,以防您决定在没有图像的情况下使用此按钮。删除它不会造成任何伤害。
猜你喜欢
  • 2014-05-20
  • 1970-01-01
  • 2021-10-03
  • 2013-04-11
  • 2016-12-26
  • 1970-01-01
  • 2012-05-29
  • 2011-03-17
  • 1970-01-01
相关资源
最近更新 更多