Tkinterの使い方:テキストウィジェット(Text)の使い方

Tkinterにおけるテキストウィジェットの使い方の解説ページアイキャッチ

このページにはプロモーションが含まれています

このページでは、Tkinter の「テキストウィジェット」の作成方法・使い方・設定方法等について説明していきたいと思います。

テキストウィジェットとは

まずは、今回解説する「テキストウィジェット」がどのようなウィジェットであるのかについて簡単に説明していきます。

テキストウィジェット=テキストボックス

テキストウィジェットは、一言で言えばテキストボックスです。

このテキストウィジェットを 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 の指定も必要となります。

他の引数についても テキストウィジェットの設定 で紹介しますが、正直言ってテキストウィジェットのコンストラクタに指定可能な引数はかなり多いです。ですが、特に重要なのは上記で挙げた fontwidthheightundo くらいになると思います。なのでテキストウィジェットを初めて使うという方は、まずは、この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メソッドによって取得される文字列とインデックスの関係図

そして、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'JK の間の位置ということになります。

改行と折り返し及び行番号の説明図

'行番号.end'

また、'行番号.end' 形式のインデックスを指定することで、特定の行における、最後の文字の後ろ側の位置を指定することも可能です。例えば '3.end' は3行目の最後の文字の後ろ側の位置を示すインデックスとなります。

'行番号.end'形式のインデックスの具体例

テキストウィジェット内の文字列の各行の最後には必ず改行が存在しますが、この '行番号.end' は、その 行番号 の改行を含めなかった場合の最後の文字の後ろ側の位置を示すインデックスとして扱われます。

'end' or tkinter.END

'end' と tkinter.END は「テキストウィジェット内の最後の文字の後ろ側の位置」を示すインデックスとなります。先ほど説明した通り、テキストウィジェット内の文字列の各行の最後には改行が存在しますので、これらのインデックスは、その最後の改行の後ろ側の位置を示すことになります。

'end'形式のインデックスの説明図1

後述で解説するように、'end' 等のインデックスには '- n chars' を追加で指定することで、そのインデックスが示す位置を n 文字分前側に移動させることが可能です。ですので、単純に「テキストウィジェット内の最後の文字」の後ろ側の位置を指定したいのであれば、'end - 1 chars' のインデックスを利用すればよいことになります。

'end'形式のインデックスの説明図2

'end - 1 chars' の場合は、'行番号.end' のように 行番号 の指定が不要なので、テキストウィジェット内に入力された文字列の行数を意識しなくてもテキストウィジェット内の最後の文字の位置を指定することができて便利です。

'insert' or tkinter.INSERT

'insert' と tkinter.INSERT は「挿入カーソルの位置」を示すインデックスとなります。

'insert'形式のインデックスの説明図

通常のテキストエディター同様に、テキストウィジェットにおいても、次の文字の入力位置には挿入カーソルが表示されます。'insert' と tkinter.INSERT は、その挿入カーソルの位置を示すインデックスとなります。

'current' or tkinter.CURRENT

'current' と tkinter.CURRENT は「マウスカーソルに一番近い位置」を示すインデックスとなります。

'cursor'形式のインデックスの説明図

'sel.first' or tkinter.SEL_FIRST

'sel.first' と tkinter.SEL_FIRST は、「選択中の文字列における最初の文字の前側の位置」を示すインデックスとなります。

'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.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' をタグ付けされた範囲の先頭の前側の位置を示すインデックスとして扱うことができるようになります。

'タグ名.first'のインデックスの説明図

'タグ名.last'

同様に、タグ付けしておくことで、'タグ名.last' を、タグ付けされた範囲の末尾の後ろ側の位置を示すインデックスとして扱うことができるようになります。

'タグ名.last'のインデックスの説明図

'+ n chars'

さて、ここまで示してきたインデックスは「基準位置を示すベースインデックス」であり、これらは単体でも使用可能なのですが、ここから紹介する + n chars- n chars+ n lines- n chars をベースインデックスに結合することで、ベースインデックスから特定の文字数分 or 行数分シフトした位置を指定することができるようになります。

MEMO

ただし、これらのシフトが指定した文字数分のみ行われるのはテキストウィジェット内の文字が半角文字(1バイト文字)の場合のみとなります

例えば平仮名や漢字などが含まれている場合、意図した文字数分のシフトが行われない可能性があるので注意してください

まず、+ n chars をベースインデックスに結合することで、ベースインデックスから n 文字分後ろの位置を指定することが可能です。例えば、'1.0 + 3 chars' は、テキストウィジェットの先頭から3文字分後ろの位置を示すインデックスとなります。

'+ n chars'によるインデックスのシフトの説明図

'- n chars'

逆に、- n chars をベースインデックスに結合することで、ベースインデックスから n 文字分前の位置を指定することが可能です。例えば、'2.end - 3 chars' は、2行目の最後の文字の後ろの位置から3文字分前の位置を示すインデックスとなります。

'- n chars'によるインデックスのシフトの説明図

'+ n lines'

同様に、+ n lines をベースインデックスに結合することで、ベースインデックスから n 行分下の位置を指定することが可能です。例えば、'insert + 2 lines' は、挿入カーソルが存在する位置から2行分下の位置を示すインデックスとなります。

'+ n lines'によるインデックスのシフトの説明図

'- n lines'

また、- n lines をベースインデックスに結合することで、ベースインデックスから n 行分上の位置を指定することが可能です。例えば、'current - 2 lines' は、マウスカーソルに一番近い位置から2行分上の位置を示すインデックスとなります。

'- n lines'によるインデックスのシフトの説明図

ここまで説明してきたように、テクストウィジェット内の文字列・文字の位置を示すインデックスには様々なものが存在します。全てを覚えておく必要はないですが、Text クラスのメソッド で紹介するメソッドでは引数にインデックスを指定するものも多いので、まずは '行番号.列番号''end' あたりに関しては覚えておくと良いと思います。

スポンサーリンク

テキストウィジェットの設定

次は、テキストウィジェットの設定について解説していきます。

他のウィジェット同様に、テキストウィジェットの見た目等の設定はキーワード引数を指定してコンストラクタ(tkinter.Text())や config メソッドを実行することで変更可能です。これらに指定可能なキーワード引数名は下記により確認することができます。

設定可能なキーワード
# text:テキストウィジェット
print(text.keys())

ここでは、私が動作を理解している設定に対する解説のみを行わせていただきます。具体的には、下記の設定について説明していきます。

上記の通り、指定可能なキーワード引数は多いです。が、重要な引数は少ないので、まずはザーッと読んでいただき、使えそうなものをピックアップして利用してみていただければ良いと思います。

MEMO

私の下記環境での実行結果をもとに説明していますが、環境によっては動きが異なるかもしれません

実際にご自身の環境で実行結果を確認していただくと、より確実に設定の効果を理解することができると思います

  • OS:Windows 11
  • Python:3.12
  • Tkinter:8.6

font

font は、テキストウィジェット内の文字のフォントを設定するキーワード引数です。

font引数の説明図

font の値としては、tkinter.font.Font のオブジェクトや、タプル等を指定することが可能です。フォントの指定の仕方に関しては下記ページでまとめていますので、必要に応じて下記ページを参照してください。

フォント指定解説ページのアイキャッチ Tkinterの使い方:フォントの指定方法

例えば下記のようにテキストウィジェットを生成すれば、そのテキストウィジェット内の文字のフォントサイズが 40 に変化することになります。

fontの指定例
text = tkinter.Text(
    # 略
    font=('', 40)
)

width

width は、テキストウィジェットの幅を指定するキーワード引数です。

width引数の説明図

width には、文字数を整数で指定します。これにより、その文字数分の文字が横方向に(極力)入力できるようにテキストウィジェットの幅が設定されます。文字の幅はフォントによって異なりますので、同じ整数を指定したとしても、font で設定したフォントによってテキストウィジェットの幅が変化することになります。また、文字の種類によって文字幅が異なるフォントを設定している場合は、入力する文字によっては一行に width で指定した文字数が入力できない場合や、その文字数を超えて文字が入力できる場合もあるので注意してください。

例えば下記のようにテキストウィジェットを生成すれば、そのテキストウィジェットが 10 文字分の幅に設定されます。

widthの指定例
text = tkinter.Text(
    # 略
    width=10
)

スポンサーリンク

height

height は、テキストウィジェットの高さを指定するキーワード引数です。

height引数の説明図

height には、width と同様に文字数を整数で指定します。これにより、その文字数分の文字が縦方向に入力できるようにテキストウィジェットの高さが設定されます。

例えば下記のようにテキストウィジェットを生成すれば、そのテキストウィジェットが 10 文字分の高さに設定されます。

heightの指定例
text = tkinter.Text(
    # 略
    height=10
)

background

background は、テキストウィジェット内の背景色を設定するキーワード引数です。background に関しては、略して bg キーワード引数で指定することも可能です。 

background引数の説明図

background の値としては、色名やカラーコード等を指定することが可能です。

例えば下記のようにテキストウィジェットを生成すれば、そのテキストウィジェット内の背景色が赤色に変化することになります。

backgroundの指定例
text = tkinter.Text(
    # 略
    background='red'
)

foreground

foreground は、テキストウィジェット内の文字色を設定するキーワード引数です。foreground に関しては、略して fg キーワード引数で指定することも可能です。 

foreground引数の説明図

foreground の値としては、色名やカラーコード等を指定することが可能です。

例えば下記のようにテキストウィジェットを生成すれば、そのテキストウィジェット内の文字色が青色に変化することになります。

foregroundの指定例
text = tkinter.Text(
    # 略
    foreground='blue'
)

スポンサーリンク

borderwidth

borderwidth は、テキストウィジェットの外枠の太さを設定するキーワード引数です。

borderwidth引数の説明図

borderwidth には整数を指定します。単位はピクセルです。

例えば下記のようにテキストウィジェットを生成すれば、テキストウィジェットの外枠の幅が 10 ピクセルに変化します。

borderwidthの指定例
text = tkinter.Text(
    # 略
    borderwidth=10
)

relief

relief は、テキストウィジェットの見た目を設定するキーワード引数です。

relief引数の説明図

relief に指定可能な値や、それらの値を指定したときのウィジェットの見た目に関しては下記ページで解説していますので、詳しくは下記ページの relief をご参照ください(フレームの例で説明していますが、見た目の変化に関してはテキストウィジェットにおいても同様になります)。

フレームウィジェットの作り方の解説ページアイキャッチ Tkinterの使い方:フレームウィジェット(Frame)の使い方

relief の指定によってウィジェットの見た目が変化するのは外枠が太い場合です。boarderwidth に小さい値が指定されていたりデフォルト値のままだったりすると relief の指定を変更しても見た目が変化しないので注意してください。

例えば下記のようにテキストウィジェットを生成すれば、そのテキストウィジェットが浮き上がるような見た目に変化します。

reliefの指定例
text = tkinter.Text(
    # 略
    borderwidth=10,
    relief=tkinter.RAISED
)

state

state は、テキストウィジェットの状態を設定するキーワード引数です。

state引数の説明図

state には下記の2つの値が指定可能です。デフォルトは tkinter.NORMAL となります。また、tkinter.DISABLED を指定して無効化すると、そのテキストウィジェットには文字の入力等が不可となります。

  • tkinter.NORMAL:有効化
  • tkinter.DISABLED:無効化

例えば下記のようにテキストウィジェットを生成すれば、そのテキストウィジェットへの文字入力が不可となります。

stateの指定例
text = tkinter.Text(
    # 略
    state=tkinter.DISABLED
)

スポンサーリンク

padxpady

padx は、テキストウィジェット内の余白の横幅を指定するキーワード引数、pady は、テキストウィジェット内の余白の縦幅を指定するキーワード引数となります。

padx引数とpady引数の説明図

padxpady には整数を指定します。単位はピクセルです。

例えば下記のようにテキストウィジェットを生成すれば、そのテキストウィジェット内の余白の横幅が 10 ピクセル、余白の縦幅が 20 ピクセルとなります。

padxとpadyの指定例
text = tkinter.Text(
    # 略
    padx=10,
    pady=20
)

selectbackground

selectbackground は、選択範囲の背景色を設定するキーワード引数です。

selectbackground引数の説明図

selectbackground の値としては、色名やカラーコード等を指定することが可能です。

例えば下記のようにテキストウィジェットを生成すれば、そのテキストウィジェット内で選択された文字列の背景色が緑色になります。

selectbackgroundの指定例
text = tkinter.Text(
    # 略
    selectbackground='green'
)

selectforeground

selectforeground は、選択範囲の文字色を設定するキーワード引数となります。

selectforeground引数の説明図

selectforeground の値としては、色名やカラーコード等を指定することが可能です。

例えば下記のようにテキストウィジェットを生成すれば、そのテキストウィジェット内で選択された文字列の文字色がオレンジ色になります。

selectforegroundの指定例
text = tkinter.Text(
    # 略
    selectforeground='orange'
)

スポンサーリンク

inactiveselectbackground

inactiveselectbackground は、フォーカスが外れたテキストウィジェットにおける、選択範囲の背景色を設定するキーワード引数です。

操作中のテキストウィジェットはフォーカスが当たっている状態なので、その状態では選択範囲の背景色は selectbackground で指定した色となりますが、選択した状態のまま他のテキストウィジェットの操作を行うと、元々操作していたテキストウィジェットのフォーカスが外れることになり、その際には選択範囲の背景色が inactiveselectbackground で指定した色に変化することになります。

inactiveselectbackground引数の説明図

inactiveselectbackground の値としては、色名やカラーコード等を指定することが可能です。

例えば下記のようにテキストウィジェットを生成すれば、そのテキストウィジェットのフォーカスが外れた際には、選択された文字列の背景色が灰色になります。

inactiveselectbackgroundの指定例
text = tkinter.Text(
    # 略
    inactiveselectbackground='gray'
)

highlightthickness

highlightthickness は、フォーカス枠(そのテキストウィジェットにフォーカスが当たっていることを示す枠)の太さを設定するキーワード引数です。フォーカス枠が存在する場合、テキストウィジェットにフォーカスが当たっていればフォーカス枠の色が特定の色に変化し、フォーカスが外れればフォーカス枠の色が他の色に変化するようになっています。なので、このフォーカス枠より、そのテキストウィジェットにフォーカスが当たっているかどうかを判断することができます。

highlightthickness引数の説明図

highlightthickness には 0 以上の整数を指定します。単位はピクセルとなります。デフォルトは、おそらく 0 となります。したがって、フォーカスが当たっていることを視覚的に判断できるようにしたいのであれば、highlightthickness 引数を指定して 1 以上の整数を設定する必要があります。

例えば下記のようにテキストウィジェットを生成すれば、そのテキストウィジェットのフォーカス枠の太さが 10 となります。

highlightthicknessの指定例
text = tkinter.Text(
    # 略
    highlightthickness=10
)

highlightcolorhighlightbackground

highlightcolor は、先ほど説明したフォーカス枠における、フォーカスが当たっているときの枠の色を設定するキーワード引数です。それに対し、highlightbackground は、フォーカスが外れているときの枠の色を指定するキーワード引数となります。

highlightcolor引数とhighlightbackground引数の説明図

highlightcolorhighlightbackground の値としては、色名やカラーコード等を指定することが可能です。

例えば下記のようにテキストウィジェットを生成すれば、そのテキストウィジェットにフォーカスが当たっているときはフォーカス枠の色が赤色となり、フォーカスが外れているときはフォーカス枠の色が青色に変化するようになります。

highlightcolorとhighlightbackgroundの指定例
text = tkinter.Text(
    # 略
    highlightthickness=10,
    highlightcolor='red',
    highlightbackground='blue'
)

スポンサーリンク

blockcursor

blockcursor は、挿入カーソルをブロック表示するかどうかを設定するキーワード引数です。

blockcursor引数の説明図

blockcursor には Bool 値(True or False)を指定します。True を指定すれば挿入カーソルがブロックで表示され、False を指定すれば挿入カーソルが縦線で表示されます。デフォルトは False となります。

例えば下記のようにテキストウィジェットを生成すれば、そのテキストウィジェット内では挿入カーソルがブロックで表示されることになります。

blockcursorの指定例
text = tkinter.Text(
    # 略
    blockcursor=True
)

insertbackground

insertbackground は、挿入カーソルの色を設定するキーワード引数です。

insertbackground引数の説明図

insertbackground の値としては、色名やカラーコード等を指定することが可能です。

例えば下記のようにテキストウィジェットを生成すれば、そのテキストウィジェット内の挿入カーソルが赤色で表示されることになります。

insertbackgroundの指定例
text = tkinter.Text(
    # 略
    insertbackground='red'
)

insertwidth

insertwidth は、挿入カーソルの太さを設定するキーワード引数です。

insertwidth引数の説明図

insertwidth には太さを整数で指定します。単位はピクセルです。

例えば下記のようにテキストウィジェットを生成すれば、そのテキストウィジェット内の挿入カーソルの太さが 10 になります。

insertwidthの指定例
text = tkinter.Text(
    # 略
    insertwidth=10
)

スポンサーリンク

insertborderwidth

insertborderwidth は、挿入カーソルの枠の太さを設定するキーワード引数です。

insertborderwidth引数の説明図

insertborderwidth には太さを整数で指定します。単位はピクセルです。

insertborderwidth がブロックの枠の太さを指定するキーワード引数であるのに対し、先ほど紹介した insertwidth は枠の内側の塗りつぶし部分の横幅を指定するキーワード引数となるようです。

例えば下記のようにテキストウィジェットを生成すれば、そのテキストウィジェット内の挿入カーソルの枠の太さが 10 になります。

insertborderwidthの指定例
text = tkinter.Text(
    # 略
    blockcursor=True,
    insertborderwidth=10
)

insertontimeinsertofftime

テキストウィジェット内の挿入カーソルは点滅して表示されることになります。この点滅における、点灯(表示時間)時間を設定するキーワード引数が insertontime、消灯(非表示時間)時間を設定するキーワード引数が inserofftime となります。

insertontime引数とinsertofftime引数の説明図

insertontimeinsertofftime には整数を指定します。単位はミリ秒となります。insertofftime0 を指定した場合は、挿入カーソルは点滅するのではなく、常に表示された状態となります。

例えば下記のようにテキストウィジェットを生成すれば、そのテキストウィジェット内の挿入カーソルは、点灯 1000 ミリ秒・消灯 100 ミリ秒の間隔で点滅することになります。

insertontimeとinsertofftimeの指定例
text = tkinter.Text(
    # 略
    insertontime=1000,
    insertofftime=100
)

insertunfocussed

insertunfocussed は、フォーカスが外れたときのテキストウィジェット内の挿入カーソルの表示の設定を行うキーワード引数です。

insertunfocussed引数の説明図

insertunfocussed に指定可能な値は下記の3つとなります。デフォルトは 'none' であり、フォーカスが外れたテキストウィジェットでは挿入カーソルが非表示になるようになっています。

  • 'none':非表示
  • 'solid':表示(枠+背景を塗りつぶしたカーソルが表示される)
  • 'hollow':表示(枠だけのカーソルが表示される)

'solid''hollow' を指定した場合は、フォーカスが外れたテキストウィジェットでも挿入カーソルが表示されるようになります。ただ、カーソルは点滅せず、点灯したままとなります。また、'solid''hollow' の違いが表れるのは、blockcursor で紹介した blockcursorTrue が指定されて挿入カーソルのブロック表示が有効になっている場合のみとなります。縦線表示時は違いが表れないので注意してください。

insertunfocussed='hollow'指定時のフォーカスが外れた時の挿入カーソルの見た目の説明図

例えば下記のようにテキストウィジェットを生成すれば、そのテキストウィジェットからフォーカスが外れても挿入カーソルは表示され続けるようになります。また、フォーカスが外れた際には、その挿入カーソルは枠だけのブロックとして表示されます。

insertunfocussedの指定例
text = tkinter.Text(
    # 略
    blockcursor=True,
    insertunfocussed='hollow'
)

スポンサーリンク

wrap

wrap は、テキストウィジェット内の文字列の折り返しの設定を行うキーワード引数です。

wrap引数の説明図

wrap に指定可能な値は下記の3つとなります。デフォルトは tkinter.CHAR となります。

  • tkinter.NONE:折り返し無し
  • tkinter.CHAR:文字単位で折り返し
  • tkinter.WORD:単語単位で折り返し

wrap=tkinter.NONE を指定している場合は、テキストウィジェット内の幅を超える文字を入力しても折り返しが行われず、テキストウィジェット内が横方向にスクロールして同じ行にどんどん文字が入力されていくことになります。したがって、改行しないと次の行への文字入力は不可となります。

wrap=tkinter.NONEを指定した場合の折り返し時の動作

wrap=tkinter.CHAR を指定している場合は、文字の入力により1行の文字列がテキストウィジェットの幅を超えると自動的に次の行への折り返しが行われることになります。この折り返しは文字単位で行われることになります。

wrap=tkinter.CHARを指定した場合の折り返し時の動作

wrap=tkinter.WORD を指定している場合も、文字の入力により1行の文字列がテキストウィジェットの幅を超えると自動的に次の行への折り返しが行われることになります。ただし、この折り返しは単語単位で行われることになります。

wrap=tkinter.WORDを指定した場合の折り返し時の動作

例えば下記のようにテキストウィジェットを生成すれば、そのテキストウィジェット内の文字列は折り返しが行われないようになります。

wrapの指定例
text = tkinter.Text(
    # 略
    wrap=tkinter.NONE
)

spacing1spacing2spacing3

spacing1spacing2spacing3 は、テキストウィジェット内の行間のスペースの大きさの設定を行うキーワード引数です。

spacing系の引数の説明図

これらはそれぞれ、spacing1 は改行された行の上側のスペースの大きさを設定するキーワード引数、spacing2 は自動的に折り返された行の行間のスペースの大きさを設定するキーワード引数、spacing3 は改行された行の下側のスペースの大きさを設定するキーワード引数となります。

spacing1とspacing2とspacing3の違いを説明する図

spacing1spacing2spacing3 には整数を指定します。これらのデフォルト値はすべて 0 となります。指定した整数の値に応じて行間のスペースの大きさが変化することになります。

例えば下記のようにテキストウィジェットを生成すれば、改行された行の下側のスペースが 20 に設定されることになります。

spacing3の指定例
text = tkinter.Text(
    # 略
    spacing3=20
)

undomaxundoautoseparators

undomaxundoautoseparators は「元に戻す(取り消し)・やり直す(やり直し)」の操作に関する設定を行うキーワード引数です。

undo引数の説明図

undo には Bool 値(True or False)が指定可能で、True を指定した場合には「元に戻す・やり直す」操作が可能となり、ショートカットキーの押下やメソッドの実行によって、これらの操作を行うことができるようになります。

さらに、maxundo には、「元に戻す」操作が実施可能な最大回数を整数で指定します。例えば、maxundo=2 を指定した場合は、一度に実行可能な「元に戻す」操作が最大2回となります。

また、元に戻す操作は、一度に最初の状態に戻るのではなく、何段階かに分けて元に戻していくことが可能です。つまり、特定のタイミングの状態が記録されており、元に戻す操作では、それらの各タイミングの状態に戻していくことが可能です。このような、特定のタイミングでの自動的な状態の保存の有効 / 無効を指定するのが autoseparators 引数となります。autoseparators には Bool 値(True or False)が指定可能で、True を指定した場合には上記のような特定のタイミングでの状態の保存が Tkinter によって自動的に行われるようになります。

autoseparatos=Trueの指定によって自動的に保存された状態に元に戻す・やり直すことが可能であることを示す図

False を指定した場合は、そのような特定のタイミングでの自動的な状態の保存が行われなくなります。なので、基本的には元に戻す操作を行うと最初の状態に戻ることになります。ただし、autoseparators=False を指定している場合でも、自動的な状態の保存は行われませんが、メソッドの実行によって状態の保存を行うことも可能です。これに関しては edit_separator で説明します。

例えば下記のようにテキストウィジェットを生成すれば、そのテキストウィジェット内の文字列の入力や削除を行った特定のタイミングの状態が最大 5 個分記録されるようになり、そのタイミングの状態への「元に戻す・やり直す」操作が可能となります。

undoとmaxundoとautoseparatorsの指定例
text = tkinter.Text(
    # 略
    undo=True,
    maxundo=5,
    autoseparators=True
)

スポンサーリンク

cursor

cursor は、マウスカーソルをテキストウィジェット上に移動させたときのカーソルの見た目を設定するキーワード引数です。

cursor引数の説明図

cursor に指定可能な値に関しては、公式の下記ページで紹介されていますので、下記ページを参考にしていただければと思います。

https://tcl.tk/man/tcl8.6/TkCmd/cursors.htm

例えば下記のようにテキストウィジェットを生成すれば、テキストウィジェット上にマウスカーソルを合わせたときのカーソルの見た目が「手」に変化します(Windows の場合は)。

cursorの指定例
text = tkinter.Text(
    # 略
    cursor='hand1'
)

xscrollcommandyscrollcommand

xscrollcommandyscrollcommand は、スクロールバー付きのテキストウィジェットを作成するためのキーワード引数となります。

xscrollcommand引数とyscrollcommand引数の説明図

スクロールバーについては別途下記ページで説明していますので、詳細については下記ページを参照してください。スクロールバー付のテキストウィジェット(テキストボックス)の作り方についても解説しています。

スクロールバーの作成方法解説ページアイキャッチ Tkinterの使い方:スクロールバー(Scrollbar)の使い方

例えば下記を実行すれば、横方向&縦方向のスクロールバー付きのテキストウィジェットを作成することができます。今までの例とは異なり、xscrollcommandyscrollcommand の指定はコンストラクタではなく config メソッドで実行しているという点に注意してください。また、スクロールバーは横方向や縦方向に入力された文字が入りきらなくなった時に表示されるようになっています。特に横方向に関しては、wrap'none' 以外を指定していると自動的に折り返しが行われて横方向に文字が入りきらなくなることが無くなり、横方向のスクロールバーの意味も無くなることになるので、この点にも注意してください。

xscrollcommandとyscrollcommandの指定例
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

get は、引数で指定されたインデックスの位置の文字列を取得するメソッドとなります。

インデックスの詳細については テキストウィジェットでのインデックスの指定 をご参照ください。

第1引数(引数 index1)と第2引数(引数 index2)のそれぞれにインデックスを指定して get  メソッドを実行することで、それらのインデックスの位置の間の文字列を返却値として取得することができます。

getメソッドの説明図

また、第2引数の指定を省略した場合、第1引数に指定されたインデックスの位置の後ろの文字のみが返却されることになります。

getメソッドの説明図2

例えば下記を実行すれば、テキストウィジェット内に入力された1行目の文字列が全て出力されることになります(改行は含まない)。

getの実行例
#text:テキストウィジェット
print(text.get(1.0, 1.end))

insert

insert は、引数で指定されたインデックスの位置に文字列を挿入するメソッドとなります。

インデックスの詳細については テキストウィジェットでのインデックスの指定 をご参照ください。

第1引数(引数 index1)にインデックス、第2引数(引数 text)に文字列を指定して insert  メソッドを実行することで、第1引数で指定されたインデックスの位置に第2引数で指定した文字列が挿入されることになります。

insertメソッドの説明図

例えば下記を実行すれば、1行目と2行目の間に Hello World! が挿入されることになります。

insertの実行例
#text:テキストウィジェット
text.insert(2.0, 'Hello World!\n')

delete

delete は、引数で指定されたインデックスの位置の文字列を削除するメソッドとなります。

インデックスの詳細については テキストウィジェットでのインデックスの指定 をご参照ください。

第1引数(引数 index1)と第2引数(引数 index2)のそれぞれにインデックスを指定して delete  メソッドを実行することで、それらのインデックスの位置の間の文字列が削除されることになります。

deleteメソッドの説明図1

また、第2引数の指定を省略した場合、第1引数に指定されたインデックスの位置の後ろの文字のみが削除されることになります。

deleteメソッドの説明図2

例えば下記を実行すれば、テキストウィジェット内に入力された先頭の文字のみが削除されることになります。

deleteの実行例
#text:テキストウィジェット
text.delete(1.0)

スポンサーリンク

search は、テキストウィジェット内から文字列を検索するメソッドとなります。

第1引数(引数 pattern)に文字列を、第2引数(引数 index)にインデックスを指定して search  メソッドを実行することで、第2引数で指定されたインデックスの位置から第1引数で指定された文字列の検索が行われることになります。見つかった場合は、その位置を示す '行番号.列番号' 形式のインデックスが返却され、見つからなかった場合は空の文字列 '' が返却されることになります。

searchメソッドの説明図

さらに、search  メソッドには下記のような引数をオプションで指定することが可能です。

  • stopindex=インデックス:検索範囲の終端を示すインデックス
    • (指定しない場合はテキストウィジェットに入力されている最後の文字の後ろが終端となる)
  • forwards=True:検索を検索範囲の始端側から実施する(デフォルト)
  • backwards=True:検索を検索範囲の終端側から実施する
  • exact=True:第1引数に完全一致する文字列のみを検索する(デフォルト)
  • regex=True:第1引数に正規表現が指定可能となる
  • nocase=True:大文字小文字を区別せずに検索する

例えば下記を実行すれば、テキストウィジェット内の先頭から Hello という文字列の検索が行われることになります(大文字と小文字の区別なしでの検索)。

searchの実行例
#text:テキストウィジェット
ret = text.search('Hello', 1.0, nocase=False)
if ret == '':
    print('Helloは存在しません')
else:
    print('Helloは(' + ret + ')の位置に存在します')

index

index は、'行番号.列番号' 形式以外のインデックスを '行番号.列番号' 形式のインデックスに変換するメソッドになります。

indexメソッドの説明図

第1引数(引数 index)に '行番号.列番号' 形式以外のインデックスを指定して index メソッドを実行すれば、返却として '行番号.列番号' 形式のインデックスが得られます。指定可能なインデックスに関しては テキストウィジェットでのインデックスの指定 を参照してください。

例えば下記を実行すれば、選択中の文字列の最後の文字の後ろの位置を示す '行番号.列番号' 形式のインデックスが出力されることになります。

indexの実行例
#text:テキストウィジェット
print(text.index('sel.last'))

edit_undoedit_redo

ここからは「元に戻す(取り消し)・やり直す(やり直し)」操作に関連するメソッドを紹介していきます。

まず edit_undo は「元に戻す」を実行するメソッドになります。それに対し、edit_redo は、直前に実施した「元に戻す」を取り消してやり直しするメソッドとなります。これらのメソッドは引数なしで実行可能です。

edit_undoとedit_redoメソッドの説明図

ただし、テキストウィジェットの「元に戻す」においては、「事前に記録されていた状態」へのみ元に戻すことが可能です。逆に記録されていない状態へ元に戻すことはできません。undo・maxundo・autoseparators の節で解説したように、テキストウィジェットに autoseparators=True を指定しておけば、文字の挿入や削除が行われたタイミングで自動的に状態の記録が行われるようになります。そして、edit_undoedit_redo を実行することで、その記録された状態に元に戻したり、その操作をやり直したりすることが可能となります。

これらのメソッドの実行例に関しては、次の edit_separator の節で示します。

また、状態の記録が行われていない場合や、記録されている状態に対する「元に戻す」が全て実施された後に edit_undo を実行すると下記のような例外が発生するので注意してください。

_tkinter.TclError: nothing to redo

スポンサーリンク

edit_separator

edit_separator は「元に戻す」を実行するための状態の記録を実施するメソッドになります。

undo・maxundo・autoseparators の節で解説したように、テキストウィジェットに autoseparators=True を指定しておけば自動的に状態の記録が行われるようになります。ですが、autoseparators=False を指定している場合であっても、edit_separator メソッドを利用すれば、開発者の好きなタイミングで状態の記録を実行することができるようになります。

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 の指定によって自動的に記録された状態をすべてクリアするメソッドになります。

text_editメソッドの説明図

edit_reset 実行時には引数は不要です。

例えば下記を実行すれば、記録された状態が全てクリアされることになります。

resetの実行例
#text:テキストウィジェット
text.edit_reset()

edit_modified

edit_modified は、テキストウィジェット内の文字列に対する変更が行われたかどうかを管理する変更フラグを取得 or 変更フラグに値をセットするメソッドになります。

テキストウィジェットでは、特定のタイミングからテキストウィジェット内の文字列が入力や削除によって変更されたかどうかを変更フラグによって管理するようになっています。そして、edit_modified メソッドを「引数なし」で実行することで、その変更フラグを取得することができます。特定のタイミングからテキストウィジェット内の文字列が変更されていれば 1 が返却され、変更されていなければ 0 が返却されます。

edit_modifiedメソッドの説明図1

また、上記における “特定のタイミング” とは、基本的には「テキストウィジェット作成直後」となります。つまり空の状態のテキストウィジェットから変更されていた場合、edit_modified メソッドを「引数なし」で実行すると 1 が返却されることになります。ただし、この “特定のタイミング” は、edit_modified メソッドの引数に False を指定して実行することで変更することが可能です。つまり、edit_modified(False) を実行したタイミングからの変更の有無を edit_modified メソッドを「引数なし」で実行することで確認することができます。

edit_modifiedメソッドの説明図2

例えば、テキストエディターでは、開いたファイルを変更した場合、閉じるボタンをクリックすると「変更を保存しなくて良いか?」というメッセージが表示されたりしますよね?こういった動作も、下記のように 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引数に指定したタグ名のタグが付けられることになります。

tag_addメソッドの説明図

ただし、第1引数のタグ名に 'sel' は指定してはいけないので注意してください。Tkinter では選択範囲に対して 'sel' というタグ名が自動的に付けられるようになっています。にも関わらず、第1引数のタグ名に 'sel' を指定して tag_add を実行すると 'sel' の名前のタグが上書きされてしまうことになります。

逆に言えば、タグ名として 'sel' を指定することで、選択範囲に対して tag_bindtag_config が実行可能ということになります(tag_bindtag_config に関しては後述で解説します)。

tag_add メソッドの実行例に関しては、次の tag_bind メソッドと一緒に紹介します。

tag_bind

tag_bind は、タグ付けされた文字列に対するイベントの設定を行うメソッドになります。

第1引数にタグ名、第2引数にシーケンス、第3引数にイベントハンドラを指定して tag_bind メソッドを実行することで、第1引数で指定されたタグ名のタグが付けられた文字部分に対して第2引数で指定したシーケンスに対応するイベントが発生したタイミングで、第3引数に指定したイベントハンドラが実行されるようになります。

通常のイベントは bind メソッドで設定することになりますが、タグ付けされた文字列に対するイベントの設定は tag_bind で行うことになります。この tag_bind メソッドを利用することで、テキストウィジェット内の特定の文字列がクリックされた際に特定の処理が自動的に実行されるようにすることもできます。

tag_bindメソッドの説明図

イベントや bind メソッドに関しては下記ページで解説しており、シーケンスやイベントハンドラに関しても説明していますので、詳細を知りたい方は下記ページを参照してください。

イベント処理解説ページのアイキャッチ Tkinterの使い方:イベント処理を行う

例えば下記のスクリプトの場合、タグ付け ボタンがクリックされた際に選択された範囲の文字列に tag1 という名前のタグが付けられることになります。そして、そのタグ付けが行われた部分の文字列をマウスでクリックすれば、その tag1 のタグが付けられている文字列全体が出力されることになります。

tag_addとtag_bindの実行例
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 は、タグ付けされた文字列に対する各種設定を行うメソッドになります。

tag_configメソッドの説明図

第1引数にタグ名、さらに第2引数以降に下記のようなキーワード引数を指定して tag_config メソッドを実行することで、そのタグ名のタグが付けられた文字列部分の見た目やフォントを変更することが可能です。

  • background:背景色(カラーコードや色名で指定)
  • foreground:文字色(カラーコードや色名で指定)
  • underline:下線の有無(Bool 値で指定)
  • underlinefg:下線の色(カラーコードや色名で指定)
  • overstrike:取り消し線の有無
  • overstrikefg:取り消し線の色
  • font:文字のフォント(タプルやフォントオブジェクトで指定)

例えば下記のスクリプトでは、テキストウィジェット内の文字列を選択した状態で タグ付け ボタンをクリックすれば、その選択された文字列に tag1 という名前のタグが付けられることになります。その後に、下線 ボタンをクリックすれば underline 関数が実行されて、tag1 でタグ付けされた文字列部分に赤色の下線が追加されることになります。同様に、取り消し線 ボタンをクリックすれば overstrike 関数が実行されて、tag1 でタグ付けされた文字列部分に緑色の取り消し線が追加されることになります。さらに、ハイライト ボタンをクリックすれば highlight 関数が実行されて、tag1 でタグ付けされた文字列部分の背景色が黄・文字色が赤に変化し、サイズ大 ボタンをクリックすれば large 関数が実行されて、tag1 でタグ付けされた文字列部分のフォントサイズが 40 に変化することになります。

tag_configの実行例
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 は引数なしで実行します。

tag_names を利用することで、追加済みのタグのタグ名一覧を表示するようなことももちろん可能ですし、for ループを利用して、前述で紹介した tag_bindtag_config を全タグ名のタグに対して一括して実行するようなことも可能となります。

例えば下記を実行すれば、タグ付けされた文字列全ての背景色が赤色に変化することになります。

tag_namesの実行例
#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の説明図

tag_delete には、引数に削除したいタグのタグ名を指定します。複数のタグ名のタグを削除したい場合は、それらのタグ名をコンマ区切りで指定してやれば良いです。

例えば下記は、タグ名 'tag1''tag2'のタグを削除する例となります。

tag_deleteの実行例
#text:テキストウィジェット
text.tag_delete('tag1', 'tag2')

xviewyview

xviewyview はスクロールバー付テキストウィジェットを作成するときに利用するメソッドになります。

スクロールバーに関しては下記ページで解説していますので、これらのメソッドについて詳細を知りたい方は下記ページを参照してください。

スクロールバーの作成方法解説ページアイキャッチ Tkinterの使い方:スクロールバー(Scrollbar)の使い方

また、これらのメソッドを利用してスクロールバー付テキストウィジェットを作成するスクリプトの例に関しては xscrollcommand・yscrollcommand を参照していただければと思います。

スポンサーリンク

まとめ

このページでは、Tkinter のテキストウィジェットについて解説しました!

このテキストウィジェットを利用することで、Tkinter でテキストエディターのようなアプリを開発することも可能ですし、長文の入力受付を行うフォームやテキストを利用した様々なアプリやゲームも開発することが可能となります。

是非、このページで解説した内容を参考にして、テキストエディターを利用したアプリ開発に挑戦してみていただければと思います!

オススメ参考書(PR)

Tkinter に興味がある方には下記のPythonでつくる ゲーム開発 入門講座がオススメです。

Tkinter をゲーム開発を通して「楽しく学ぶ」ことができます。Python 入門者、Tkinter 入門者の方にオススメです。

同じカテゴリのページ一覧を表示