Windowsの小物はほぼPythonで作っているわけですが。
WindowsにPythonをインストーラーを使ってインストールすると*.pyにデフォルトだとpython.exeを関連付けしてくれます。
これは非プログラマな人にプログラムを渡すとき非常に便利で、とりあえずPythonをインストールして、このファイルをダブルクリックしろ、というだけでオッケー。exe化して無駄な容量を食わなくても大丈夫なのです。
んで、作るのはだいたいコンソールで実行するもの。
これがダブルクリックで実行できるのはいいんですが、当然、プログラムが終了するとウインドウ(DOSプロンプト)が閉じちゃうから結果が見れない。
いちいちDOSプロンプトから実行するのもめんどくさい。しかも見た目的に非プログラマにはいかつい。
なんとかならないかなー、と思ってTkを使ってコンソールアプリを作るためのライブラリを作ってみた。
guiconsole.py
# vim: fileencoding=utf-8from Tkinter import *from ScrolledText import ScrolledTextimport sysimport threadimport timeclass GUIConsole(Frame):def init(self):self.init_input()self.init_output()def init_input(self):self.input_var = StringVar()self.input = Entry(self, width=100, textvariable=self.input_var)self.input.pack(side=TOP)self.input.bind('<Return>', self.input_enter)self.input_var.readline = self.readlinesys.stdin = self.input_vardef init_output(self):self.out = ScrolledText(self, width=100, height=30)self.out.pack(side=TOP)self.out.write = self.writesys.stdout = self.outdef write(self, str):self.out.insert(END, str)time.sleep(0.0001)self.out.yview_scroll(str.count("\n") + 1, "units")def readline(self, size=None):self.input.focus()self.input_entered = Falsewhile True:time.sleep(0.5)if self.input_entered == True:breakresult = self.input_var.get()self.input_var.set("")return resultdef input_enter(self, event):self.input_entered = Truedef __init__(self, title, master=None):self.input_entered = FalseFrame.__init__(self, master)self.pack()self.master.title(title)self.init()def start(main_func, title="Python") :app = GUIConsole(title)thread.start_new_thread(main_func, ())app.mainloop()
使い方はこんなかんじ。
import guiconsoledef main():while True:var = raw_input()print varguiconsole.start(main, "GUIコンソールのテスト")
でこんな風にみえる。
Pythonの場合、stdoutはwriteというメソッド、stdinはreadlineというメソッドさえもっていればどんなオブジェクトでもオッケー。
なので単純にstdoutとstdinをTkのウィジットに置き換えてメインループに入り、別スレッドでメインの処理を実行してやっているだけ。
見栄えも生のDOSプロンプトよりはいいし、処理が終わってもウィンドウを閉じない限り結果を見ることができる。
プチ便利なので、はやくも自分で使いまくりです(笑