「PythonでGUIアプリ開発」に挑戦!Tkinter/Ttk編 その14
「PythonでGUIアプリ開発」に挑戦!Tkinter/Ttk編 その14ステップ01 ウインドウを表示するステップ02 ボタンでメッセージボックスステップ03 クラスでコーディングを楽にステップ04 「終了」メニューを作ろうステップ05 必須の「バージョン情報」ステップ06 ヘルプはWebサイトに置くステップ07 Textで複数行の処理ステップ08 スクロールバーを付けようステップ09 ウインドウの大きさを取得ステップ10 INIファイルに設定を保持ステップ11 空のメニュー項目を作るステップ12 ファイル処理を実装するおまけ .pyファイルのexe化## ステップ11 空のメニュー項目を作る# 『日経ソフトウエア』2021年9月号「特集1 PythonでGUIアプリ開発」の基礎(p.16~p.17)## リスト15、リスト16 TextEdit11.py# 「ファイル」メニューを作るために、TextEditクラスのコンストラクター# (__init__メソッド)に(1)~(3)を追加。# # リスト14に付け加えた部分は、(1)~(3)# モジュール(tkinter)のインポートfrom tkinter import *# モジュール(messagebox, ttk)のインポート# messageboxモジュール:メッセージボックスを表示するfrom tkinter import messagebox, ttk# webbrowserモジュールをインポートするimport webbrowser# (a)ScrolledTextモジュールをインポートするfrom tkinter.scrolledtext import ScrolledText# (0)configparserモジュールをインポートするコードを追加。import configparser# 「TextEdit」クラスの定義class TextEdit: def __init__(self, root): root.title(self.__class__.__name__) # 変数clientHeightとclientWidthを用意し、文字列50と300で初期化しておき、 # INIファイルからの値の読み込みが失敗した時(INIファイルがなかった時など)に初期値を使う。 clientHeight = '50' clientWidth = '300' # ConfigParserのインスタンスcpを用意する。 cp = configparser.ConfigParser() try: # INIファイルを読み込む準備 cp.read(self.__class__.__name__ + '.ini') # 「client」の「Height」を読み込む。 clientHeight = cp['Client']['Height'] # 「client」の「Width」を読み込む。 clientWidth = cp['Client']['Width'] except: # で例外が発生した場合に、「TextEdit:Use default value(s)」とエラー出力にメッセージを出す。 print(self.__class__.__name__ + ':Use default value(s)', file=sys.stderr) # root.geometry(clientWidth + 'x' + clientHeight) # root.protocol('WM_DELETE_WINDOW', self.menuFileExit) # メニューの切り離し(tear off)を禁じるコード root.option_add('*tearOff', FALSE) # Menuクラスのインスタンスを生成し、名前「menu」で参照可能にする menu = Menu(root) # もう一つMenuクラスのインスタンスを生成し、名前「menuFile」で参照可能にする menuFile = Menu(menu) # menuの「add_cascade」メソッドを呼び出し、menu・label・underlineオプションを指定する # menuオプションに、「menuFile」を指定 # labelオプションに、メニューとして表示する文字列「ファイル(F)」を指定する。 # underlineオプションは、文字列の何番目に下線を引くかを設定するもので、 # 「F」は文字列「ファイル(F)」の6番目であるため、「5」(最初の文字が「0」)を設定。 menu.add_cascade(menu=menuFile, label='ファイル(F)', underline=5) # (1)-1 menuFileにコマンド「新規(N)」を追加 menuFile.add_command(label='新規(N)', underline=3, command=self.menuFileNew) # (1)-2 menuFileにコマンド「開く(O)」を追加 menuFile.add_command(label='開く(O)', underline=3, command=self.menuFileOpen) # (1)-3 menuFileにコマンド「保存(S)」を追加 menuFile.add_command(label='保存(S)', underline=3, command=self.menuFileSave) # (1)-4 menuFileにコマンド「保存(A)」を追加 menuFile.add_command( label='名前を付けてシフトJISで保存(A)', underline=16, command=self.menuFileSaveAsSjis) # (1)-5 menuFileにコマンド「保存(U)」を追加 menuFile.add_command( label='名前を付けてUTF-8で保存(U)', underline=15, command=self.menuFileSaveAsUtf8) # (2) セパレータを追加 menuFile.add_separator() # menuFileにコマンド「終了(X)」を追加 menuFile.add_command(label='終了(X)', underline=3, command=self.menuFileExit) # もう一つMenuクラスのインスタンスを生成し、名前「menuHelp」で参照可能にする menuHelp = Menu(menu) # menuの「add_cascade」メソッドを呼び出し、menu・label・underlineオプションを指定する # menuオプションに、「menuHelp」を指定 # labelオプションに、メニューとして表示する文字列「ヘルプ(H)」を指定する。 # underlineオプションに、「H」に下線を引くため、「H」は文字列「ヘルプ(H)」の5番目なので、「4」を設定。 menu.add_cascade(menu=menuHelp, label='ヘルプ(H)', underline=4) # menuHelpにコマンド「Webサイトを開く(W)」を追加 menuHelp.add_command(label='Webサイトを開く(W)', underline=10, command=self.menuHelpOpenWeb) # 区切り線(セパレーター)を表示するコード menuHelp.add_separator() # menuHelpにコマンド「バージョン情報(V)」を追加 menuHelp.add_command(label='バージョン情報(V)', underline=8, command=self.menuHelpVersion) root['menu'] = menu # (b)Textウィジェットのインスタンスを作成し、textという名前で参照できるようにする。 text = ScrolledText(root) # textのpackメソッドを呼び出す。 # expandオプションを1に、fillオプションをBOTHに設定 # このような設定にしないと、ウインドウの大きさを変えた時に、テキスト領域がクライアント領域いっぱいに広がらない。 text.pack(expand=1, fill=BOTH) # リスト16 # TextEditクラスに、メニューコマンドのイベントハンドラーを5個追加する。 # 中身は「Pass」と書いておくだけで、まだ、実際の内容はまだ書かない。 # (3)-1 def menuFileNew(self): pass # (3)-2 def menuFileOpen(self): pass # (3)-3 def menuFileSave(self): pass # (3)-4 def menuFileSaveAsSjis(self): pass # (3)-5 def menuFileSaveAsUtf8(self): pass def menuFileExit(self): # ConfigParserクラスのインスタンスを生成し、cpという名前で参照できるようにする。 cp = configparser.ConfigParser() #「Client]というセクションに「Height」というキーを作り、その値としてクライアント領域の高さを文字列にしたものを与える。 # 同じセクションに「Width」というキーを作り、その値としてクライアント領域の幅を文字列にしたものを与える。 cp['Client'] = { 'Height': str(root.winfo_height()), 'Width': str(root.winfo_width())} #「TextEdit.」というファイルを書き込み可能にして開き、それをconfigfileという名前で参照できるようにし、configfileにデータを書き込む。 with open(self.__class__.__name__ + '.ini', 'w') as f: cp.write(f) # プログラムを終了する。 root.destroy() # 「Webサイトを開く(W)」メニューの処理 def menuHelpOpenWeb(self): #変数sを宣言し、そこにクラス名「TextEdit」を入れる webbrowser.open( 'https://info.nikkeibp.co.jp/media/NSW/') # バージョン情報メニューの処理 def menuHelpVersion(self): # 変数sを宣言し、そこにクラス名「TextEdit」を入れる s = self.__class__.__name__ # バージョン番号(0.01)、年月日、改行(\n) s += ' Version 0.01(2021/03/10)\n' # 著作権表記 s += ' ©2021 Hideo Harada\n' # Pythonのシステム情報 s += 'with Python ' + sys.version # 変数sに格納された文字列をメッセージボックスに表示する messagebox.showinfo( self.__class__.__name__, s) # #def menuHelpExit(self): #root.destroy() # 「root」root = Tk()TextEdit(root)# root.mainloopの開始root.mainloop()リスト15、リスト16(TextEdit11.py)の実行結果