Subprocess&tkinterを使ってコマンドプロンプトもどきプログラム
今後もPythonを扱うこともありそうなので、シリーズ化(その3)することにした。今回は、Subprocessおよびtkinter(GUIフレームワーク)を使って、コマンドプロンプトもどきプログラムをつくる。
Subprocess
Subprocessでは、Windowsコマンドプロンプトのコマンドを実行できる。次のサイトを主に参照した。
作成したもの
ソースコード
# -*- coding: utf-8 -*-
import subprocess
import tkinter as tk
def showResult():
cmd = cmdbox.get()
output = subprocess.run(cmd.split(), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout
output = output.decode('shift_jis')
output = output.replace('\r', '')
result.insert(tk.END, '<<< command >>> ' + cmd + '\n\n')
result.insert(tk.END, output + '\n\n')
result.see("end")
cmdbox.delete(0, tk.END)
def func(event):
showResult()
def func2():
showResult()
root = tk.Tk()
root.geometry('600x600')
root.title('Like command prompt')
frm1 = tk.Frame()
frm1.place(x = 40, y = 10)
frm2 = tk.Frame()
frm2.place(x = 40, y = 50)
cmdbox = tk.Entry(frm1, width = 70)
cmdbox.pack(side=tk.LEFT)
cmdbox.bind('<Return>', func)
btn = tk.Button(frm1, text='OK', command=func2)
btn.pack(side=tk.LEFT)
result = tk.Text(frm2, font=("", 10), width=70, height=40)
ysc = tk.Scrollbar(frm2, orient=tk.VERTICAL, command=result.yview)
ysc.pack(side=tk.RIGHT, fill="y")
result["yscrollcommand"] = ysc.set
result.pack()
root.mainloop()
以下、ポイントを解説。
frm1 = tk.Frame()
frm1.place(x = 40, y = 10)
frm2 = tk.Frame()
frm2.place(x = 40, y = 50)
コマンド入力用フレームと結果用フレームの作成。
cmdbox = tk.Entry(frm1, width = 70)
cmdbox.pack(side=tk.LEFT)
cmdbox.bind('<Return>', func)
btn = tk.Button(frm1, text='OK', command=func2)
btn.pack(side=tk.LEFT)
コマンド入力用Entry widget、エンター(リターン)キーが押されたときの関数(func)、OKボタンおよびボタンが押されたときの関数(func2)の定義(ボタンは必須ではない、おまけ)。キーが押されたときの処理については下記のサイト参照した。
result = tk.Text(frm2, font=("", 10), width=70, height=40)
ysc = tk.Scrollbar(frm2, orient=tk.VERTICAL, command=result.yview)
ysc.pack(side=tk.RIGHT, fill="y")
result["yscrollcommand"] = ysc.set
result.pack()
結果用Text Widget、スクロールバーの作成。後者については、下記サイトを参照した。
def func(event):
showResult()
def func2():
showResult()
キーが押されたときに呼び出される関数およびOKボタンが押されたときに呼び出される関数。前者は「event」という引数が必要なようだ。
def showResult():
cmd = cmdbox.get()
output = subprocess.run(cmd.split(), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout
output = output.decode('shift_jis')
output = output.replace('\r', '')
result.insert(tk.END, '<<< command >>> ' + cmd + '\n\n')
result.insert(tk.END, output + '\n\n')
result.see("end")
cmdbox.delete(0, tk.END)
Entryに入力された文字列を取得し(get())、リスト化(split())してSubprocessにわたす。結果をシフトJIS化(decode())、CR('\r')削除(replace()、環境によっては不要かも)、結果をTextに挿入(insert())する。Textの現在位置を最後に移動し(see("end"))、Entry内容を削除する(delete())。
終わりに
Text Widgetのみで実現(よりコマンドプロンプトに近い)できるか検討中、、。まがりなりにもなんとかなれば、記事にします。