4

create_text() ループ内で、Tkinter キャンバスのボックスにテキストを表示するプログラムを作成しています。各単語が表示され、次の単語に置き換えられます。フラッシュカードのようなもの。

ユーザーが単語を読んでいるときに目が単語の中央に集中するように、各単語の 1 文字の単語の中央付近に色を付ける必要があります。などif len(i)=1, color i[0], if len(i)>= 2 and <= 5, color i[1]など。キャンバスを使用して行う必要があります。

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

結果はこのように印刷されるはずです

exaMple

(ただし、明らかに「m」は大文字ではなく赤になります)

4

2 に答える 2

3

私はあなたがこのようなものが欲しいと思いますか?

これが今のところ入手できる最も近いものです。3 つのテキスト ボックスを作成し、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()

OK、 Bryan Oakley のコメントからのリンクを使用して、コードをさらに改善して、等幅フォントだけでなく、任意のフォントで動作するようにしました。このコードは、色付きの文字の中心を同じ場所に保ち、単語の前後を正しい距離に配置します。

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()
于 2015-03-31T15:07:04.707 に答える
2

キャンバス テキスト アイテムの個々の文字に書式を適用することはできません。赤い文字用に個別の項目を作成し、文字列の上に重ねるには少し計算する必要があります。

キャンバスを使用する必要がない場合は、単一の文字に書式を適用するのが簡単なテキスト ウィジェットをお勧めします。完全な動作例を次に示します。

import Tkinter as tk

words = '''
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi mi leo, vulputate a consectetur in, congue sit amet elit. Fusce lacinia placerat mi, vitae maximus leo congue sed. Donec non diam dapibus, fringilla risus at, interdum sem. Interdum et malesuada fames ac ante ipsum primis in faucibus. 
'''.strip().split()

class Example(tk.Frame):
   def __init__(self, parent):
      tk.Frame.__init__(self, parent)
      self.text = tk.Text(self, wrap=None, font="Helvetica 24",
                          highlightthickness=0)
      self.text.pack(side="top", fill="x")

      self.text.tag_configure("center", justify="center")
      self.text.tag_configure("red", foreground="red")

      self.show_words(0)

   def show_words(self, index):
      self.show_word(words[index])
      next = index + 1 if index < len(words)-1 else 0
      self.after(200, self.show_words, next)

   def show_word(self, word):
      self.text.configure(state="normal")
      self.text.delete("1.0", "end")
      self.text.insert("1.0", word, "center")
      offset = len(word)/2
      self.text.tag_add("red", "1.0 + %sc" % offset)
      self.text.configure(state="disabled")

if __name__ == "__main__":
   root = tk.Tk()
   Example(root).pack(fill="both", expand=True)
   root.mainloop()
于 2015-03-31T15:57:13.270 に答える