2
我想知道如何在Tkinter中創建具有多個標籤的按鈕構件,如下圖所示。 Buttons with sub-label. 正如您所看到的,在某些按鈕中有一個子標籤,例如按鈕「X」有另一個小標籤「A」。我試圖尋找解決方案,但沒有發現。如何在Tkinter的Button小部件中創建多個標籤?
非常感謝您提前。
我想知道如何在Tkinter中創建具有多個標籤的按鈕構件,如下圖所示。 Buttons with sub-label. 正如您所看到的,在某些按鈕中有一個子標籤,例如按鈕「X」有另一個小標籤「A」。我試圖尋找解決方案,但沒有發現。如何在Tkinter的Button小部件中創建多個標籤?
非常感謝您提前。
您可以將您的標籤放在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的上標/下標。
非常感謝。我從來沒有想過我可以有一個框架作爲一個按鈕的孩子。正如你所說,我必須小心處理事件。現在,我有了一個新想法來創建一個圖像並將其放在按鈕上。 非常感謝。 – Hasan
偉大的方法。這個答案值得更多讚賞 –