【问题标题】:Tkinter - Dynamic Font Size ChangingTkinter - 动态字体大小更改
【发布时间】:2015-12-15 16:41:01
【问题描述】:

我几乎尝试了所有方法,并到处寻找如何在Text() 小部件中动态更改字体。我不希望 Text() 小部件中的所有文本仅更改字体大小更改后键入的文本,例如页面或单词等。

这是我想象中的效果:

#in the __init__ function
    sizesList = [8, 10, 12, 13, 14, 16, 18, 22, 26, 32, 40]
    var = IntVar()
    var.set(13)
    self.fontsizeDropDown = OptionMenu(self.toolbarFrame, var, *sizesList, command=self.fontSizeFunc)
    self.fontsizeDropDown.grid(row=0, column=1, sticky=N)

def fontSizeFunc(self, var):
    theFont = "Arial %d" % var
    self.textentry.tag_add('texthere', INSERT, INSERT)
    self.textentry.tag_config('texthere', font=theFont)

但是它所做的只是改变光标后字母的大小,只有当那里有一个字母时,任何进一步的输入都会恢复到原来的字体大小。

【问题讨论】:

  • 尝试将第二个 INSERT 更改为 END,这样您就可以在配置的标签内输入。
  • @TerryJanReedy 我也试过了,光标大小会改变,并保持在指定的字体大小,但是键入的文本仍然是默认大小。然后当我将光标移动到一些文本的中间并更改字体大小时,从光标到文本末尾的文本更改为指定的大小。

标签: python fonts tkinter python-3.5


【解决方案1】:

编辑:

想出了另一种我更喜欢的方法,所以把它放在上面,下面是旧的作为参考。

新版本:

代码需要跟踪标签索引的开始和结束位置。它还将为每种字体大小设置一个唯一的标签名称。我认为一个好的标签名称可以与标签配置所使用的字体和大小相同。

选择了新的字体大小时,书面的文本将获得带有启动和结束索引的标签,并配置为适当的字体大小。然后它将设置新的字体大小,将其设置为 Text Widget 并更新变量。在您再次更改字体大小之前,不会添加标签。但是由于 Text Widget 具有当前选择的字体大小,它会以正确的大小显示。

import sys
import tkinter as tk
from tkinter import ttk


def main():
    def current_index():
        # Return current cursor position in the text widget
        return textentry.index(tk.INSERT)

    def fontSizeFunc(*new_var):
        # Set the tag for the text that has been written
        textentry.tag_add(current_tag.get(), start_index.get(), current_index())
        textentry.tag_config(current_tag.get(), font=current_tag.get())

        # Sets new Font Size, store start_index position for new tag,
        # create a new tag that has theFont as tag name
        theFont = "Arial %d" % new_var
        textentry.configure(font=theFont)
        start_index.set(current_index())
        current_tag.set(theFont)

    # Simple Tkinter setup for testing purpose
    root = tk.Tk()

    sizesList = [8, 10, 12, 13, 14, 16, 18, 22, 26, 32, 40]
    var = tk.IntVar()
    var.set(13)

    frame = ttk.Frame(root)
    frame.grid(column=0, row=0)
    fontsizeDropDown = tk.OptionMenu(frame, var, *sizesList, command=fontSizeFunc)
    fontsizeDropDown.grid(row=0, column=1, sticky=tk.N)
    textentry = tk.Text(frame)
    textentry.grid(row=1, column=0, columnspan=2)

    # Initialize start_index and current_tag
    start_index = tk.StringVar()
    current_tag = tk.StringVar()
    start_index.set(current_index())
    current_tag.set("Arial %d" % var.get())

    root.mainloop()

if __name__ == '__main__':
    sys.exit(main())

如果您想将文本存储在 Text Widget 中,请记住在退出/存储之前通过调用 fontSizeFunc() 来设置标签。否则最后输入的文本将没有标签。

旧版本:

我在想,如果你想进行动态更改,你必须检查文本小部件是否有更改。每次使用选项菜单更改字体大小时,都会创建一个新标签。

在下面的示例代码中,它会在 Text Widget 处于焦点时检查 KeyRelease。当前标签索引将在您键入时展开,当您选择新字体大小时,它将创建一个新标签。尽可能使用您的代码,只需将其调整为无需上课即可工作。

import sys
import tkinter as tk
from tkinter import ttk


def main():
    def text_changes(*event):
        # On every KeyRelease with the Text widget in focus,
        # it get the current tag, start index and current index.
        theFont = "Arial %d" % var.get()
        textentry.tag_add(current_tag.get(), start_index.get(), current_index())
        textentry.tag_config(current_tag.get(), font=theFont)

    def current_index():
        # Return current cursor position in the text widget
        return textentry.index(tk.INSERT)

    def fontSizeFunc(*new_var):
        # Create a new tag with a new start index / position
        start_index.set(current_index())
        current_tag.set(current_index())

    # Simple Tkinter setup for testing purpose
    root = tk.Tk()

    sizesList = [8, 10, 12, 13, 14, 16, 18, 22, 26, 32, 40]
    var = tk.IntVar()
    var.set(13)

    frame = ttk.Frame(root)
    frame.grid(column=0, row=0)
    fontsizeDropDown = tk.OptionMenu(frame, var, *sizesList, command=fontSizeFunc)
    fontsizeDropDown.grid(row=0, column=1, sticky=tk.N)
    textentry = tk.Text(frame)
    textentry.grid(row=1, column=0, columnspan=2)

    # Initialize start_index and current_tag
    start_index = tk.StringVar()
    current_tag = tk.StringVar()
    start_index.set(current_index())
    current_tag.set(current_index())

    # When the text entry has focus, every key release will run the
    # text_changes function
    textentry.bind('<KeyRelease>', text_changes)

    root.mainloop()

if __name__ == '__main__':
    sys.exit(main())

希望你可以用它来构建你自己的更好的版本:)

【讨论】:

    猜你喜欢
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    • 2011-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-07
    相关资源
    最近更新 更多