Python:バイナリでコンソールを表示しないようにするには?

Pythonのコードをwindows用exeにするには当然、py2exeを使います。

で、そのとき、 python setup.py py2exe --windows とすれば、コンソールを表示しないようにできます。

Note:これはもう古いやり方で、現在のバージョンのpy2exeでは動きません・・・。現在はターゲットファイルの拡張子を.pywにする、もしくはwindows = [{'script' : 'script.py', "icon_resources": [(1,"script.ico")]}]というオプションをsetupに渡す、という方法になっています。

今日、昔py2exeで作ったファイルが出てきたんですが、困ったことにpythonのソースファイルはない。いや、別に改良とかもうしないしいいんだけど。
ふと起動してみるとGUI with console。かっちょわりい。

コンソールが表示される、というのは単純にPEファイルのオプションなわけで。

pe.jpg

この部分を変更してやればとりあえずは直る。ちなみに、

  • 00 00:未知のサブシステム

  • 01 00:デバイス ライバおよびWindowsNTネイティブプロセス用

  • 02 00:GUIで実行されるファイル

  • 03 00:コンソールで実行されるファイル

  • 07 00:Posixコンソールで実行されるファイル

  • 09 00:WindowsCEで実行されるファイル

なので02h 00hにしてやればオッケー。

Pythonでバイナリファイルの読み書きとかしたことないので練習もかねて。

PYTHON:
  1. # vim: fileencoding=utf-8
  2. import sys
  3. from struct import *
  4. target_file = len(sys.argv)> 1 and sys.argv[1] or sys.exit("Target file is not specified.")
  5. target_file = unicode(target_file, "mbcs")
  6. out_file    = open(target_file + "_gui", "wb")
  7.  
  8. io = open(target_file, "rb")
  9. while 1 :
  10.   if io.read(1) == "P" and io.read(1) == "E" : break
  11. subsystem_pos = io.tell() +90
  12. io.seek(0)
  13. out_file.write(io.read(subsystem_pos))
  14. io.seek(4, 1)
  15. out_file.write(pack('hh', 2, 0))
  16. out_file.write(io.read())
  17.  
  18. io.close()
  19. out_file.close()


こんな感じ。引数にexeファイルを渡せばオッケー。でも、適当なので全部のケースで動くかはあやしいw
pythonではバイナリを扱うときはstructモジュールを使う、ということが分かりました(笑

Posted at 2pm on 10/05/06 | no comments | Tags : read on

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

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

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

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

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

guiconsole.py

PYTHON:
  1. # vim: fileencoding=utf-8
  2. from Tkinter import *
  3. from ScrolledText import ScrolledText
  4. import sys
  5. import thread
  6. import time
  7.  
  8. class 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.  
  54. def start(main_func, title="Python") :
  55.   app = GUIConsole(title)
  56.   thread.start_new_thread(main_func, ())
  57.   app.mainloop()


使い方はこんなかんじ。

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


でこんな風にみえる。

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

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

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

Posted at 7pm on 10/01/06 | no comments | Tags : read on

About

about me
yuin()
文学部文化学科卒という生粋の文系趣味プログラマ。
ベンチャー企業でアルバイトを経て、某大手企業で働いてます。    
主にRuby、Javascript、PHP、JAVA,Python,C,Scala,Schemeなどを使っています。
今はPythonな感じかもしれない。今後作曲活動なども復活するかもしれない。

Pages