如何将小部件放在ttk.Button

时间:2016-01-30 19:14:46

标签: python tkinter

是否有正确的方法将小部件嵌套在ttk.Button内?它支持指定标签(str)和图像(PhotoImage),我假设它是使用子窗口小部件实现的。

以下是我向按钮添加左对齐和右对齐标签的示例。

import tkinter as tk
import tkinter.ttk as ttk

root = tk.Tk()

normal_button = ttk.Button(root, text="Normal Button")
normal_button.pack(fill=tk.X)

custom_button = ttk.Button(root)
custom_button.pack(fill=tk.X)
left_label = ttk.Label(custom_button, text="Left")
left_label.pack(side=tk.LEFT, padx=16, pady=4)
right_label = ttk.Label(custom_button, text="Right")
right_label.pack(side=tk.RIGHT, padx=16, pady=4)

root.mainloop()

这种作品,但有一些怪癖:

  • 当鼠标悬停在按钮上时,按钮的背景会突出显示,但嵌套的标签会保留其未突出显示的背景。
  • 如果我在任一嵌套标签内点击,该按钮将按下,但不会被取消。
  • 按下按钮时,嵌套标签不会移动,从而产生按下按钮的错觉。

是否有正确的方法将小部件打包在按钮内?

2 个答案:

答案 0 :(得分:4)

正如我在评论中所说,您可以创建自己的小部件。

以下是tk.Frametk.Label的简单示例(ttk.Label需要更多地使用ttk.Style)。

我绑定事件<Enter><Leave>来更改框架和标签背景。

对于更多小部件,您可以将它们保存在列表中,并使用for循环来更改背景。

import tkinter as tk
import tkinter.ttk as ttk

class MyButton(tk.Frame):

    def __init__(self, master, bg_hover='red', bg_normal=None, **options):
        tk.Frame.__init__(self, master, **options)

        self.bg_normal = bg_normal
        self.bg_hover = bg_hover

        # use default color if bg_normal is `None`
        if not self.bg_normal:
            self.bg_normal = self['bg']

        # add first label
        self.left_label = tk.Label(self, text="Left")
        self.left_label.pack(side=tk.LEFT, padx=16, pady=4)

        # add second label
        self.right_label = tk.Label(self, text="Right")
        self.right_label.pack(side=tk.RIGHT, padx=16, pady=4)

        # bind events
        self.bind('<Enter>', self.on_enter)
        self.bind('<Leave>', self.on_leave)

    def on_enter(self, event=None):
        # change all backgrounds on mouse enter
        self['bg'] = self.bg_hover
        self.left_label['bg'] = self.bg_hover
        self.right_label['bg'] = self.bg_hover

    def on_leave(self, event=None):
        # change all backgrounds on mouse leave
        self['bg'] = self.bg_normal
        self.left_label['bg'] = self.bg_normal
        self.right_label['bg'] = self.bg_normal


root = tk.Tk()

normal_button = ttk.Button(root, text="Normal Button")
normal_button.pack(fill=tk.X)

my_button = MyButton(root)
my_button.pack()

root.mainloop()

答案 1 :(得分:2)

没有正确的方法来在按钮内打包小部件。按钮不是为该功能设计的。正如您所见,您确实可以使用packgrid将小部件放在按钮内。但是,您必须添加自定义绑定才能使其看起来像是一个按钮小部件。