Tkinter - 动态字体大小更改

时间:2015-12-09 06:46:09

标签: python fonts tkinter python-3.5

我已经尝试了很多东西,并且到处寻找如何动态更改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)

然而它所做的只是更改光标后面字母的大小,只有当有一个字母时,才会进一步输入原来的字体大小。

1 个答案:

答案 0 :(得分:0)

修改

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

新版本

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

当选择新的字体大小时,写入的文本将获得带有开始和结束索引的标记,并使用正确的字体大小进行配置。然后它将设置新的字体大小,将其设置为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()来设置标记。或者最后输入的文字没有标签。

OLD VERSION:

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

在下面的示例代码中,当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())

希望你能用它来建立自己更好的版本:)