更改字体大小而不会弄乱Tkinter按钮大小

时间:2017-03-16 16:45:07

标签: python user-interface button tkinter 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()

此处最重要的部分font=('Helvetica', '15')或更具体地说,数字15 。如果您更改了该号码并再次运行,则不仅文字会更大/更小,,按钮也是如此!我该如何解决这个问题?

这可能是真正的简单问题。我刚刚开始使用Tkinter。提前感谢我收到的任何帮助!

3 个答案:

答案 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_columnconfiguregrid_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的结果:

Image for font size 40 Image for font size 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()

答案太晚了,但也许会对别人有所帮助。