python - 如何在 Tkinter Canvas 中为子字符串着色

标签 python tkinter tkinter-canvas

我正在编写一个程序,涉及在 create_text() 中显示一些文本Tkinter Canvas 上的框,在一个循环中。显示每个单词,然后由下一个替换。有点像闪存卡。

我需要为每个单词的一个字母着色,靠近单词的中间,这样当用户阅读单词时,他们的眼睛会聚焦在单词的中间。所以if len(i)=1, color i[0], if len(i)>= 2 and <= 5, color i[1] , 等等。它需要使用 Canvas 完成,并使用

canvas.create_text(text = i[focus_index],fill = 'red') 

结果应该这样打印

exaMple

(但显然“m”会变成红色,而不是大写)

最佳答案

我假设你想要类似 this 的东西?

这是我目前能得到的最接近的。它创建了三个文本框并使用 anchor 属性将它们保持在正确的位置。但是,它对于非常宽或窄的字母效果不是很好。它并不完美,但可能是一个开始。

import Tkinter as tk

root = tk.Tk()

c = tk.Canvas(root)
c.pack(expand=1, fill=tk.BOTH)

words = '''I am writing a program that involves displaying some text in a create_text() box on a Tkinter canvas, within a loop. Each word is displayed, then replaced by the next. Sort of like flash cards. I need to color one letter of each word, close to the middle of the word, so that when the user is reading the words their eyes focus on the middle of the word. So if len(i)=1, color i[0], if len(i)>= 2 and <= 5, color i[1], and so on. It needs to be done using the Canvas, and using canvas.create_text(text = i[focus_index],fill = 'red') The result should print like this exaMple (but obviously "m" would be colored red, not be uppercase)'''
words = words.split()

def new_word(i):
    if i == len(words):
        i = 0

    word = words[i]
    middle = (len(word)+1)//2
    c.itemconfigure(t1, text=word[:middle-1]+' ')
    c.itemconfigure(t2, text=word[middle-1:middle])
    c.itemconfigure(t3, text=word[middle:])

    root.after(100, lambda: new_word(i+1))


t1 = c.create_text(200,100,text='', anchor='e', font=("Courier", 25))
t2 = c.create_text(200,100,text='', anchor='e', font=("Courier", 25), fill='red')
t3 = c.create_text(200,100,text='', anchor='w', font=("Courier", 25))
new_word(0)

root.geometry('400x200+200+200')
root.mainloop()

好的,使用来自 Bryan Oakley's comment 的链接,我进一步改进了代码,使其适用于任何字体,而不仅仅是等宽字体。该代码将彩色字母的中心保持在同一位置,并将单词的前后放置在其周围的正确距离处。

import Tkinter as tk
import tkFont

root = tk.Tk()
c = tk.Canvas(root)
c.pack(expand=1, fill=tk.BOTH)

fn = "Helvetica"
fs = 24
font = tkFont.Font(family=fn, size=fs)

words = '''I am writing a program that involves displaying some text in a create_text() box on a Tkinter canvas, within a loop. Each word is displayed, then replaced by the next. Sort of like flash cards. I need to color one letter of each word, close to the middle of the word, so that when the user is reading the words their eyes focus on the middle of the word. So if len(i)=1, color i[0], if len(i)>= 2 and <= 5, color i[1], and so on. It needs to be done using the Canvas, and using canvas.create_text(text = i[focus_index],fill = 'red') The result should print like this exaMple (but obviously "m" would be colored red, not be uppercase)'''
words = words.split()

def new_word(i):
    if i == len(words):
        i = 0

    word = words[i]
    middle = (len(word)+1)//2

    front = word[:middle-1]
    letter = word[middle-1:middle]
    back = word[middle:]

    c.itemconfigure(t1, text=front)
    c.itemconfigure(t2, text=letter)
    c.itemconfigure(t3, text=back)
    c.coords(t1, 200-font.measure(letter)/2, 100)
    c.coords(t3, 200+font.measure(letter)/2, 100)

    root.after(100, lambda: new_word(i+1))


t1 = c.create_text(200,100,text='', anchor='e', font=font)
t2 = c.create_text(200,100,text='', anchor='c', font=font, fill='red')
t3 = c.create_text(200,100,text='', anchor='w', font=font)
new_word(0)

root.geometry('400x200+200+200')
root.mainloop()

关于python - 如何在 Tkinter Canvas 中为子字符串着色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29368737/

相关文章:

python - 查询 django 中的多位字段列表返回的结果比预期多

python - 如何将 Seaborn 图集成到 Tkinter GUI 中

python-2.7 - 滚动文本 "spill over"顶部边框内的复选按钮

python - 在文本框 python 中以特定格式插入列表中的值

python - 创建后如何更改 tkinter Canvas 的背景颜色?

python - 在 Python 2.7 中打印带反斜杠的字符串

python - 实时向点云添加新点 - Open3D

python-3.x - python tkinter tag_bind 在循环内不工作

python - 从文件夹中打开多个Python文件

Python 3 unicode 编解码器错误在 tkinter 中绑定(bind)鼠标滚轮