我想知道如何使用多个标签在Tkinter中创建按钮小部件,如下图所示。 Buttons with sub-label. 正如您所看到的,在某些按钮中有一个子标签,例如Button" X"还有另一个小品牌" A"。我试图搜索解决方案,但没有找到解决方案。
非常感谢你。
答案 0 :(得分:1)
您可以将标签放在Frame
中,并让Button
成为该框架的父级。但是,你需要有点聪明并克服一些问题,例如:
relief
时正确配置(不要忘记,您可能正在点击框架或标签!)等。这是一个MCVE:
import sys
import string
import random
try:
import tkinter as tk
from tkinter import ttk
except ImportError:
import Tkinter as tk
import ttk
CHARS = string.ascii_letters + string.digits
class CustomButton(tk.Button):
"""
CustomButton class inherits from tk.Button, which means it
behaves just like an ordinary tk.Button widget, but it also
has some extended functionality.
"""
def __init__(self, parent, *args, **kwargs):
super().__init__()
self.command = kwargs.get('command')
self.frame = tk.Frame(self)
self.frame.pack(fill='none', expand=False, pady=(3, 0))
self.upper_label = ttk.Label(self.frame, text=kwargs.get('upper_text'))
self.upper_label.grid(row=0, column=0)
self.bottom_label = ttk.Label(self.frame, text=kwargs.get('bottom_text'))
self.bottom_label.grid(row=1, column=1)
self.frame.pack_propagate(False)
self.configure(width=kwargs.get('width'), height=kwargs.get('height'))
self.pack_propagate(False)
self.clicked = tk.BooleanVar()
self.clicked.trace_add('write', self._button_cmd)
self.bind('<Enter>', self._on_enter)
self.bind('<Leave>', self._on_leave)
self.frame.bind('<Enter>', self._on_enter)
self.frame.bind('<Button-1>', self._on_click)
self.upper_label.bind('<Button-1>', self._on_click)
self.bottom_label.bind('<Button-1>', self._on_click)
def _button_cmd(self, *_):
"""
Callback helper method
"""
if self.clicked.get() and self.command is not None:
self.command()
def _on_enter(self, _):
"""
Callback helper method which is triggered
when the cursor enters the widget's 'territory'
"""
for widget in (self, self.frame, self.upper_label, self.bottom_label):
widget.configure(background=self.cget('activebackground'))
def _on_leave(self, _):
"""
Callback helper method which is triggered
when the cursor leaves the widget's 'territory'
"""
for widget in (self, self.frame, self.upper_label, self.bottom_label):
widget.configure(background=self.cget('highlightbackground'))
def _on_click(self, _):
"""
Callback helper method which is triggered
when the the widget is clicked
"""
self.clicked.set(True)
self.configure(relief='sunken')
self.after(100, lambda: [
self.configure(relief='raised'), self.clicked.set(False)
])
class KeyboardMCVE(tk.Tk):
"""
MCVE class for demonstration purposes
"""
def __init__(self):
super().__init__()
self.title('Keyboard')
self._widgets = []
self._create_widgets()
def _create_widgets(self):
"""
Instantiating all the "keys" (buttons) on the fly while both
configuring and laying them out properly at the same time.
"""
for row in range(5):
current_row = []
for column in range(15):
button = CustomButton(
self,
width=1, height=2,
upper_text=random.choice(CHARS),
bottom_text=random.choice(CHARS)
)
button.grid(row=row, column=column, sticky='nswe')
current_row.append(button)
self._widgets.append(current_row)
if __name__ == '__main__':
sys.exit(KeyboardMCVE().mainloop())
或者,一个简单的解决方法是使用Unicode上标/下标。