はじめに
以前Twitterのツイートで視線を動かさないように文章を提示されると
それなりに早いスピードで文字が切り替わっても
スムーズに読むことが出来るという主旨のツイートがありまして。
↓これですね。
それを見て読むのがあまり早くない自分でもこれだと多少早く読めるのではないかと思いまして
似たようなことをしてくれるアプリを作ってみました。
あくまで試作版なのでまだいろいろみづらかったりUIにはあるのに設定切り替える処理が実装されていなかったりはしますが、
一旦成果として記事にまとめてみようと思った次第です。
もうちょい改良してみて自分でも使いやすいのにはその内していく所存。
今日は実際に書いた内容についてちょっと解説とまではいきませんが、簡単に説明していこうかなと思います。
開発環境
前提
実施した環境は以下の通りです。
・macOS Catalina
・Python 3.7.4
・pip 19.2.3
使用したパッケージ
今回使用したパッケージは以下の通りです。
・PySimpleGUI:今回はローカルで使える簡易的なものとして作ってみたかったので気になってたこれを使ってみた。
$ pip install pysimplegui
・janome : 読み込んだテキストを単語単位に形態素解析をするために使用。
$ pip install janome
実際のコード
とりあえず動けばいい精神で書いたのでかなり雑でお目汚しになってしまいますが上げておきます・・・。
# -*- coding: utf-8 -*-
import PySimpleGUI as sg
import time
from janome.tokenizer import Tokenizer
t = Tokenizer()
sg.theme('Dark Blue 3')
flg_read = False
flg_start = False
text_body = ''
file_name = ''
word_list = None
# レイアウト生成
layout = [
[sg.Text('読み込むテキストファイルを選択してください', size=(45, 1))],
[sg.InputText('', key='file_name', disabled=True), sg.FileBrowse(key='file_browse', file_types=(('Text Files', '*.txt'),)) ],
[sg.Button('テキストファイルを読み込む', key='read')],
[sg.Text('')],
[sg.Text('表示速度(0.1〜10.0)', size=(15, 1)), sg.InputText('1.0', size=(3, 1))],
[sg.InputText('ああああ', key='display_text', disabled=True)],
[sg.Button('<<', key='first'), sg.Button('<10', key='back10'), sg.Button('▶︎', key='start'), sg.Button('10>', key='next10') ],
]
# ウィンドウ生成
window = sg.Window('文字送りアプリ', layout)
index = 0
while True:
# 文字送りするためにタイムアウトを設定
event, values = window.read(timeout=500,timeout_key='-timeout-')
if event is None:
print('exit')
break
# 設定した時間が経過、かつ再生中の場合は文章の文字送りする
if event == '-timeout-' and flg_start:
window['display_text'].update(word_list[index])
index += 1
# ファイル読み込みイベント
if event == 'read':
file_name = values['file_browse']
print(file_name)
if file_name == '':
# ポップアップで実装予定
print('ファイルを選択してください')
else:
# その他エラーチェックの実装が必要
# 文字コードどうにかしたい
with open(file_name, encoding='shift_jis') as f:
text_body = f.read()
word_list = [token.surface for token in t.tokenize(text_body)]
flg_read = True
# ポップアップで実装予定
print('読み込みが完了しました')
# 最初の単語まで戻すイベント
if event == 'first':
index = 0
flg_start = False
# 単語10個前まで早戻しイベント
if event == 'back10':
index -= 10
# 再生/停止イベント
if event == 'start':
if flg_start:
flg_start = False
window['start'].update('▶︎')
print('停止中')
else:
flg_start = True
window['start'].update('||')
index += 1
print('再生中')
# 単語10個先まで早送りイベント
if event == 'next10':
index += 10
# ウィンドウ破棄
window.close()
実際の画面
切り抜きですが実際の画面です。
実際に操作してる動画が撮れたら後ほど上げておきます。
説明
処理の流れ
今実装できている流れとしては、
- テキストファイルを選択する。
- テキストファイルの内容を読み込ませる。(ここで形態素解析して単語に分けてる)
- 再生ボタンを押下して文字送りを再生。
実際にUI上は早送りとか早戻しのようなボタンありますが、まだ実装しきれてないです。
苦戦したところ
最初特に何も考えてないで実装してみてた時は文字の更新を再生ボタン押下したときのイベント内で
文字の更新処理(key:display_textのupdate処理)を行っていたんですが、一向に更新してくれる気配なくて
じゃあどうすればええんじゃ・・・?ということで悩んでました。
PySimpleGUIの画面描画のロジックが分からなくて悩んでいましたが、
window.read()の処理通らないとupdate()処理が発火しない感じなんですかね・・・。
プロセス関連の話なのかなーと思ってふとタイマーの処理とかPySimpleGUIだとどう書くんだと思って調べてたら
以下記事にたどり着きましてtimeoutの設定の存在を知ることで上記実装とすることができました。
これは使えるのではと思い、実際にtimeoutを設定し、かつ再生中のときのフラグ設定をすることでなんとか自分が動かしたい処理を実装できました。
大体いつも並列処理的なもの実装する時は苦戦するな・・・。
やり残し
まだいろいろ改善点ばかりなので修正していきたい。
そもそも見にくいレイアウトなのでもう少し修正しなければ・・・。
最低限文字切り替わるところはもう少し大きめに表示するなり、フォントサイズ切り替えられるようにしないとというところですね。
あとは表示速度を切り替えるようにはしておきたい。
テキストボックスに設定する値も上限、下限の設定もしておかんと。
あとは設定出来るファイルの種類がテキストファイルだけでなくなんでも設定できてしまうのでそこらへんとあと文字コード気にせず読み込めるようにすることが大きなところですかね。
引き続きちょっとずつ修正してその内、gitにも上げておきたい。
最後に
とりあえず自分が最低限やりたいことは書ききれてよかった。
久しぶりにちゃんと動くGUIアプリ作りましたが上の処理までは4時間ぐらいで書けました。
前はTinker使ってGUIアプリ書いてみたことはありましたが「めんどくさ・・・」と思って
挫折してたのでいいライブラリが見つけられて試しに使えてよかった。
今後ももう少しPySimpleGUIを使っていろいろ試してみたい。
GUIアプリ作るの楽しい。
janomeの使い方とか諸々説明省いたところはあるのでそれはまた別記事で書いて行こうかなーと思います。
では今日はこの辺で。
それでは〜
コメント