このページでは、Tkinter の「テキストウィジェット」の作成方法・使い方・設定方法等について説明していきたいと思います。
Contents
- テキストウィジェットとは
- テキストウィジェットの使い方
- テキストウィジェットの設定
- font
- width
- height
- background
- foreground
- borderwidth
- relief
- state
- padx・pady
- selectbackground
- selectforeground
- inactiveselectbackground
- highlightthickness
- highlightcolor・highlightbackground
- blockcursor
- insertbackground
- insertwidth
- insertborderwidth
- insertontime・insertofftime
- insertunfocussed
- wrap
- spacing1・spacing2・spacing3
- undo・maxundo・autoseparators
- cursor
- xscrollcommand・yscrollcommand
- Text クラスのメソッド
- まとめ
テキストウィジェットとは
まずは、今回解説する「テキストウィジェット」がどのようなウィジェットであるのかについて簡単に説明していきます。
テキストウィジェット=テキストボックス
テキストウィジェットは、一言で言えばテキストボックスです。
このテキストウィジェットを GUI アプリ上に表示することで、ユーザーからの文字列入力を受け付けることができるようになります。
基本的には、このテキストウィジェットをアプリ上に表示し、ユーザーに入力された文字列を利用して何かしらの処理を行うというのが、テキストウィジェットを扱うアプリの基本的な動作になると思います。
スポンサーリンク
エントリーとの違い
下記ページで紹介しているエントリーウィジェットでもユーザーからの文字列入力を受け付けることは可能です。ですが、エントリーウィジェットの場合は入力欄が1行となります。それに対し、テキストウィジェットの場合は入力欄が複数行となります。
Tkinterの使い方:エントリー(Entry)の使い方なので、単語や名前やファイルパスの入力受付を実施する際にはエントリーウィジェットを利用すればよいのですが、複数行にまたがるような文字列の入力受付、例えば掲示板のコメントや自己紹介文の入力受付を行うような場合はテキストウィジェットを利用することになります。
もちろん、テキストウィジェットでパスや単語の入力受付を行っても良いのですが、エントリーウィジェットの方が使い方がシンプルであるため、可能であればエントリーウィジェットを利用する方が良いと思います。
テキストウィジェットの使い方
続いては、テキストウィジェットの使い方について解説していきたいと思います。
まずは、テキストウィジェットを利用することで実現できることを理解していただくため、テキストウィジェットを利用した簡単なアプリのスクリプト例を示したいと思います。
import tkinter
def open_text():
# エントリーに入力されたパスのファイルを読み込む
f = open(entry.get(), encoding='utf-8')
read_text = f.read()
f.close()
# テキストウィジェットの中身を空にする
text.delete('1.0', 'end - 1 chars')
# テキストウィジェットの先頭に読み込んだデータを挿入する
text.insert('1.0', read_text)
def save_text():
# テキストウィジェットに入力された全文字列を取得する
save_text = text.get('1.0', 'end - 1 chars')
# 取得した文字列をエントリーに入力されたパスに保存する
f = open(entry.get(), 'w', encoding='utf-8')
f.write(save_text)
f.close()
# メインウィンドウを作成
app = tkinter.Tk()
app.geometry('500x350')
# テキストウィジェットを作成して配置
text = tkinter.Text(
app,
font=('', 20),
width=20,
height=5,
undo=True
)
text.pack(padx=10, pady=10)
# パスの入力受付用エントリーを作成して配置
entry = tkinter.Entry(
app,
font=('', 20)
)
entry.pack(padx=10, pady=10)
# ファイルを開く用のボタンを作成して配置
open_button = tkinter.Button(
app,
text='開く',
font=('', 20),
command=open_text
)
open_button.pack(padx=10, pady=10)
# ファイルへの保存用のボタンを作成して配置
save_button = tkinter.Button(
app,
text='保存',
font=('', 20),
command=save_text
)
save_button.pack(padx=10, pady=10)
# メインループ
app.mainloop()
このスクリプトを実行すれば、次の図のようなアプリが起動します。
ラベルなどを全く付けてないの分かりにくいのですが、一番上に表示されているウィジェットが「テキストウィジェット」になります。テキストウィジェットをクリックして文字列を入力すれば、入力された文字列がテキストウィジェット内に表示されることが確認できると思います。
また、文字の入力や削除を行ってから「元に戻す」を実行すれば(Windows の場合は Ctrl
+ Z
・Mac の場合は command
+ Z
)、直前の操作を取り消すことも可能ですし、他のアプリからコピーした文字列の貼り付けを実行すれば(Windows の場合は Ctrl
+ V
・Mac の場合は command
+ V
)、その文字列がテキストウィジェットに貼り付けされることも確認できるはずです。このように、テキストウィジェットは作成して配置するだけで、Windows のメモ帳のような簡単なテキストエディターとして利用することができます。
また、テキストウィジェットの下に表示されているエントリーウィジェットにファイルパスを入力して 保存
ボタンをクリックすれば、テキストウィジェット内の全文字列を、入力されたファイルパスにテキストファイルとして保存することができます。また、同様にエントリーウィジェットにテキストファイルのパスを入力し、今度は 開く
ボタンをクリックすれば、そのファイルパスのファイル内の文字列が読み込まれてテキストウィジェットに表示されることになります。
上記のスクリプトにおいては、開く
ボタンがクリックされた際にはテキストウィジェットに入力されている文字列をクリアし、その後にファイルから読み込んだ文字列をテキストウィジェットに挿入するようになっています。また、保存
ボタンがクリックされた際にはテキストウィジェットに入力されている文字列を全て取得し、それをファイルとして保存するようにしています。
こういった、テキストウィジェット内の文字列に対する操作も、テキストウィジェットのメソッドを利用して実現することが可能です。
テキストウィジェットの作成
次は、テキストウィジェットの使い方の手順を説明していきます。
まず、テキストウィジェットを使うためにはテキストウィジェットの作成が必要となります。
テキストウィジェットは、tkinter の Text
クラスのコンストラクタを実行することで作成することができます。第1引数には、そのテキストウィジェットの配置先となるウィジェット(メインウィンドウなど)を指定します。
# app はメインウィンドウ等の親ウィジェット
text = tkinter.Text(
app
)
テキストウィジェットの場合は、コンストラクタ実行時に必須となるのは第1引数(配置先ウィジェット)のみです。ただし、テキストウィジェットに入力される文字列のフォントを変更したい場合は font
引数、テキストウィジェットの幅や高さを調整したい場合は width
引数や height
引数の指定も必要となります。また、テキストウィジェットに対する文字の入力や削除に対する取り消し・やり直し操作を行いたいのであれば、undo=True
の指定も必要となります。
他の引数についても テキストウィジェットの設定 で紹介しますが、正直言ってテキストウィジェットのコンストラクタに指定可能な引数はかなり多いです。ですが、特に重要なのは上記で挙げた font
・width
・height
・undo
くらいになると思います。なのでテキストウィジェットを初めて使うという方は、まずは、この4つについて覚えておくとよいと思います。
スポンサーリンク
テキストウィジェットの配置
また、他のウィジェット同様に、作成したテキストウィジェットをアプリ上に表示するためにはウィジェットの配置が必要となります。
この配置に関しては他のウィジェットと同様の手順で実施することが可能で、配置の詳細に関しては下記ページでまとめていますので、詳しく知りたい方は下記ページを参照してください。
Tkinterの使い方:ウィジェットの配置(pack・grid・place)先ほど示したスクリプトにおいては、下記でテキストウィジェットの配置を行っています。
text.pack(padx=10, pady=10)
ここまで説明してきたテキストウィジェットの作成と配置を行えば、後は mainloop
を実行することでアプリが起動し、作成したテキストウィジェットがアプリ上に表示されることになります。
テキストウィジェットからの文字列の取得
テキストウィジェットが表示されれば、ユーザーはそのテキストウィジェットに文字列を入力することが可能となります。ただ、この入力された文字列が「何らかの処理」に利用されないとユーザーがテキストウィジェットに文字列を入力する意味が無いですよね…。なので、テキストウィジェットを利用するのであれば、そのテキストウィジェットに入力された文字列を「何らかの処理」に利用するようにアプリを開発した方が良いです。
そして、入力された文字列を利用するためには、まずはテキストウィジェットから入力された文字列の取得を行う必要があります。ということで、テキストウィジェットを利用する場合は、このテキストウィジェットからの文字列の取得方法は理解しておいた方が良いと思います。
このテキストウィジェットからの文字列の取得は、テキストウィジェットに get
メソッドを実行させることで実現可能です。get
メソッドには、下記のように2つのインデックス(index1
引数と index2
引数)を指定して実行します。インデックスは、テキストウィジェット内の位置を示す文字列や定数となります。このインデックスを指定して get
メソッドを実行することで、2つのインデックスで指定された位置の間の文字列を返却値として取得することができます。
# text:テキストウィジェット
text.get(index1, index2)
例えば、テキストウィジェットに入力されている全文字列を取得して print
で出力するのであれば、下記のように get
メソッドを実行することになります。
# text:テキストウィジェット
all_text = text.get(1.0, 'end - 1 chars')
print(all_text)
ここで、'1.0'
はテキストウィジェット内に入力された最初の文字の前の位置を示すインデックスであり、'end - 1 chars'
はテキストウィジェット内に入力された最後の文字の後ろの位置を示すインデックスとなります。
そして、get
メソッドでは引数で指定される2つの位置の間の文字列が取得されるため、上記によってテキストウィジェットに入力されている全文字列を取得することができることになります。
ここで伝えたいことは2つで、1つはテキストウィジェットに入力されている文字列はメソッドによって操作可能であるという点になります。先ほど紹介した get
メソッドは、そのメソッドの一例になります。
もう1つが、それらのメソッドでは、テキストウィジェット内の特定の位置の文字列を操作するものが多く、その位置を指定するために、上記における '1.0'
や 'end - 1 chars'
のような特殊なインデックスを引数に指定する必要があるという点になります。
つまり、テキストウィジェットのメソッドを使いこなすためには利用可能なメソッドを理解するだけでなく、意図通りの位置の文字列に対して操作を行うためにインデックスについても理解しておく必要があります。
ということで、次の節では、このテキストウィジェットにおけるインデックスについて説明します。また、テキストウィジェットで利用可能なメソッドに関しては、後述の Text クラスのメソッド の章で解説を行います。
テキストウィジェットでのインデックスの指定
前述の通り、テキストウィジェットにメソッドを実行させることで、テキストウィジェット内に入力されている文字列に対して操作を行うことが可能となります。
ただし、これらのメソッドでは、テキストウィジェット内のどの位置の文字列に対して操作を行うのかを「インデックス」で指定する必要があります。インデックスとは、テキストウィジェット内の位置を示す文字列(or 定数)となります。
このインデックスとして指定可能な文字列について、ここから説明していきます。
'行番号.列番号'
基本となるのが、この '行番号.列番号'
形式のインデックス指定になります。テキストウィジェット内には2次元的に文字列が入力されていくことになり、その文字列の中の特定の位置を、行番号
と 列番号
で指定します。ややこしいのが、行番号
は文字列の行に対して割り振られるのに対し、列番号
は文字の前後に割り振られるという点になります。
このインデックスは、「挿入カーソルの位置」を示すための値であると考えるとイメージが湧きやすくなると思います。挿入カーソルは文字の前後に表示されることになるため、この 列番号
も文字の前後に割り当てられることになります。そのため、上の図のように、行番号
は 1
から始まるのに対し、列番号
は 0
から始まることになります。
したがって、テキストウィジェット内の先頭の位置を示すインデックスは '1.0'
となります。また、2行目の3文字目の前の位置を示すインデックスは '2.2'
となりますし、2行目の3文字目の後ろの位置を示すインデックスは '2.3'
ということになります。
また、テキストウィジェットでは、行の区切りは改行(図における \n
)となります。1行に長い文字列を入力すれば、(デフォルト設定では)テキストウィジェット内で文字列が折り返しされることになりますが、この折り返しは行の区切りとならないので同じ行として扱われます。なので、折り返しされることで見た目上は複数行となりますが、行番号
としては同じ値の行となります。例えば下記において、インデックス '2.3'
は J
と K
の間の位置ということになります。
'行番号.end'
また、'行番号.end'
形式のインデックスを指定することで、特定の行における、最後の文字の後ろ側の位置を指定することも可能です。例えば '3.end'
は3行目の最後の文字の後ろ側の位置を示すインデックスとなります。
テキストウィジェット内の文字列の各行の最後には必ず改行が存在しますが、この '行番号.end'
は、その 行番号
の改行を含めなかった場合の最後の文字の後ろ側の位置を示すインデックスとして扱われます。
'end'
or tkinter.END
'end'
と tkinter.END
は「テキストウィジェット内の最後の文字の後ろ側の位置」を示すインデックスとなります。先ほど説明した通り、テキストウィジェット内の文字列の各行の最後には改行が存在しますので、これらのインデックスは、その最後の改行の後ろ側の位置を示すことになります。
後述で解説するように、'end'
等のインデックスには '- n chars'
を追加で指定することで、そのインデックスが示す位置を n
文字分前側に移動させることが可能です。ですので、単純に「テキストウィジェット内の最後の文字」の後ろ側の位置を指定したいのであれば、'end - 1 chars'
のインデックスを利用すればよいことになります。
'end - 1 chars'
の場合は、'行番号.end'
のように 行番号
の指定が不要なので、テキストウィジェット内に入力された文字列の行数を意識しなくてもテキストウィジェット内の最後の文字の位置を指定することができて便利です。
'insert'
or tkinter.INSERT
'insert'
と tkinter.INSERT
は「挿入カーソルの位置」を示すインデックスとなります。
通常のテキストエディター同様に、テキストウィジェットにおいても、次の文字の入力位置には挿入カーソルが表示されます。'insert'
と tkinter.INSERT
は、その挿入カーソルの位置を示すインデックスとなります。
'current'
or tkinter.CURRENT
'current'
と tkinter.CURRENT
は「マウスカーソルに一番近い位置」を示すインデックスとなります。
'sel.first'
or tkinter.SEL_FIRST
'sel.first'
と tkinter.SEL_FIRST
は、「選択中の文字列における最初の文字の前側の位置」を示すインデックスとなります。
テキストウィジェット内の文字列はマウス操作等で選択することが可能です。そして、選択されている文字列における、最初の文字の前側の位置を示すのが 'sel.first'
と tkinter.SEL_FIRST
となります。
これらのインデックスを、テキストウィジェット内の文字列が選択されていないタイミングで指定すると下記のような例外が発生するので注意してください。
tkinter.TclError: text doesn't contain any characters tagged with "sel"
'sel.last'
or tkinter.SEL_LAST
'sel.first'
と tkinter.SEL_FIRST
が選択中の文字列における “最初の文字の前側の位置” を示すインデックスであるのに対し、'sel.last'
と tkinter.SEL_LAST
は、「選択中の文字列における “最後の文字の後ろ側の位置”」を示すインデックスとなります。
'sel.first'
と tkinter.SEL_FIRST
同様に、'sel.last'
と tkinter.SEL_LAST
に関しても、テキストウィジェット内の文字列が選択されていないタイミングで指定すると下記のような例外が発生するので注意してください。
tkinter.TclError: text doesn't contain any characters tagged with "sel"
'タグ名.first'
後述の tag_add の節で説明するように、テキストウィジェット内の特定の範囲の文字列には、好きなタグ名の「タグ」を付けることができます。タグ付けを行うことで、そのタグ付けされた範囲の文字列部分のみの設定を行ったりイベントの設定を行ったりすることが可能となります。
また、タグ付けしておくことで、'タグ名.first'
をタグ付けされた範囲の先頭の前側の位置を示すインデックスとして扱うことができるようになります。
'タグ名.last'
同様に、タグ付けしておくことで、'タグ名.last'
を、タグ付けされた範囲の末尾の後ろ側の位置を示すインデックスとして扱うことができるようになります。
'+ n chars'
さて、ここまで示してきたインデックスは「基準位置を示すベースインデックス」であり、これらは単体でも使用可能なのですが、ここから紹介する + n chars
・- n chars
・+ n lines
・- n chars
をベースインデックスに結合することで、ベースインデックスから特定の文字数分 or 行数分シフトした位置を指定することができるようになります。
ただし、これらのシフトが指定した文字数分のみ行われるのはテキストウィジェット内の文字が半角文字(1バイト文字)の場合のみとなります
例えば平仮名や漢字などが含まれている場合、意図した文字数分のシフトが行われない可能性があるので注意してください
まず、+ n chars
をベースインデックスに結合することで、ベースインデックスから n
文字分後ろの位置を指定することが可能です。例えば、'1.0 + 3 chars'
は、テキストウィジェットの先頭から3文字分後ろの位置を示すインデックスとなります。
'- n chars'
逆に、- n chars
をベースインデックスに結合することで、ベースインデックスから n
文字分前の位置を指定することが可能です。例えば、'2.end - 3 chars'
は、2行目の最後の文字の後ろの位置から3文字分前の位置を示すインデックスとなります。
'+ n lines'
同様に、+ n lines
をベースインデックスに結合することで、ベースインデックスから n
行分下の位置を指定することが可能です。例えば、'insert + 2 lines'
は、挿入カーソルが存在する位置から2行分下の位置を示すインデックスとなります。
'- n lines'
また、- n lines
をベースインデックスに結合することで、ベースインデックスから n
行分上の位置を指定することが可能です。例えば、'current - 2 lines'
は、マウスカーソルに一番近い位置から2行分上の位置を示すインデックスとなります。
ここまで説明してきたように、テクストウィジェット内の文字列・文字の位置を示すインデックスには様々なものが存在します。全てを覚えておく必要はないですが、Text クラスのメソッド で紹介するメソッドでは引数にインデックスを指定するものも多いので、まずは '行番号.列番号'
や 'end'
あたりに関しては覚えておくと良いと思います。
スポンサーリンク
テキストウィジェットの設定
次は、テキストウィジェットの設定について解説していきます。
他のウィジェット同様に、テキストウィジェットの見た目等の設定はキーワード引数を指定してコンストラクタ(tkinter.Text()
)や config
メソッドを実行することで変更可能です。これらに指定可能なキーワード引数名は下記により確認することができます。
# text:テキストウィジェット
print(text.keys())
ここでは、私が動作を理解している設定に対する解説のみを行わせていただきます。具体的には、下記の設定について説明していきます。
- font
- width
- height
- background
- foreground
- borderwidth
- relief
- state
- padx
- pady
- selectbackground
- selectforeground
- inactiveselectbackground
- highlightthickness
- highlightcolor
- highlightbackground
- blockcursor
- insertbackground
- insertwidth
- insertborderwidth
- insertontime
- insertofftime
- insertunfocussed
- wrap
- spacing1
- spacing2
- spacing3
- undo
- maxundo
- autoseparators
- cursor
- xscrollcommand
- yscrollcommand
上記の通り、指定可能なキーワード引数は多いです。が、重要な引数は少ないので、まずはザーッと読んでいただき、使えそうなものをピックアップして利用してみていただければ良いと思います。
私の下記環境での実行結果をもとに説明していますが、環境によっては動きが異なるかもしれません
実際にご自身の環境で実行結果を確認していただくと、より確実に設定の効果を理解することができると思います
- OS:Windows 11
- Python:3.12
- Tkinter:8.6
font
font
は、テキストウィジェット内の文字のフォントを設定するキーワード引数です。
font
の値としては、tkinter.font.Font
のオブジェクトや、タプル等を指定することが可能です。フォントの指定の仕方に関しては下記ページでまとめていますので、必要に応じて下記ページを参照してください。
例えば下記のようにテキストウィジェットを生成すれば、そのテキストウィジェット内の文字のフォントサイズが 40
に変化することになります。
text = tkinter.Text(
# 略
font=('', 40)
)
width
width
は、テキストウィジェットの幅を指定するキーワード引数です。
width
には、文字数を整数で指定します。これにより、その文字数分の文字が横方向に(極力)入力できるようにテキストウィジェットの幅が設定されます。文字の幅はフォントによって異なりますので、同じ整数を指定したとしても、font
で設定したフォントによってテキストウィジェットの幅が変化することになります。また、文字の種類によって文字幅が異なるフォントを設定している場合は、入力する文字によっては一行に width
で指定した文字数が入力できない場合や、その文字数を超えて文字が入力できる場合もあるので注意してください。
例えば下記のようにテキストウィジェットを生成すれば、そのテキストウィジェットが 10
文字分の幅に設定されます。
text = tkinter.Text(
# 略
width=10
)
スポンサーリンク
height
height
は、テキストウィジェットの高さを指定するキーワード引数です。
height
には、width
と同様に文字数を整数で指定します。これにより、その文字数分の文字が縦方向に入力できるようにテキストウィジェットの高さが設定されます。
例えば下記のようにテキストウィジェットを生成すれば、そのテキストウィジェットが 10
文字分の高さに設定されます。
text = tkinter.Text(
# 略
height=10
)
background
background
は、テキストウィジェット内の背景色を設定するキーワード引数です。background
に関しては、略して bg
キーワード引数で指定することも可能です。
background
の値としては、色名やカラーコード等を指定することが可能です。
例えば下記のようにテキストウィジェットを生成すれば、そのテキストウィジェット内の背景色が赤色に変化することになります。
text = tkinter.Text(
# 略
background='red'
)
foreground
foreground
は、テキストウィジェット内の文字色を設定するキーワード引数です。foreground
に関しては、略して fg
キーワード引数で指定することも可能です。
foreground
の値としては、色名やカラーコード等を指定することが可能です。
例えば下記のようにテキストウィジェットを生成すれば、そのテキストウィジェット内の文字色が青色に変化することになります。
text = tkinter.Text(
# 略
foreground='blue'
)
スポンサーリンク
borderwidth
borderwidth
は、テキストウィジェットの外枠の太さを設定するキーワード引数です。
borderwidth
には整数を指定します。単位はピクセルです。
例えば下記のようにテキストウィジェットを生成すれば、テキストウィジェットの外枠の幅が 10
ピクセルに変化します。
text = tkinter.Text(
# 略
borderwidth=10
)
relief
relief
は、テキストウィジェットの見た目を設定するキーワード引数です。
relief
に指定可能な値や、それらの値を指定したときのウィジェットの見た目に関しては下記ページで解説していますので、詳しくは下記ページの relief をご参照ください(フレームの例で説明していますが、見た目の変化に関してはテキストウィジェットにおいても同様になります)。
relief
の指定によってウィジェットの見た目が変化するのは外枠が太い場合です。boarderwidth
に小さい値が指定されていたりデフォルト値のままだったりすると relief
の指定を変更しても見た目が変化しないので注意してください。
例えば下記のようにテキストウィジェットを生成すれば、そのテキストウィジェットが浮き上がるような見た目に変化します。
text = tkinter.Text(
# 略
borderwidth=10,
relief=tkinter.RAISED
)
state
state
は、テキストウィジェットの状態を設定するキーワード引数です。
state
には下記の2つの値が指定可能です。デフォルトは tkinter.NORMAL
となります。また、tkinter.DISABLED
を指定して無効化すると、そのテキストウィジェットには文字の入力等が不可となります。
tkinter.NORMAL
:有効化tkinter.DISABLED
:無効化
例えば下記のようにテキストウィジェットを生成すれば、そのテキストウィジェットへの文字入力が不可となります。
text = tkinter.Text(
# 略
state=tkinter.DISABLED
)
スポンサーリンク
padx
・pady
padx
は、テキストウィジェット内の余白の横幅を指定するキーワード引数、pady
は、テキストウィジェット内の余白の縦幅を指定するキーワード引数となります。
padx
と pady
には整数を指定します。単位はピクセルです。
例えば下記のようにテキストウィジェットを生成すれば、そのテキストウィジェット内の余白の横幅が 10
ピクセル、余白の縦幅が 20
ピクセルとなります。
text = tkinter.Text(
# 略
padx=10,
pady=20
)
selectbackground
selectbackground
は、選択範囲の背景色を設定するキーワード引数です。
selectbackground
の値としては、色名やカラーコード等を指定することが可能です。
例えば下記のようにテキストウィジェットを生成すれば、そのテキストウィジェット内で選択された文字列の背景色が緑色になります。
text = tkinter.Text(
# 略
selectbackground='green'
)
selectforeground
selectforeground
は、選択範囲の文字色を設定するキーワード引数となります。
selectforeground
の値としては、色名やカラーコード等を指定することが可能です。
例えば下記のようにテキストウィジェットを生成すれば、そのテキストウィジェット内で選択された文字列の文字色がオレンジ色になります。
text = tkinter.Text(
# 略
selectforeground='orange'
)
スポンサーリンク
inactiveselectbackground
inactiveselectbackground
は、フォーカスが外れたテキストウィジェットにおける、選択範囲の背景色を設定するキーワード引数です。
操作中のテキストウィジェットはフォーカスが当たっている状態なので、その状態では選択範囲の背景色は selectbackground
で指定した色となりますが、選択した状態のまま他のテキストウィジェットの操作を行うと、元々操作していたテキストウィジェットのフォーカスが外れることになり、その際には選択範囲の背景色が inactiveselectbackground
で指定した色に変化することになります。
inactiveselectbackground
の値としては、色名やカラーコード等を指定することが可能です。
例えば下記のようにテキストウィジェットを生成すれば、そのテキストウィジェットのフォーカスが外れた際には、選択された文字列の背景色が灰色になります。
text = tkinter.Text(
# 略
inactiveselectbackground='gray'
)
highlightthickness
highlightthickness
は、フォーカス枠(そのテキストウィジェットにフォーカスが当たっていることを示す枠)の太さを設定するキーワード引数です。フォーカス枠が存在する場合、テキストウィジェットにフォーカスが当たっていればフォーカス枠の色が特定の色に変化し、フォーカスが外れればフォーカス枠の色が他の色に変化するようになっています。なので、このフォーカス枠より、そのテキストウィジェットにフォーカスが当たっているかどうかを判断することができます。
highlightthickness
には 0
以上の整数を指定します。単位はピクセルとなります。デフォルトは、おそらく 0
となります。したがって、フォーカスが当たっていることを視覚的に判断できるようにしたいのであれば、highlightthickness
引数を指定して 1
以上の整数を設定する必要があります。
例えば下記のようにテキストウィジェットを生成すれば、そのテキストウィジェットのフォーカス枠の太さが 10
となります。
text = tkinter.Text(
# 略
highlightthickness=10
)
highlightcolor
・highlightbackground
highlightcolor
は、先ほど説明したフォーカス枠における、フォーカスが当たっているとき枠の色を設定するキーワード引数です。それに対し、highlightbackground
は、フォーカスが外れているときの枠の色を指定するキーワード引数となります。
highlightcolor
と highlightbackground
の値としては、色名やカラーコード等を指定することが可能です。
例えば下記のようにテキストウィジェットを生成すれば、そのテキストウィジェットにフォーカスが当たっているときはフォーカス枠の色が赤色となり、フォーカスが外れているときはフォーカス枠の色が青色に変化するようになります。
text = tkinter.Text(
# 略
highlightthickness=10,
highlightcolor='red',
highlightbackground='blue'
)
スポンサーリンク
blockcursor
blockcursor
は、挿入カーソルをブロック表示するかどうかを設定するキーワード引数です。
blockcursor
には Bool 値(True
or False
)を指定します。True
を指定すれば挿入カーソルがブロックで表示され、False
を指定すれば挿入カーソルが縦線で表示されます。デフォルトは False
となります。
例えば下記のようにテキストウィジェットを生成すれば、そのテキストウィジェット内では挿入カーソルがブロックで表示されることになります。
text = tkinter.Text(
# 略
blockcursor=True
)
insertbackground
insertbackground
は、挿入カーソルの色を設定するキーワード引数です。
insertbackground
の値としては、色名やカラーコード等を指定することが可能です。
例えば下記のようにテキストウィジェットを生成すれば、そのテキストウィジェット内の挿入カーソルが赤色で表示されることになります。
text = tkinter.Text(
# 略
insertbackground='red'
)
insertwidth
insertwidth
は、挿入カーソルの太さを設定するキーワード引数です。
insertwidth
には太さを整数で指定します。単位はピクセルです。
例えば下記のようにテキストウィジェットを生成すれば、そのテキストウィジェット内の挿入カーソルの太さが 10
になります。
text = tkinter.Text(
# 略
insertwidth=10
)
スポンサーリンク
insertborderwidth
insertborderwidth
は、挿入カーソルの枠の太さを設定するキーワード引数です。
insertborderwidth
には太さを整数で指定します。単位はピクセルです。
insertborderwidth
がブロックの枠の太さを指定するキーワード引数であるのに対し、先ほど紹介した insertwidth
は枠の内側の塗りつぶし部分の横幅を指定するキーワード引数となるようです。
例えば下記のようにテキストウィジェットを生成すれば、そのテキストウィジェット内の挿入カーソルの枠の太さが 10
になります。
text = tkinter.Text(
# 略
blockcursor=True,
insertborderwidth=10
)
insertontime
・insertofftime
テキストウィジェット内の挿入カーソルは点滅して表示されることになります。この点滅における、点灯(表示時間)時間を設定するキーワード引数が insertontime
、消灯(非表示時間)時間を設定するキーワード引数が inserofftime
となります。
insertontime
・insertofftime
には整数を指定します。単位はミリ秒となります。insertofftime
に 0
を指定した場合は、挿入カーソルは点滅するのではなく、常に表示された状態となります。
例えば下記のようにテキストウィジェットを生成すれば、そのテキストウィジェット内の挿入カーソルは、点灯 1000
ミリ秒・消灯 100
ミリ秒の間隔で点滅することになります。
text = tkinter.Text(
# 略
insertontime=1000,
insertofftime=100
)
insertunfocussed
insertunfocussed
は、フォーカスが外れたときのテキストウィジェット内の挿入カーソルの表示の設定を行うキーワード引数です。
insertunfocussed
に指定可能な値は下記の3つとなります。デフォルトは 'none'
であり、フォーカスが外れたテキストウィジェットでは挿入カーソルが非表示になるようになっています。
'none'
:非表示'solid'
:表示(枠+背景を塗りつぶしたカーソルが表示される)'hollow'
:表示(枠だけのカーソルが表示される)
'solid'
と 'hollow'
を指定した場合は、フォーカスが外れたテキストウィジェットでも挿入カーソルが表示されるようになります。ただ、カーソルは点滅せず、点灯したままとなります。また、'solid'
と 'hollow'
の違いが表れるのは、blockcursor で紹介した blockcursor
に True
が指定されて挿入カーソルのブロック表示が有効になっている場合のみとなります。縦線表示時は違いが表れないので注意してください。
例えば下記のようにテキストウィジェットを生成すれば、そのテキストウィジェットからフォーカスが外れても挿入カーソルは表示され続けるようになります。また、フォーカスが外れた際には、その挿入カーソルは枠だけのブロックとして表示されます。
text = tkinter.Text(
# 略
blockcursor=True,
insertunfocussed='hollow'
)
スポンサーリンク
wrap
wrap
は、テキストウィジェット内の文字列の折り返しの設定を行うキーワード引数です。
wrap
に指定可能な値は下記の3つとなります。デフォルトは tkinter.CHAR
となります。
tkinter.NONE
:折り返し無しtkinter.CHAR
:文字単位で折り返しtkinter.WORD
:単語単位で折り返し
wrap=tkinter.NONE
を指定している場合は、テキストウィジェット内の幅を超える文字を入力しても折り返しが行われず、テキストウィジェット内が横方向にスクロールして同じ行にどんどん文字が入力されていくことになります。したがって、改行しないと次の行への文字入力は不可となります。
wrap=tkinter.CHAR
を指定している場合は、文字の入力により1行の文字列がテキストウィジェットの幅を超えると自動的に次の行への折り返しが行われることになります。この折り返しは文字単位で行われることになります。
wrap=tkinter.WORD
を指定している場合も、文字の入力により1行の文字列がテキストウィジェットの幅を超えると自動的に次の行への折り返しが行われることになります。ただし、この折り返しは単語単位で行われることになります。
例えば下記のようにテキストウィジェットを生成すれば、そのテキストウィジェット内の文字列は折り返しが行われないようになります。
text = tkinter.Text(
# 略
wrap=tkinter.NONE
)
spacing1
・spacing2
・spacing3
spacing1
と spacing2
と spacing3
は、テキストウィジェット内の行間のスペースの大きさの設定を行うキーワード引数です。
これらはそれぞれ、spacing1
は改行された行の上側のスペースの大きさを設定するキーワード引数、spacing2
は自動的に折り返された行の行間のスペースの大きさを設定するキーワード引数、spacing3
は改行された行の下側のスペースの大きさを設定するキーワード引数となります。
spacing1
と spacing2
と spacing3
には整数を指定します。これらのデフォルト値はすべて 0
となります。指定した整数の値に応じて行間のスペースの大きさが変化することになります。
例えば下記のようにテキストウィジェットを生成すれば、改行された行の下側のスペースが 20
に設定されることになります。
text = tkinter.Text(
# 略
spacing3=20
)
undo
・maxundo
・autoseparators
undo
・maxundo
・autoseparators
は「元に戻す(取り消し)・やり直す(やり直し)」の操作に関する設定を行うキーワード引数です。
undo
には Bool 値(True
or False
)が指定可能で、True
を指定した場合には「元に戻す・やり直す」操作が可能となり、ショートカットキーの押下やメソッドの実行によって、これらの操作を行うことができるようになります。
さらに、maxundo
には、「元に戻す」操作が実施可能な最大回数を整数で指定します。例えば、maxundo=2
を指定した場合は、一度に実行可能な「元に戻す」操作が最大2回となります。
また、元に戻す操作は、一度に最初の状態に戻るのではなく、何段階かに分けて元に戻していくことが可能です。つまり、特定のタイミングの状態が記録されており、元に戻す操作では、それらの各タイミングの状態に戻していくことが可能です。このような、特定のタイミングでの自動的な状態の保存の有効 / 無効を指定するのが autoseparators
引数となります。autoseparators
には Bool 値(True
or False
)が指定可能で、True
を指定した場合には上記のような特定のタイミングでの状態の保存が Tkinter によって自動的に行われるようになります。
False
を指定した場合は、そのような特定のタイミングでの自動的な状態の保存が行われなくなります。なので、基本的には元に戻す操作を行うと最初の状態に戻ることになります。ただし、autoseparators=False
を指定している場合でも、自動的な状態の保存は行われませんが、メソッドの実行によって状態の保存を行うことも可能です。これに関しては edit_separator で説明します。
例えば下記のようにテキストウィジェットを生成すれば、そのテキストウィジェット内の文字列の入力や削除を行った特定のタイミングの状態が最大 5
個分記録されるようになり、そのタイミングの状態への「元に戻す・やり直す」操作が可能となります。
text = tkinter.Text(
# 略
undo=True,
maxundo=5,
autoseparators=True
)
スポンサーリンク
cursor
cursor
は、マウスカーソルをテキストウィジェット上に移動させたときのカーソルの見た目を設定するキーワード引数です。
cursor
に指定可能な値に関しては、公式の下記ページで紹介されていますので、下記ページを参考にしていただければと思います。
https://tcl.tk/man/tcl8.6/TkCmd/cursors.htm
例えば下記のようにテキストウィジェットを生成すれば、テキストウィジェット上にマウスカーソルを合わせたときのカーソルの見た目が「手」に変化します(Windows の場合は)。
text = tkinter.Text(
# 略
cursor='hand1'
)
xscrollcommand
・yscrollcommand
xscrollcommand
・yscrollcommand
は、スクロールバー付きのテキストウィジェットを作成するためのキーワード引数となります。
スクロールバーについては別途下記ページで説明していますので、詳細については下記ページを参照してください。スクロールバー付のテキストウィジェット(テキストボックス)の作り方についても解説しています。
Tkinterの使い方:スクロールバー(Scrollbar)の使い方例えば下記を実行すれば、横方向&縦方向のスクロールバー付きのテキストウィジェットを作成することができます。今までの例とは異なり、xscrollcommand
と yscrollcommand
の指定はコンストラクタではなく config
メソッドで実行しているという点に注意してください。また、スクロールバーは横方向や縦方向に入力された文字が入りきらなくなった時に表示されるようになっています。特に横方向に関しては、wrap
に 'none'
以外を指定していると自動的に折り返しが行われて横方向に文字が入りきらなくなることが無くなり、横方向のスクロールバーの意味も無くなることになるので、この点にも注意してください。
import tkinter
# メインウィンドウの作成
app = tkinter.Tk()
# テキストボックスの作成と配置
textbox = tkinter.Text(
app,
width=10,
height=5,
font=('', 40),
wrap='none'
)
textbox.grid(row=0, column=0)
# 水平方向のスクロールバーを作成
xbar = tkinter.Scrollbar(
app, # 親ウィジェット
orient=tkinter.HORIZONTAL, # バーの方向
)
# 垂直方向のスクロールバーを作成
ybar = tkinter.Scrollbar(
app, # 親ウィジェット
orient=tkinter.VERTICAL, # バーの方向
)
# テキストボックスの下に垂直方向のスクロールバーを配置
xbar.grid(
row=1, column=0, # テキストの下の位置を指定
sticky=tkinter.E + tkinter.W # 左右いっぱいに引き伸ばす
)
# テキストボックスの右に垂直方向のスクロールバーを配置
ybar.grid(
row=0, column=1, # テキストの右の位置を指定
sticky=tkinter.N + tkinter.S # 上下いっぱいに引き伸ばす
)
# テキストボックスをスクロールするための設定
# スクロールバーのスライダーが動かされた時に実行する処理を設定
xbar.config(
command=textbox.xview
)
ybar.config(
command=textbox.yview
)
# テキストボックススクロール時に実行する処理を設定
textbox.config(
xscrollcommand=xbar.set,
yscrollcommand=ybar.set
)
# メインループ
app.mainloop()
Text
クラスのメソッド
最後に Text
クラスに用意されたメソッドについて紹介していきたいと思います。
ここでは、Text
クラス特有のメソッド&私が動作を理解している下記のメソッドのみを紹介させていただきます。
- get
- insert
- delete
- search
- index
- edit_undo
- edit_redo
- edit_separator
- edit_reset
- edit_modified
- tag_add
- tag_bind
- tag_config
- tag_names
- tag_delete
- xview
- yview
スポンサーリンク
get
get
は、引数で指定されたインデックスの位置の文字列を取得するメソッドとなります。
インデックスの詳細については テキストウィジェットでのインデックスの指定 をご参照ください。
第1引数(引数 index1
)と第2引数(引数 index2
)のそれぞれにインデックスを指定して get
メソッドを実行することで、それらのインデックスの位置の間の文字列を返却値として取得することができます。
また、第2引数の指定を省略した場合、第1引数に指定されたインデックスの位置の後ろの文字のみが返却されることになります。
例えば下記を実行すれば、テキストウィジェット内に入力された1行目の文字列が全て出力されることになります(改行は含まない)。
#text:テキストウィジェット
print(text.get(1.0, 1.end))
insert
insert
は、引数で指定されたインデックスの位置に文字列を挿入するメソッドとなります。
インデックスの詳細については テキストウィジェットでのインデックスの指定 をご参照ください。
第1引数(引数 index1
)にインデックス、第2引数(引数 text
)に文字列を指定して insert
メソッドを実行することで、第1引数で指定されたインデックスの位置に第2引数で指定した文字列が挿入されることになります。
例えば下記を実行すれば、1行目と2行目の間に Hello World!
が挿入されることになります。
#text:テキストウィジェット
text.insert(2.0, 'Hello World!\n')
delete
delete
は、引数で指定されたインデックスの位置の文字列を削除するメソッドとなります。
インデックスの詳細については テキストウィジェットでのインデックスの指定 をご参照ください。
第1引数(引数 index1
)と第2引数(引数 index2
)のそれぞれにインデックスを指定して delete
メソッドを実行することで、それらのインデックスの位置の間の文字列が削除されることになります。
また、第2引数の指定を省略した場合、第1引数に指定されたインデックスの位置の後ろの文字のみが削除されることになります。
例えば下記を実行すれば、テキストウィジェット内に入力された先頭の文字のみが削除されることになります。
#text:テキストウィジェット
text.delete(1.0)
スポンサーリンク
search
search
は、テキストウィジェット内から文字列を検索するメソッドとなります。
第1引数(引数 pattern
)に文字列を、第2引数(引数 index
)にインデックスを指定して search
メソッドを実行することで、第2引数で指定されたインデックスの位置から第1引数で指定された文字列の検索が行われることになります。見つかった場合は、その位置を示す '行番号.列番号'
形式のインデックスが返却され、見つからなかった場合は空の文字列 ''
が返却されることになります。
さらに、search
メソッドには下記のような引数をオプションで指定することが可能です。
stopindex=インデックス
:検索範囲の終端を示すインデックス- (指定しない場合はテキストウィジェットに入力されている最後の文字の後ろが終端となる)
forwards=True
:検索を検索範囲の始端側から実施する(デフォルト)backwards=True
:検索を検索範囲の終端側から実施するexact=True
:第1引数に完全一致する文字列のみを検索する(デフォルト)regex=True
:第1引数に正規表現が指定可能となるnocase=True
:大文字小文字を区別せずに検索する
例えば下記を実行すれば、テキストウィジェット内の先頭から Hello
という文字列の検索が行われることになります(大文字と小文字の区別なしでの検索)。
#text:テキストウィジェット
ret = text.search('Hello', 1.0, nocase=False)
if ret == '':
print('Helloは存在しません')
else:
print('Helloは(' + ret + ')の位置に存在します')
index
index
は、'行番号.列番号'
形式以外のインデックスを '行番号.列番号'
形式のインデックスに変換するメソッドになります。
第1引数(引数 index
)に '行番号.列番号'
形式以外のインデックスを指定して index
メソッドを実行すれば、返却として '行番号.列番号'
形式のインデックスが得られます。指定可能なインデックスに関しては テキストウィジェットでのインデックスの指定 を参照してください。
例えば下記を実行すれば、選択中の文字列の最後の文字の後ろの位置を示す '行番号.列番号'
形式のインデックスが出力されることになります。
#text:テキストウィジェット
print(text.index('sel.last'))
edit_undo
・edit_redo
ここからは「元に戻す(取り消し)・やり直す(やり直し)」操作に関連するメソッドを紹介していきます。
まず edit_undo
は「元に戻す」を実行するメソッドになります。それに対し、edit_redo
は、直前に実施した「元に戻す」を取り消してやり直しするメソッドとなります。これらのメソッドは引数なしで実行可能です。
ただし、テキストウィジェットの「元に戻す」においては、「事前に記録されていた状態」へのみ元に戻すことが可能です。逆に記録されていない状態へ元に戻すことはできません。undo・maxundo・autoseparators の節で解説したように、テキストウィジェットに autoseparators=True
を指定しておけば、文字の挿入や削除が行われたタイミングで自動的に状態の記録が行われるようになります。そして、edit_undo
や edit_redo
を実行することで、その記録された状態に元に戻したり、その操作をやり直したりすることが可能となります。
これらのメソッドの実行例に関しては、次の edit_separator
の節で示します。
また、状態の記録が行われていない場合や、記録されている状態に対する「元に戻す」が全て実施された後に edit_undo
を実行すると下記のような例外が発生するので注意してください。
_tkinter.TclError: nothing to redo
スポンサーリンク
edit_separator
edit_separator
は「元に戻す」を実行するための状態の記録を実施するメソッドになります。
undo・maxundo・autoseparators の節で解説したように、テキストウィジェットに autoseparators=True
を指定しておけば自動的に状態の記録が行われるようになります。ですが、autoseparators=False
を指定している場合であっても、edit_separator
メソッドを利用すれば、開発者の好きなタイミングで状態の記録を実行することができるようになります。
例えば下記のようにスクリプトを実装すれば、記録
ボタンのクリックによって、そのクリックしたタイミングの状態が記録されることになり、元に戻す
ボタンのクリックによって、その記録された状態に元に戻すことができるようになります。また、やり直す
ボタンをクリックすれば、直前に実施した元に戻す操作の取り消しを行うことも可能となります。
import tkinter
def push():
text.edit_separator()
def undo():
text.edit_undo()
def redo():
text.edit_redo()
# メインウィンドウを作成
app = tkinter.Tk()
app.geometry('500x350')
# テキストウィジェットを作成して配置
text = tkinter.Text(
app,
font=('', 20),
width=20,
height=5,
autoseparators=False,
undo=True,
maxundo=20
)
text.pack(padx=10, pady=10)
push_button = tkinter.Button(
app,
text='記録',
font=('', 20),
command=push
)
push_button.pack(padx=10, pady=10)
undo_button = tkinter.Button(
app,
text='元に戻す',
font=('', 20),
command=undo
)
undo_button.pack(padx=10, pady=10)
redo_button = tkinter.Button(
app,
text='やり直す',
font=('', 20),
command=redo
)
redo_button.pack(padx=10, pady=10)
# メインループ
app.mainloop()
edit_reset
edit_reset
は、edit_separator
メソッドの実行によって記録された状態や autoseparators=True
の指定によって自動的に記録された状態をすべてクリアするメソッドになります。
edit_reset
実行時には引数は不要です。
例えば下記を実行すれば、記録された状態が全てクリアされることになります。
#text:テキストウィジェット
text.edit_reset()
edit_modified
edit_modified
は、テキストウィジェット内の文字列に対する変更が行われたかどうかを管理する変更フラグを取得 or 変更フラグに値をセットするメソッドになります。
テキストウィジェットでは、特定のタイミングからテキストウィジェット内の文字列が入力や削除によって変更されたかどうかを変更フラグによって管理するようになっています。そして、edit_modified
メソッドを「引数なし」で実行することで、その変更フラグを取得することができます。特定のタイミングからテキストウィジェット内の文字列が変更されていれば 1
が返却され、変更されていなければ 0
が返却されます。
また、上記における “特定のタイミング” とは、基本的には「テキストウィジェット作成直後」となります。つまり空の状態のテキストウィジェットから変更されていた場合、edit_modified
メソッドを「引数なし」で実行すると 1
が返却されることになります。ただし、この “特定のタイミング” は、edit_modified
メソッドの引数に False
を指定して実行することで変更することが可能です。つまり、edit_modified(False)
を実行したタイミングからの変更の有無を edit_modified
メソッドを「引数なし」で実行することで確認することができます。
例えば、テキストエディターでは、開いたファイルを変更した場合、閉じるボタンをクリックすると「変更を保存しなくて良いか?」というメッセージが表示されたりしますよね?こういった動作も、下記のように edit_modified
メソッドを利用することで実現可能となります。
- ファイルから読み込んだ文字列をテキストウィジェットに挿入した直後に
edit_modified(False)
を実行する - テキストウィジェット内の文字列の保存直後に
edit_modified(False)
を実行する - 閉じるボタンがクリックされた際に
edit_modified()
を実行する1
が返却された場合に「変更を保存しなくて良いか?」というメッセージを表示
これらを実際に実装したスクリプトが下記となります。テキストファイルを読み込んだ後にテキストウィジェット内の文字列を変更して閉じるボタンをクリックすれば「変更を保存しなくて良いか?」というメッセージが表示され、変更せずに閉じるボタンをクリックしたり、保存してから閉じるボタンをクリックしたりした場合は何もメッセージが表示されないことが確認できると思います。
import tkinter
from tkinter import messagebox
def open_text():
f = open(entry.get(), encoding='utf-8')
read_text = f.read()
f.close()
text.delete('1.0', 'end - 1 chars')
text.insert('1.0', read_text)
# 変更フラグをFalseにセット
text.edit_modified(False)
def save_text():
save_text = text.get('1.0', 'end - 1 chars')
f = open(entry.get(), 'w', encoding='utf-8')
f.write(save_text)
f.close()
# 変更フラグをFalseにセット
text.edit_modified(False)
def ask_save():
# 変更フラグをチェック
if text.edit_modified() == 1:
# 変更ありの場合は保存が不要かどうかを確認
ret = messagebox.askokcancel('確認', '変更を保存しなくて良いか?')
if ret:
# 不要であればアプリ終了
app.destroy()
else:
# 変更なしの場合はアプリ終了
app.destroy()
# メインウィンドウを作成
app = tkinter.Tk()
app.geometry('500x350')
# テキストウィジェットを作成して配置
text = tkinter.Text(
app,
font=('', 20),
width=20,
height=5,
undo=True
)
text.pack(padx=10, pady=10)
# パスの入力受付用エントリーを作成して配置
entry = tkinter.Entry(
app,
font=('', 20)
)
entry.pack(padx=10, pady=10)
# ファイルを開く用のボタンを作成して配置
open_button = tkinter.Button(
app,
text='開く',
font=('', 20),
command=open_text
)
open_button.pack(padx=10, pady=10)
# ファイルへの保存用のボタンを作成して配置
save_button = tkinter.Button(
app,
text='保存',
font=('', 20),
command=save_text
)
save_button.pack(padx=10, pady=10)
# 閉じるボタンがクリックされた時にask_saveを実行
app.protocol('WM_DELETE_WINDOW', ask_save)
# メインループ
app.mainloop()
スポンサーリンク
tag_add
ここからはタグ関係のメソッドを紹介していきます。
テキストウィジェット内に入力された文字列にはタグを付けることが可能です。そして、タグ付けされた部分の文字列に対してイベントハンドラを設定したり、タグ付けされた部分のみに対して設定変更を行ったりすることが可能です。
ここで紹介する tag_add
は、インデックスで指定される範囲の文字列に対して特定の名前のタグを付けるメソッドになります。
第1引数にタグ名、第2引数と第3引数にインデックスを指定して tag_add
メソッドを実行すれば、第2引数と第3引数に指定されるインデックスの間の文字列に第1引数に指定したタグ名のタグが付けられることになります。
ただし、第1引数のタグ名に 'sel'
は指定してはいけないので注意してください。Tkinter では選択範囲に対して 'sel'
というタグ名が自動的に付けられるようになっています。にも関わらず、第1引数のタグ名に 'sel'
を指定して tag_add
を実行すると 'sel'
の名前のタグが上書きされてしまうことになります。
逆に言えば、タグ名として 'sel'
を指定することで、選択範囲に対して tag_bind
や tag_config
が実行可能ということになります(tag_bind
や tag_config
に関しては後述で解説します)。
tag_add
メソッドの実行例に関しては、次の tag_bind
メソッドと一緒に紹介します。
tag_bind
tag_bind
は、タグ付けされた文字列に対するイベントの設定を行うメソッドになります。
第1引数にタグ名、第2引数にシーケンス、第3引数にイベントハンドラを指定して tag_bind
メソッドを実行することで、第1引数で指定されたタグ名のタグが付けられた文字部分に対して第2引数で指定したシーケンスに対応するイベントが発生したタイミングで、第3引数に指定したイベントハンドラが実行されるようになります。
通常のイベントは bind
メソッドで設定することになりますが、タグ付けされた文字列に対するイベントの設定は tag_bind
で行うことになります。この tag_bind
メソッドを利用することで、テキストウィジェット内の特定の文字列がクリックされた際に特定の処理が自動的に実行されるようにすることもできます。
イベントや bind
メソッドに関しては下記ページで解説しており、シーケンスやイベントハンドラに関しても説明していますので、詳細を知りたい方は下記ページを参照してください。
例えば下記のスクリプトの場合、タグ付け
ボタンがクリックされた際に選択された範囲の文字列に tag1
という名前のタグが付けられることになります。そして、そのタグ付けが行われた部分の文字列をマウスでクリックすれば、その tag1
のタグが付けられている文字列全体が出力されることになります。
import tkinter
def print_selected(event):
print(text.get('tag1.first', 'tag1.last'))
def add_tag():
text.tag_add('tag1', 'sel.first', 'sel.last')
text.tag_bind('tag1', '<ButtonPress>', print_selected)
# メインウィンドウを作成
app = tkinter.Tk()
app.geometry('500x350')
# テキストウィジェットを作成して配置
text = tkinter.Text(
app,
font=('', 20),
width=20,
height=5
)
text.pack(padx=10, pady=10)
# ファイルを開く用のボタンを作成して配置
add_tag_button = tkinter.Button(
app,
text='タグ付け',
font=('', 20),
command=add_tag
)
add_tag_button.pack(padx=10, pady=10)
# メインループ
app.mainloop()
tag_config
tag_config
は、タグ付けされた文字列に対する各種設定を行うメソッドになります。
第1引数にタグ名、さらに第2引数以降に下記のようなキーワード引数を指定して tag_config
メソッドを実行することで、そのタグ名のタグが付けられた文字列部分の見た目やフォントを変更することが可能です。
background
:背景色(カラーコードや色名で指定)foreground
:文字色(カラーコードや色名で指定)underline
:下線の有無(Bool 値で指定)underlinefg
:下線の色(カラーコードや色名で指定)overstrike
:取り消し線の有無overstrikefg
:取り消し線の色font
:文字のフォント(タプルやフォントオブジェクトで指定)
例えば下記のスクリプトでは、テキストウィジェット内の文字列を選択した状態で タグ付け
ボタンをクリックすれば、その選択された文字列に tag1
という名前のタグが付けられることになります。その後に、下線
ボタンをクリックすれば underline
関数が実行されて、tag1
でタグ付けされた文字列部分に赤色の下線が追加されることになります。同様に、取り消し線
ボタンをクリックすれば overstrike
関数が実行されて、tag1
でタグ付けされた文字列部分に緑色の取り消し線が追加されることになります。さらに、ハイライト
ボタンをクリックすれば highlight
関数が実行されて、tag1
でタグ付けされた文字列部分の背景色が黄・文字色が赤に変化し、サイズ大
ボタンをクリックすれば large
関数が実行されて、tag1
でタグ付けされた文字列部分のフォントサイズが 40
に変化することになります。
import tkinter
def add_tag():
text.tag_add('tag1', 'sel.first', 'sel.last')
def underline():
text.tag_config(
'tag1',
underline=True,
underlinefg='red'
)
def overstrike():
text.tag_config(
'tag1',
overstrike=True,
overstrikefg='green'
)
def highlight():
text.tag_config(
'tag1',
background='yellow',
foreground='red',
)
def large():
text.tag_config(
'tag1',
font=('', 40)
)
# メインウィンドウを作成
app = tkinter.Tk()
app.geometry('500x500')
# テキストウィジェットを作成して配置
text = tkinter.Text(
app,
font=('', 20),
width=20,
height=5
)
text.pack(padx=10, pady=10)
add_tag_button = tkinter.Button(
app,
text='タグ付け',
font=('', 20),
command=add_tag
)
add_tag_button.pack(padx=10, pady=10)
underline_button = tkinter.Button(
app,
text='下線',
font=('', 20),
command=underline
)
underline_button.pack(padx=10, pady=10)
overstrike_button = tkinter.Button(
app,
text='取り消し線',
font=('', 20),
command=overstrike
)
overstrike_button.pack(padx=10, pady=10)
highlight_button = tkinter.Button(
app,
text='ハイライト',
font=('', 20),
command=highlight
)
highlight_button.pack(padx=10, pady=10)
large_button = tkinter.Button(
app,
text='サイズ大',
font=('', 20),
command=large
)
large_button.pack(padx=10, pady=10)
# メインループ
app.mainloop()
スポンサーリンク
tag_names
tag_names
は、追加済みのタグのタグ名のリストを取得するメソッドになります。
tag_names
は引数なしで実行します。
tag_names
を利用することで、追加済みのタグのタグ名一覧を表示するようなことももちろん可能ですし、for
ループを利用して、前述で紹介した tag_bind
や tag_config
を全タグ名のタグに対して一括して実行するようなことも可能となります。
例えば下記を実行すれば、タグ付けされた文字列全ての背景色が赤色に変化することになります。
#text:テキストウィジェット
for tag_name in text.tag_names():
if tag_name != 'sel':
text.tag_config(tag_name, background='red')
tag_add で説明したように、選択されている範囲に対しては 'sel'
という名前のタグが自動的に付けられるようになっています。そこを除いて tag_config
を実行するようにするため、上記のように tag_name != 'sel'
を満たす場合のみ tag_config
を実行するようにしています。選択されている範囲に対しても tag_config
を実行したいのであれば、この条件分岐を削除してやれば良いです。
tag_delete
tag_delete
は、タグを削除するメソッドになります。
tag_delete
には、引数に削除したいタグのタグ名を指定します。複数のタグ名のタグを削除したい場合は、それらのタグ名をコンマ区切りで指定してやれば良いです。
例えば下記は、タグ名 'tag1'
・'tag2'
のタグを削除する例となります。
#text:テキストウィジェット
text.tag_delete('tag1', 'tag2')
xview
・yview
xview
と yview
はスクロールバー付テキストウィジェットを作成するときに利用するメソッドになります。
スクロールバーに関しては下記ページで解説していますので、これらのメソッドについて詳細を知りたい方は下記ページを参照してください。
Tkinterの使い方:スクロールバー(Scrollbar)の使い方また、これらのメソッドを利用してスクロールバー付テキストウィジェットを作成するスクリプトの例に関しては xscrollcommand・yscrollcommand を参照していただければと思います。
スポンサーリンク
まとめ
このページでは、Tkinter のテキストウィジェットについて解説しました!
このテキストウィジェットを利用することで、Tkinter でテキストエディターのようなアプリを開発することも可能ですし、長文の入力受付を行うフォームやテキストを利用した様々なアプリやゲームも開発することが可能となります。
是非、このページで解説した内容を参考にして、テキストエディターを利用したアプリ開発に挑戦してみていただければと思います!
オススメ参考書(PR)
Tkinter に興味がある方には下記のPythonでつくる ゲーム開発 入門講座がオススメです。
Tkinter をゲーム開発を通して「楽しく学ぶ」ことができます。Python 入門者、Tkinter 入門者の方にオススメです。