tkinter画布:文本对象可变字体大小?

4 投票
1 回答
4976 浏览
提问于 2025-04-17 13:27

我正在用tkinter的画布制作一些漂亮的图形,并在圆圈上方叠加文字,就像下面这张图片一样:

http://static.guim.co.uk/sys-images/Guardian/Pix/pictures/2012/11/6/1352220546059/Causes-of-deaths-graphic-008.jpg

我希望字体的大小能够根据圆圈的大小来变化。

tempfont = tkFont.Font(family='Helvetica',size=int(round(ms*topnode[1])))
self.display.create_text(center[0],center[1],fill = "#FFFFFF",text = int(round(ms*topnode[1])),font = tempfont)

我的问题是,当我使用上面的代码时,叠加的文字大小对每个文本对象来说都是固定的。虽然文本内容是正确的,也就是显示了我想要的数字,但字体大小却不对。我尝试过在大小定义中使用固定的整数(这样是正常工作的),并在上面两行代码后面立即添加了一个del(tempfont),但我还没有找到解决这个问题的方法。

我哪里做错了呢?

这里有一个简单的程序,可以重现这个问题:

from Tkinter import *
import tkFont

class TestApp(Frame):
    def __init__(self, master=None, height = 160, width = 400):
        Frame.__init__(self, master)
        self.grid()
        self.createWidgets()

    def createWidgets(self):
        self.display = Canvas(self, width = 800, height = 320, bg = "#FFFFFF")
        self.display.grid(row=0,column=0)

        def recurtext(tsize):
            if tsize > 20:
                recurtext(tsize-10)
            tempfont = tkFont.Font(family='Helvetica',size=tsize)
            self.display.create_text(800 - (tsize*12),160, text = str(tsize), font = tempfont)

        recurtext(60)

app = TestApp()
app.master.title("Test")
app.mainloop()

关键是recurtext会递归地调整字体大小,而shows应该会以那个大小输出字体...或者我认为应该是这样。也许这是tkinter的一个bug,但我仍然希望是我在逻辑上犯了错误。

1 个回答

2

我以前从来没有遇到过这种情况;这看起来像是Tkinter的一个错误。不过好消息是,似乎有个解决办法。如果你给每种字体起个独特的名字,这个问题就好像消失了一样。

下面的例子展示了多行文本,每行都有不同的字体大小:

import Tkinter as tk
import tkFont

class Example(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)

        self.display = tk.Canvas(self, width=400, height=600, background="black")
        self.display.pack(side="top", fill="both", expand=True)
        y = 10
        for size in range (2, 38, 2):
            tempfont = tkFont.Font(family='Helvetica',size=size, 
                                   name="font%s" % size)
            self.display.create_text(10, y, fill = "#FFFFFF",text = size, 
                                     font = tempfont, anchor="nw")
            y = y + tempfont.metrics()["linespace"]

if __name__ == "__main__":
    root = tk.Tk()
    frame = Example(parent=root)
    frame.pack(side="top", fill="both", expand=True)

    root.mainloop()

撰写回答