war*_*ing 6 python user-interface tkinter button font-size
我在更改Tkinter 中按钮的字体大小时遇到问题,当我尝试这样做时,按钮也会根据文本大小进行扩展/收缩。有没有一种方法可以改变文本大小,并将按钮的大小固定到位?
我在设计井字游戏应用程序时遇到了这个问题,但是为了省去麻烦,这里是实践中问题的一个非常小的例子:
import Tkinter as tk
MyWindow = tk.Tk()
MyWindow.geometry("500x550")
button = tk.Button(MyWindow,text="Hello!",width=17,height=10,font=('Helvetica', '20'))
button.grid(row=1, column=1)
MyWindow.mainloop()
Run Code Online (Sandbox Code Playgroud)
这里最重要的部分是font=('Helvetica', '15')或更具体地说,数字 15。如果您更改该数字并再次运行它,不仅文本会变大/变小,按钮也会变大/变小!我该如何解决这个问题?
这可能是一个非常简单的问题。我刚刚开始使用 Tkinter。在此先感谢我收到的任何帮助!
通常,当您为按钮指定宽度时,该宽度以字符为单位(即:width=1表示一个平均大小字符的宽度)。但是,如果按钮具有图像,则宽度以像素为单位指定大小。
按钮可以同时包含图像和文本,因此一种策略是将 1x1 像素作为图像,以便您可以以像素为单位指定按钮大小。当你这样做并改变字体大小时,按钮不会增长,因为它被赋予了绝对大小。
这是一个说明该技术的示例。运行代码,然后单击“更大”或“更小”以查看文本更改大小但按钮没有更改。
import Tkinter as tk
import tkFont
def bigger():
size = font.cget("size")
font.configure(size=size+2)
def smaller():
size = font.cget("size")
size = max(2, size-2)
font.configure(size=size)
root = tk.Tk()
font = tkFont.Font(family="Helvetica", size=12)
toolbar = tk.Frame(root)
container = tk.Frame(root)
toolbar.pack(side="top", fill="x")
container.pack(side="top", fill="both", expand=True)
bigger = tk.Button(toolbar, text="Bigger", command=bigger)
smaller = tk.Button(toolbar, text="Smaller", command=smaller)
bigger.pack(side="left")
smaller.pack(side="left")
pixel = tk.PhotoImage(width=1, height=1)
for row in range(3):
container.grid_rowconfigure(row, weight=1)
for column in range(3):
container.grid_columnconfigure(column, weight=1)
button = tk.Button(container, font=font, text="x",
image=pixel, compound="center", width=20, height=20)
button.grid(row=row, column=column)
root.mainloop()
Run Code Online (Sandbox Code Playgroud)
话虽如此,几乎从来没有时候这是一个好主意。如果用户想要更大的字体,整个 UI 应该适应。Tkinter 非常擅长实现这一点,以至于它在默认情况下几乎都能正常工作。
按钮的宽度以字符宽度为单位定义。在您的例子中,按钮被定义为 17 个字符宽。因此,通过更改字符宽度(即更改字体大小)会更改按钮的宽度。AFAIK,解决这个问题的唯一方法是将按钮放入框架中,因为框架可以定义其大小(以像素为单位)。这是一种新的 Button,它的作用正是如此:
import Tkinter as tk
class Warspyking(tk.Frame):
'''A button that has it's width and height set in pixels'''
def __init__(self, master=None, **kwargs):
tk.Frame.__init__(self, master)
self.rowconfigure(0, minsize=kwargs.pop('height', None))
self.columnconfigure(0, minsize=kwargs.pop('width', None))
self.btn = tk.Button(self, **kwargs)
self.btn.grid(row=0, column=0, sticky="nsew")
self.config = self.btn.config
#example usage:
MyWindow = tk.Tk()
MyWindow.geometry("500x550")
from itertools import cycle
fonts = cycle((('Helvetica', '11'),('Helvetica', '15'),('Helvetica', '20')))
def chg():
button.config(font=next(fonts))
button = Warspyking(MyWindow,text="Click me!",width=200,height=100 ,font=next(fonts), command=chg)
button.grid(row=1, column=1)
MyWindow.mainloop()
Run Code Online (Sandbox Code Playgroud)
编辑:根据我从 Bryan Oakley 学到的知识,这里有一个更简洁的实现:
class Warspyking(tk.Button):
def __init__(self, master=None, **kwargs):
self.img = tk.PhotoImage()
tk.Button.__init__(self, master, image=self.img, compound='center', **kwargs)
Run Code Online (Sandbox Code Playgroud)
我还应该补充一点,我非常同意布莱恩的观点:使用这个可能表明你做错了什么。您应该让 tkinter 处理大小调整。