我在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()
此处最重要的部分是font=('Helvetica', '15')
或更具体地说,数字15 。如果您更改了该号码并再次运行,则不仅文字会更大/更小,,按钮也是如此!我该如何解决这个问题?
这可能是真正的简单问题。我刚刚开始使用Tkinter。提前感谢我收到的任何帮助!
答案 0 :(得分:3)
通常,当您为按钮指定宽度时,该宽度以字符为单位进行测量(即: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()
所有这一切,几乎从来都没有这个好主意。如果用户想要更大的字体,整个UI应该适应。 Tkinter非常善于实现这一目标,以至于默认情况下这一切都很常见。
答案 1 :(得分:2)
按钮的宽度以字符宽度为单位定义。在您的情况下,按钮被定义为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()
编辑:基于我从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)
我还应该补充一点,我非常同意布莱恩:使用这可能表明你做错了。你应该让tkinter处理大小调整。
答案 2 :(得分:0)
我找到了解决此问题的方法。我试图解决一个类似的问题:我想将图像放在标签上。我将图像尺寸设置为等于标签尺寸。当我尝试使用命令label.config(image=img)
放置标签时,标签尺寸会增大。图片具有我设置的尺寸,因此没有完全覆盖标签。我正在使用网格管理器。所有尺寸均未预先输入,而是由Tkinter计算得出。我正在使用grid_columnconfigure
和grid_rowconfigure
。我找到的解决方案是将带有图像的标签(或您的情况下的按钮)放置到LabelFrame
上,并将grid_propagate
设置为False
。
代码示例:
MyWindow = tk.Tk()
MyWindow.geometry("500x550")
#create LabelFrame (200x200)
label = tk.LabelFrame(MyWindow, width=200, height=200)
#grid manager to set label localization
labelk.grid(row=0, column=0)
#label row and column configure: first argument is col or row id
label.grid_rowconfigure(0, weight=1)
label.grid_columnconfigure(0, weight=1)
#cancel propagation
label.grid_propagate(False)
#Create button and set it localization. You can change it font without changing size of button, but if You set too big not whole will be visible
button = t.Button(label, text="Hello!", font=('Helvetica', '20'))
#Use sticky to button took up the whole label area
button.grid(row=0, column=0, sticky='nesw')
MyWindow.mainloop()
字体大小为40和20的结果:
由网格管理器创建具有动态尺寸的按钮的示例:
MyWindow = tk.Tk()
MyWindow.geometry("500x550")
#Divide frame on 3x3 regions
for col in range(3):
MyWindow.grid_columnconfigure(col, weight=1)
for row in range(3):
MyWindow.grid_rowconfigure(row, weight=1)
label = tk.LabelFrame(MyWindow)
#Put label in the middle
label.grid(row=1, column=1, sticky='nesw')
label.grid_propagate(False)
label.grid_rowconfigure(0, weight=1)
label.grid_columnconfigure(0, weight=1)
button = tk.Button(label, text="Hello!", font=('Helvetica', '30'))
button.grid(row=0, column=0, sticky='nesw')
MyWindow.mainloop()
答案太晚了,但也许会对别人有所帮助。