質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

4702閲覧

【Python】wxPythonで入力したテキストをファイルに保存させたい。

Python.R

総合スコア28

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2018/12/29 05:59

編集2018/12/29 15:17

現在自分の使っている各種プログラミング言語の文法をまとめて確認できるツールを作っています。
見た目は下記の通りです。
ツールのレイアウト
タブごとに言語が並んでおり、最後のタブにテキストエリアを設けています。
テキスト入力エリア
そして画面下に入力したテキストを保存するボタンを配置しました。

ここからが問題でした。ボタンを配置したは良いが、Bindメソッドを使いどのように、イベントとテキスト情報を取得し、関数で処理をさせるか?
詳しい方いましたら、ぜひ知恵を貸していただきたいです。

ちなみに、私はまだクラスを用いた複雑な設計は理解できないことが多く、まだ難しいです。

以下が書いたコードになります。できるだけ、コードをするなくしようと努力しましたが、現時点で200行以上あります。
#コード

Python

1import wx 2import os 3import glob 4from mutagen.mp3 import MP3 as mp3 5import pygame 6 7class Prog_lgs(): 8 def python_button_func(event): # Python用の関数を宣言 9 pygame.mixer.init() 10 pygame.mixer.music.load('md\nc106374.wav') 11 pygame.mixer.music.play(1) 12 if event.GetId() == 3: 13 os.system('data\py\3_list_and_loop.txt') 14 elif event.GetId() == 4: 15 os.system('data\py\4_function_and_module.txt') 16 elif event.GetId() == 1: 17 os.system('data\py\1_variable.txt') 18 elif event.GetId() == 2: 19 os.system('data\py\2_input_and_if.txt') 20 elif event.GetId() == 5: 21 os.system('data\py\5_file_control.txt') 22 elif event.GetId() == 6: 23 os.system('data\py\6_text_control.txt') 24 elif event.GetId() == 7: 25 os.system('data\py\7_recall_function.txt') 26 elif event.GetId() == 8: 27 os.system('data\py\8_COM_Sapi.txt') 28 elif event.GetId() == 9: 29 os.system('data\py\9_CSV_database_control.txt') 30 elif event.GetId() == 10: 31 os.system('data\py\10_time_method.txt') 32 elif event.GetId() == 11: 33 os.system('data\py\11_key_event.txt') 34 elif event.GetId() == 12: 35 os.system('data\py\12_sort_algorithm.txt') 36 def c_button_func(event): # C言語用の関数を宣言 37 if event.GetId() == 200: 38 os.system('data\c\1_variable.txt') 39 elif event.GetId() == 201: 40 os.system('data\c\2_list_and_loop.txt') 41 elif event.GetId() == 202: 42 os.system('data\c\3_input_and_if.txt') 43 elif event.GetId() == 203: 44 os.system('data\c\4_file_control.txt') 45 elif event.GetId() == 204: 46 os.system('data\c\5_pointer_and_function.txt') 47 def java_button_func(event): # Java用の関数を宣言 48 if event.GetId() == 400: 49 os.system('data\java\1_kihon.txt') 50 elif event.GetId() == 401: 51 os.system('data\java\2_input.txt') 52 elif event.GetId() == 402: 53 os.system('data\java\3_if.txt') 54 elif event.GetId() == 403: 55 os.system('data\java\4_loop.txt') 56 elif event.GetId() == 404: 57 os.system('data\java\5_list.txt') 58 elif event.GetId() == 405: 59 os.system('data\java\6_sqpow.txt') 60 61#プロンプトで表示するように作った関数です 62def save_text(tmp): 63 print(tmp) 64 65def run_music(): 66 pygame.mixer.init() 67 pygame.mixer.music.load('md\mens-ou1.mp3') #音源を読み込み 68 #再生開始。1の部分を変えるとn回再生(その場合は次の行の秒数も×nすること) 69 pygame.mixer.music.play(1) 70 71application = wx.App() 72frame = wx.Frame(None, wx.ID_ANY, 'プログラミング言語文法確認ツール', size=(700, 450)) 73run_music() 74frame.CreateStatusBar() 75#image = wx.Image('img\background.jpg') 76#bitmap = image.ConvertToBitmap() 77icon = wx.Icon('img\tool_logo.ico',wx.BITMAP_TYPE_ICO) 78frame.SetIcon(icon) 79 80notebook = wx.Notebook(frame, wx.ID_ANY) 81 82#それぞれのパネルにnotebook(タブ)の属性を付与する 83panel_1 = wx.Panel(notebook, wx.ID_ANY) 84panel_2 = wx.Panel(notebook, wx.ID_ANY) 85panel_3 = wx.Panel(notebook, wx.ID_ANY) 86panel_4 = wx.Panel(notebook, wx.ID_ANY) 87panel_5 = wx.Panel(notebook, wx.ID_ANY) 88 89#タブパネルごとのバックグラウンドカラーを指定 90panel_1.SetBackgroundColour('#BCF5F1') 91panel_2.SetBackgroundColour('#F2C0BC') 92panel_3.SetBackgroundColour('#F3ECAF') 93panel_4.SetBackgroundColour('#ADEDB2') 94panel_5.SetBackgroundColour('#B1BDF6') 95 96#タブメニュー文字列の表示を指定 97notebook.InsertPage(0, panel_1, 'Python') 98notebook.InsertPage(1, panel_2, 'C言語') 99notebook.InsertPage(2, panel_3, 'Java') 100notebook.InsertPage(3, panel_4, 'VBS') 101notebook.InsertPage(4, panel_5, 'メモエリア') 102 103# それぞれのタブにアイコンを設定する 104image_list = wx.ImageList(30, 30) 105image_list_bata = sorted(glob.glob(".\img\tab_icon\*.ico")) 106for i in range(len(image_list_bata)): 107 icon = wx.Icon(image_list_bata[i], wx.BITMAP_TYPE_ICO) 108 image_list.Add(icon) 109notebook.AssignImageList(image_list) 110for i in range(len(image_list_bata)): 111 notebook.SetPageImage(i, i) 112 113# パネル5のテキストボックス 114text_main = wx.TextCtrl(panel_5, wx.ID_ANY, style = wx.TE_MULTILINE) 115text_main.SetBackgroundColour('#0D0D0D') 116text_main.SetForegroundColour('#FFFFFF') 117 118##################################### 119# ボタンの戻り値と表示文字列の指定 120##################################### 121# Pythonタブ用 122button_1_py = wx.Button(panel_1, 1, '変数') 123button_2_py = wx.Button(panel_1, 2, '入力と\n条件分岐') 124button_3_py = wx.Button(panel_1, 3, 'リストとループ') 125button_4_py = wx.Button(panel_1, 4, '関数と\nモジュール') 126button_5_py = wx.Button(panel_1, 5, 'ファイル操作') 127button_6_py = wx.Button(panel_1, 6, 'テキスト処理\n(乱数・正規表現)') 128button_7_py = wx.Button(panel_1, 7, '再起呼出\n(2進数計算)') 129button_8_py = wx.Button(panel_1, 8, 'COM(Sapi)') 130button_9_py = wx.Button(panel_1, 9, 'CSVメソッド\nデータベース処理') 131button_10_py = wx.Button(panel_1, 10, 'timeメソッド\n(時間制御)') 132button_11_py = wx.Button(panel_1, 11, 'getchメソッド\n(キー操作)') 133button_12_py = wx.Button(panel_1, 12, 'ソート\nアルゴリズム') 134python_button = [button_1_py, button_2_py, button_3_py, button_4_py, button_5_py, 135button_6_py, button_7_py, button_8_py, button_9_py, button_10_py, button_11_py, 136button_12_py] 137# C言語タブ用 138button_1_c = wx.Button(panel_2, 200, '変数\n(基礎文法)') 139button_2_c = wx.Button(panel_2, 201, 'リストとループ') 140button_3_c = wx.Button(panel_2, 202, '入力と\n条件分岐') 141button_4_c = wx.Button(panel_2, 203, 'ファイル操作') 142button_5_c = wx.Button(panel_2, 204, 'ポインタと関数') 143c_button = [button_1_c, button_2_c, button_3_c, button_4_c, button_5_c] 144# Javaタブ用 145button_1_java = wx.Button(panel_3, 400, '基本文法') 146button_2_java = wx.Button(panel_3, 401, '入力') 147button_3_java = wx.Button(panel_3, 402, '条件分岐') 148button_4_java = wx.Button(panel_3, 403, 'ループ処理') 149button_5_java = wx.Button(panel_3, 404, 'リスト・配列') 150button_6_java = wx.Button(panel_3, 405, '平方根・累乗') 151java_button = [button_1_java, button_2_java, button_3_java, button_4_java, 152button_5_java, button_6_java] 153 154#保存ボタンを生成 155test_button = wx.Button(panel_5, wx.ID_ANY, '保存', size = (0, 50)) 156 157################################# 158# フォントサイズの指定 159################################# 160font = wx.Font(20, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL) 161for i in range(len(python_button)): 162 python_button[i].SetFont(font) 163for i in range(len(c_button)): 164 c_button[i].SetFont(font) 165for i in range(len(java_button)): 166 java_button[i].SetFont(font) 167notebook.SetFont(font) # タブ全体のフォントサイズ指定 168text_main.SetFont(font) 169 170################################$ 171# ボタンクリック時の動作を指定 172################################# 173for i in range(len(python_button)): 174 frame.Bind(wx.EVT_BUTTON, Prog_lgs.python_button_func, python_button[i]) 175for i in range(len(c_button)): 176 frame.Bind(wx.EVT_BUTTON, Prog_lgs.c_button_func, c_button[i]) 177for i in range(len(java_button)): 178 frame.Bind(wx.EVT_BUTTON, Prog_lgs.java_button_func, java_button[i]) 179 180#入力したテキストを取得したかった。 181tmp = text_main.GetValue() 182test_button.Bind(wx.EVT_BUTTON, save_text(tmp)) 183 184################################# 185# ボタン配置のレイアウトを指定 186################################# 187layout_py = wx.GridSizer(rows=5, cols=3, gap=(0, 0)) 188for i in range(len(python_button)): 189 layout_py.Add(python_button[i], 0, wx.GROW) 190layout_c = wx.GridSizer(rows=5, cols=3, gap=(0, 0)) 191for i in range(len(c_button)): 192 layout_c.Add(c_button[i], 0, wx.GROW) 193layout_java = wx.GridSizer(rows=5, cols=3, gap=(0, 0)) 194for i in range(len(java_button)): 195 layout_java.Add(java_button[i], 0, wx.GROW) 196layout_textbox = wx.BoxSizer(wx.VERTICAL) 197layout_textbox.Add(text_main, 1, wx.EXPAND|wx.ALL) 198layout_textbox.Add(test_button, 0, wx.EXPAND|wx.ALL) 199panel_1.SetSizer(layout_py) 200panel_2.SetSizer(layout_c) 201panel_3.SetSizer(layout_java) 202panel_5.SetSizer(layout_textbox) 203 204frame.Centre() 205frame.Show() 206# wx.StaticBitmap(panel_1, 1, bitmap, pos=(0, 0), size=panel_1.GetSize()) 207application.MainLoop()

#やったこと
まずパネル5でテキストボックスを生成

Python

1# パネル5のテキストボックス 2text_main = wx.TextCtrl(panel_5, wx.ID_ANY, style = wx.TE_MULTILINE) 3text_main.SetBackgroundColour('#0D0D0D') 4text_main.SetForegroundColour('#FFFFFF')

そしてボタンを生成

Python

1#保存ボタンを生成 2test_button = wx.Button(panel_5, wx.ID_ANY, '保存', size = (0, 50))

それとレイアウトは、コード後半で行っています。

とりあえずここまではできたのですが、ボタンクリック時の動作を関数でそう処理すればようかわかりません。

##試したこと
試したことといっても、

Python

1#プロンプトで表示するように作った関数です 2def save_text(tmp): 3 print(tmp) 4 5・・・・中略・・・・ 6 7#入力したテキストを取得したかった。 8tmp = text_main.GetValue() 9test_button.Bind(wx.EVT_BUTTON, save_text(tmp))

これでまず入力したテキストを確認しようとしたが、ボタンを押しても反応なし。

##解決したいこと
冒頭で書いたとおり、入力したテキストをファイルに保存するところまでいきたいです。

また、ファイルに保存するコードは以前作ったものを組み込もうと思います。

Python

1app = wx.App() 2 frame_b = wx.Frame(None, wx.ID_ANY, 'ファイル参照', size=(700, 450)) 3 panel_b = wx.Panel(frame_b, wx.ID_ANY) 4 folder = wx.DirDialog(panel_b,style=wx.DD_CHANGE_DIR,message="保存先フォルダ") 5 if folder.ShowModal() == wx.ID_OK: 6 folder = folder.GetPath() 7 with codecs.open(f'{folder}\test.txt', 'w', encoding = "shift_jis") as f: 8 f.write('test') 9 f.close() 10app.MainLoop()

非常に長くなってしまし、申し訳ないです。現役の方も含め、お力添えしていただけると幸いです。

##補足
・一時ファイル
イメージ説明
・完成
イメージ説明

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

質問者さんが造りたいものを実現するまでもう少しだと思いましたので、回答としてはボタンを押したときのイベントハンドラーの使い方を簡単に説明させていただくことにとどめます。

test_button.Bind(wx.EVT_BUTTON, save_text(tmp))で惜しいのですが、この場合、save_text関数に渡される引数の内容はあらかじめ決まっていて、その引数の内容は実際にクリックされた時に決まります。wxPython - Events and Event Handling

ではどうしたらいいのかと言うと、ボタンであるtest_buttonボタンがクリックされたときに呼び出されるようsave_text関数をBind(結び付け)した訳ですから、savet_text関数の中で改めてtext_mainを操作し、入力されたテキストを取得するようにしなければなりません。具体的なコードは以下のようになります。質問者さんのコードを流用し、必要なところを抜粋(一部修正)したものを全部掲載しますので見てみてください。

Python3

1import wx 2 3# パネル5のテキストボックスをグローバルで 4text_main = None 5 6#プロンプトで表示するように作った関数です 7#def save_text(tmp): 8# print(tmp) 9 10# イベントハンドラーを定義 11# ※このイベントハンドラーに渡される引数はあらかじめ決まっている 12def save_text(event): 13 content = '' 14 #入力したテキストを取得 15 if text_main is not None: 16 # (安全の為)作成済みであればTextControlの値を取得 17 content = text_main.GetValue() 18 19 print('save_textが呼ばれた!!') 20 print(content) 21 # ここで好きにファイルへ保存すればよい 22 23 24application = wx.App() 25frame = wx.Frame(None, wx.ID_ANY, 'プログラミング言語文法確認ツール') 26 27panel_5 = wx.Panel(frame, wx.ID_ANY) 28 29text_main = wx.TextCtrl(panel_5, wx.ID_ANY, style = wx.TE_MULTILINE) 30 31#保存ボタンを生成 32test_button = wx.Button(panel_5, wx.ID_ANY, '保存') 33 34#入力したテキストを取得したかった。 35#ここではダメ tmp = text_main.GetValue() 36#これではダメ test_button.Bind(wx.EVT_BUTTON, save_text(tmp)) 37test_button.Bind(wx.EVT_BUTTON, save_text) 38 39layout_textbox = wx.BoxSizer(wx.VERTICAL) 40layout_textbox.Add(text_main, 1, wx.GROW) 41layout_textbox.Add(test_button, 0, wx.GROW) 42panel_5.SetSizer(layout_textbox) 43 44frame.Show() 45 46application.MainLoop() 47

実際に動作させた例です。linuxであるUbuntu 16.04 上(python3.5.2 + wxPython 4.0.0.b1)ですが、windows環境でも同じなはずです。

Ubuntu16.04上での動作例

ファイルに保存する方法はほぼ目処がついておられるようですのでここでは述べないことにします。もう少しだと思うので、ぜひ頑張ってください。

投稿2018/12/29 08:52

編集2018/12/29 08:56
dodox86

総合スコア9183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Python.R

2018/12/29 15:14

無事完成しました。ヒントをくださり、ありがとうございます。 完成したコードは下記の通りです。 すみません、文字数オーバーなので、一部削除。 大幅に処理形態を改良しました。 ```Python ・・・・上記コード省略・・・・ # テキストをリアルタイムで取得し、一時ファイルへ格納 def save_text(event): obj = event.GetEventObject() obj = obj.GetValue() frame.SetStatusText('文字カウント:'+ str(len(obj)) +" 字 | Made by RYUKI.Y") with open('.\tmp\tmp.txt', 'w') as f: f.write(obj) f.close() # 一時ファイルからテキストファイル新規作成した後、一時ファイル初期化 def save_text_file(event): add_text = [] with open('.\tmp\tmp.txt', 'r') as f: for read_text in f: add_text.append(read_text) f.close() app = wx.App() frame_b = wx.Frame(None, wx.ID_ANY, 'ファイル参照', size=(700, 450)) panel_b = wx.Panel(frame_b, wx.ID_ANY) panel_b_a = wx.Panel(frame_b, wx.ID_ANY) panel_b_b = wx.Panel(frame_b, wx.ID_ANY) folder = wx.DirDialog(panel_b,style = wx.DD_CHANGE_DIR,message="保存先のディレクトリー(パス)") if folder.ShowModal() == wx.ID_OK: dirs = folder.GetPath() folder.Destroy() dlg = wx.TextEntryDialog(panel_b_a, 'ファイル名を拡張子含めて入力してください。','ファイル名の入力') dlg.SetValue("ファイル名を入力") if dlg.ShowModal() == wx.ID_OK: filename = dlg.GetValue() with open(dirs + "\" + filename, 'w') as f: for line in add_text: f.write(line) f.close() dlg = wx.MessageDialog(panel_b_b, "ファイルを作成しました。", "確認のメッセージ") dlg.ShowModal() dlg.Destroy() with open('.\tmp\tmp.txt', 'w') as f: f.close() app.MainLoop() def run_music(): pygame.mixer.init() pygame.mixer.music.load('md\mens-ou1.mp3') #音源を読み込み #再生開始。1の部分を変えるとn回再生(その場合は次の行の秒数も×nすること) pygame.mixer.music.play(1) ・・・中略・・・ # パネル5のテキストボックス text_main = wx.TextCtrl(panel_5, wx.ID_ANY, "ここに入力", style = wx.TE_MULTILINE) text_main.SetBackgroundColour('#0D0D0D') text_main.SetForegroundColour('#FFFFFF') ・・・・中略・・・・・ # パネル5のテキストエリアにおける内容の保存 text_button = wx.Button(panel_5, 3000, 'ファイルに保存', size = (0, 40)) ・・・中略・・・・ ################################$ # ボタンクリック時の動作を指定 ################################# for i in range(len(python_button)): frame.Bind(wx.EVT_BUTTON, Prog_lgs.python_button_func, python_button[i]) for i in range(len(c_button)): frame.Bind(wx.EVT_BUTTON, Prog_lgs.c_button_func, c_button[i]) for i in range(len(java_button)): frame.Bind(wx.EVT_BUTTON, Prog_lgs.java_button_func, java_button[i]) text_button.Bind(wx.EVT_BUTTON, save_text_file) ###################################### # テキストエリアでの入力時の動作 ###################################### text_main.Bind(wx.EVT_TEXT, save_text) ・・・以下省略・・・・ ``` テキストを入力するとまず、一時ファイル「tmp」にリアルタイムで格納され、 ![一時ファイル](baf3f134a711bd2a4d66b370af109fd9.png) ツールの「ファイルを保存」ボタンを押すと、ファルダー参照画面とファイル名入力ダイアログを立ち上げるようにしました。ファイルの保存は成功です。 ![完成](f9650c86ba1ab4a591e4277625f9448d.png) 今回リアルタイム処理をしたのは、文字数をステータスバーに表示したかったからです。 少し回りくどいことをしているように見えると思いますが、許してください。
Python.R

2018/12/29 15:18

すみません、画像は本文に補足しました。
dodox86

2018/12/29 15:33

その後の修正内容も示してくださり、ありがとうございます。 自分の思い通りに作れると楽しいですよね。完成おめでとうございます。
Python.R

2018/12/29 23:22

そうですね!ありがとうございます。 どんどんしたいことが増えていきそうです(! 徐々にwxPythonについても理解してきたので、これからどんどん使い込んで行きたいです。 それと、pyinstallerを使い、これから実行形式に変換しようと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問