【问题标题】:How to only change font size of text widget in tkinter(not family)如何仅更改 tkinter 中文本小部件的字体大小(不是系列)
【发布时间】:2017-07-15 06:03:46
【问题描述】:

我正在尝试在 tkinter 中制作一个文本编辑器。

我正在更改标签属性上的字体大小和字体系列,但问题是当我更改字体系列时,所选文本的大小恢复为默认值,而当我更改字体大小时,字体系列恢复为默认值。 我尝试了很多东西

def changeFontSize2():
     textPad.tag_add("bt2", "sel.first", "sel.last")
     textPad.tag_config("bt2",font = (False,2))

def changeFontSize6():
     textPad.tag_add("bt6", "sel.first", "sel.last")
     textPad.tag_config("bt6",font = (False,6))

def changeFontFamily1():
     textPad.tag_add("btArial", "sel.first", "sel.last")
     textPad.tag_config("btArial",font = ("Arial",False))

def changeFontFamily2():
      textPad.tag_add("btCourierNew", "sel.first", "sel.last")
      textPad.tag_config("btCourierNew",font = ("Courier New",False))

【问题讨论】:

  • 我现在要去某个地方。我会在晚上检查。希望我能得到一个有用的答案
  • 我认为这确实是 tkinter 的极限 :(。但我仍然希望我能在明天得到完美的答案。请通过一些代码进行评估。我现在要睡觉了。晚安
  • 这不是 tkinter 的限制。在您发布的代码中,您将False 作为家庭(或大小)传递,这是不正确的用法。您不能将False 作为这些参数之一传递。这里唯一的限制是您的代码中的限制。

标签: python python-2.7 tkinter tkinter-canvas


【解决方案1】:

如果您想将字体配置为与现有字体完全相同但稍作更改,您可以基于现有字体创建新字体对象,然后配置该新字体对象的属性。

例如:

...
import tkinter.font as tkFont
...

def changeFontSize2():
    textPad.tag_add("bt2", "sel.first", "sel.last")

    new_font = tkFont.Font(font=textPad.cget("font"))
    size = new_font.actual()["size"]
    new_font.configure(size=size+2)
    textPad.tag_config("bt2", font=new_font)

但是,完全按照上面的方式进行操作会导致内存泄漏,因为每次调用函数时都会创建新的字体对象。最好是预先创建所有字体,或者想出一种动态创建字体然后缓存它们的方法,这样你只创建一次字体。

例子:

fonts = {}
...
def changeFontSize2():
    name = "bt2"
    textPad.tag_add("bt2", "sel.first", "sel.last")

    if name not in fonts:
        fonts[name] = tkFont.Font(font=textPad.cget("font"))
        size = fonts[name].actual()["size"]
        fonts[name].configure(size=size+2)
        textPad.tag_configure(name, font=fonts[name])

我的建议是在程序开始时创建一次字体和标签,而不是动态创建它们。

fonts = {
    "default": tkFont.Font(family="Helvetica", size=12),
    "bt2": tkFont.Font(family="Helvetica", size=14),
    "btArial", tkFont.Font(family="Arial", size=12),
    ...
}
textPad.configure(font=fonts["default"])
textPad.tag_configure("bt2", font=fonts["bt2"])
textPad.tag_configure("btArial", font=fonts["btArial"])
...
def changeFontSize2():
    textPad.tag_add("bt2", "sel.first", "sel.last")

tkinter 字体对象非常强大。创建字体并使用它后,如果您重新配置字体(例如:fonts["bt2"].configure(family="Courier")),使用该字体的每个地方都会立即更新以使用新配置。

【讨论】:

  • 您好,我尝试了所有方法。但问题是一样的。使用字典仍然会将大小和系列更改为默认值。
  • 我认为这确实是 tkinter 的极限 :(。但我仍然希望我能在明天得到完美的答案。请通过一些代码进行评估。我现在要睡觉了。晚安
  • @BurhanAsif:tkinter 没有限制。如果你不改变家庭,家庭就不会改变。
【解决方案2】:

正如您所说,有很多方法可以达到预期的效果。由于在数小时后没有其他选项出现,因此这里有一个无论如何都可以使用的选项。我将字体的格式集中到一个函数中,并使用来自各个按钮的不同参数调用它。

def setSelTagFont(family, size):
    curr_font = textPad.tag_cget('sel', "font")
    # Set default font information
    if len(curr_font) == 0:
        font_info = ('TkFixedFont', 10)
    elif curr_font.startswith('{'):
        font_info = curr_font.replace('{','').replace('} ','.').split('.')
    else:
        font_info = curr_font.split()

    # Apply requested font attributes
    if family != 'na':
        font_info = (family, font_info[1])
    if str(size) != 'na':
        font_info = (font_info[0], size)
    textPad.tag_config('sel', font=font_info)
    print("Updated font to:", font_info)

root = Tk()
textPad = Text(root)
textPad.pack()
textPad.insert(1.0, "Test text for font attibutes")
textPad.tag_add("sel", 1.0, END + '-1c')
textPad.focus_set()
frame = Frame(root)
frame.pack()
Button(frame, text="Size 2", command=lambda: setSelTagFont('na', 2)).pack(side='left',padx=2)
Button(frame, text="Size 6", command=lambda: setSelTagFont('na', 6)).pack(side='left',padx=2)
Button(frame, text="Family 1", command=lambda: setSelTagFont('Arial', 'na')).pack(side='left',padx=2)
Button(frame, text="Family 2", command=lambda: setSelTagFont('Courier New', 'na')).pack(side='left',padx=2)
root.mainloop()

【讨论】:

  • 选择改变时样式消失。我正在考虑相同的方法,但是对于具有 2 种不同字体的选定文本,情况会变得更糟
  • 那我晚上试试。非常感谢
  • @PRMoureu -- 我同意。需要一种更复杂的方法来提供对多个标签的控制,就像原始帖子试图做的那样。也许在 setSelTagFont 函数中添加一个 tag_name 会是一个很好的增强...
  • 如果你想要一个字体的信息,你可以创建一个字体对象,然后查询字体属性——font.actual()会返回一个字典,包含家族、大小等。不需要做对字体信息进行一些字符串操作。
  • 仍然没有运气。选择更改时样式会更改。
猜你喜欢
  • 1970-01-01
  • 2011-05-03
  • 2015-08-21
  • 1970-01-01
  • 2019-07-03
  • 2012-04-07
  • 1970-01-01
  • 2017-02-15
  • 2013-01-22
相关资源
最近更新 更多