Python:Tkを使って気軽にコンソールアプリ?

Windowsの小物はほぼPythonで作っているわけですが。

WindowsにPythonをインストーラーを使ってインストールすると*.pyにデフォルトだとpython.exeを関連付けしてくれます。 これは非プログラマな人にプログラムを渡すとき非常に便利で、とりあえずPythonをインストールして、このファイルをダブルクリックしろ、というだけでオッケー。exe化して無駄な容量を食わなくても大丈夫なのです。

んで、作るのはだいたいコンソールで実行するもの。 これがダブルクリックで実行できるのはいいんですが、当然、プログラムが終了するとウインドウ(DOSプロンプト)が閉じちゃうから結果が見れない。 いちいちDOSプロンプトから実行するのもめんどくさい。しかも見た目的に非プログラマにはいかつい。

なんとかならないかなー、と思ってTkを使ってコンソールアプリを作るためのライブラリを作ってみた。

 1# vim: fileencoding=utf-8
 2from Tkinter import *
 3from ScrolledText import ScrolledText
 4import sys
 5import thread
 6import time
 7
 8class GUIConsole(Frame):
 9  def init(self):
10    self.init_input()
11    self.init_output()
12
13  def init_input(self):
14    self.input_var = StringVar()
15    self.input = Entry(self, width=100, textvariable=self.input_var)
16    self.input.pack(side=TOP)
17    self.input.bind('<Return>', self.input_enter)
18
19    self.input_var.readline = self.readline
20    sys.stdin = self.input_var
21
22  def init_output(self):
23    self.out = ScrolledText(self, width=100, height=30)
24    self.out.pack(side=TOP)
25    self.out.write = self.write
26    sys.stdout = self.out
27
28  def write(self, str):
29    self.out.insert(END, str)
30    time.sleep(0.0001)
31    self.out.yview_scroll(str.count("\n") + 1, "units")
32
33  def readline(self, size=None):
34    self.input.focus()
35    self.input_entered = False
36    while True:
37      time.sleep(0.5)
38      if self.input_entered == True:
39        break
40    result = self.input_var.get()
41    self.input_var.set("")
42    return result
43
44  def input_enter(self, event):
45    self.input_entered = True
46
47  def __init__(self, title, master=None):
48    self.input_entered = False
49    Frame.__init__(self, master)
50    self.pack()
51    self.master.title(title)
52    self.init()
53
54def start(main_func, title="Python") : 
55  app = GUIConsole(title)
56  thread.start_new_thread(main_func, ())
57  app.mainloop()

使い方はこんなかんじ。

1import guiconsole
2
3def main():
4  while True:
5    var = raw_input()
6    print var
7
8guiconsole.start(main, "GUIコンソールのテスト")

でこんな風にみえる。

image

一番上に入力欄があって、その下に結果表示エリア。

Pythonの場合、stdoutはwriteというメソッド、stdinはreadlineというメソッドさえもっていればどんなオブジェクトでもオッケー。 なので単純にstdoutとstdinをTkのウィジットに置き換えてメインループに入り、別スレッドでメインの処理を実行してやっているだけ。

見栄えも生のDOSプロンプトよりはいいし、処理が終わってもウィンドウを閉じない限り結果を見ることができる。 プチ便利なので、はやくも自分で使いまくりです(笑

comments powered by Disqus