0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ろうとるがPythonを扱う、、(その8:tkinter&Subprocessでの割り込み)

Posted at

tkinterでSubprocess利用時の割り込み(中断)

PythonでのGUIフレームワークであるtkinterプログラムにて、Subprocessを利用したときに、各種割り込みを使う方法を記載。

割り込み方法

Subprocessによる実行中プロセスを中断する方法として、次のものを取り上げる。

  • 専用ボタンクリック
  • Ctrl-c
  • Windows Close(”☓”クリック)

プログラム

見た目は次のようなもの。
GUI.png
「Start subprocess」クリックにより指定されたプログラムが実行され、「Stop subprocess」(専用ボタン)クリックにより、そのプログラムが中断する。また、実行中に、「Ctrl-c」入力、右上の”☓”()クリックでもプログラムを中断させる。なお、ここでは、中断=プログラム終了とした。

ソースコード

ポイントを中心に説明。なお、実行結果はコンソールに出力(print())している。

メイン

import signal
import tkinter as tk

def check(): 
    root.after(500, check)  #  time in ms.

signal.signal(signal.SIGINT, handler) # ctrl-c from console

root = tk.Tk()
root.after(500, check)  #  time in ms.

tk.Button(root, text="Start subprocess", command=start).pack()
tk.Button(root, text="Stop subprocess", command=stop).pack()
root.bind('<Control-c>', ctrlC) 
root.protocol("WM_DELETE_WINDOW", stop)

root.mainloop()
print("exited")

各種定義およびtkinter。

  • コンソールで「Ctrl-C」をCatchしやすくするための関数(check())および呼び出し
  • コンソールで「Ctrl-C」が入力されたときに呼び出される関数(ハンドラ(handler))
  • ”Start”および”Stop”用ボタン
  • GUI(tkinter)上で「Ctrl-C」が入力されたときの関数(ctrlC)
  • Windows Close時の関数(stop)
  • 終了時にコンソールに表示されるメッセージ(exited)

check()については、下記サイト情報を利用。

Subprocess実行および中断

from subprocess import Popen, PIPE, STDOUT

cmd = ['ping', '-t', '192.168.10.1']

def stop():
    print("stop")
    killProcess()

def start():
    global proc
    print("start")
    proc = Popen(cmd, stdout=PIPE, stderr=STDOUT)
  • Subprocess(cmd):pingの無限実行(オプション:-t)を実施
  • Start関数:コンソール表示(start)およびPoepnによるSubprocess実行
  • Stop関数:コンソール表示(stop)およびSubprocess中断関数(killProcess)呼び出し

Ctrl-c

def handler(signum, root):
    print("handler")
    killProcess()

def ctrlC(event):
    print("ctrlC")
    killProcess()
  • GUI上での「Ctrl-c」:コンソール表示(ctrlC)および中断関数(killProcess)呼び出し
  • コンソール上での「Ctrl-c」:コンソール表示(ctrlC)および中断関数(killProcess)呼び出し

リアル中断関数

def killProcess():
    if 'proc' in globals():
        proc.terminate()
        proc.wait()
        output, err = proc.communicate()
        output = output.decode('shift_jis')
        print(output)
    root.destroy()
  • Subprocess実行時:プロセス中断(terminate)、実行結果の取得(communicate)、コンソールへの出力
  • tkinterプログラムの終了(root.destroy())

全体

from subprocess import Popen, PIPE, STDOUT
import signal
import tkinter as tk

cmd = ['ping', '-t', '192.168.10.1']

def killProcess():
    if 'proc' in globals():
        proc.terminate()
        proc.wait()
        output, err = proc.communicate()
        output = output.decode('shift_jis')
        print(output)
    root.destroy()

def handler(signum, root):
    print("handler")
    killProcess()

def ctrlC(event):
    print("ctrlC")
    killProcess()

def stop():
    print("stop")
    killProcess()

def start():
    global proc
    print("start")
    proc = Popen(cmd, stdout=PIPE, stderr=STDOUT)

def check(): 
    root.after(500, check)  #  time in ms.
#
signal.signal(signal.SIGINT, handler) # ctrl-c from console

root = tk.Tk()
root.after(500, check)  #  time in ms.

tk.Button(root, text="Start subprocess", command=start).pack()
tk.Button(root, text="Stop subprocess", command=stop).pack()
root.bind('<Control-c>', ctrlC) 
root.protocol("WM_DELETE_WINDOW", stop)

root.mainloop()
print("exited")

結果

いずれも期待どおりの動作。

実行中に「Stop subprocess」クリックまたはWindows Close(”☓”クリック)

start
stop

192.168.10.1 に ping を送信しています 32 バイトのデータ:
192.168.10.1 からの応答: バイト数 =32 時間 =2ms TTL=63
192.168.10.1 からの応答: バイト数 =32 時間 =2ms TTL=63

exited

なお、ここでは、リアルタイムにコマンド(ping)の出力が表示されるのではなく、中断後に出力される(プログラムの構成上)。以下、同様である。

実行中にGUI上で「Ctrl-c」入力

start
ctrlC

192.168.10.1 に ping を送信しています 32 バイトのデータ:
192.168.10.1 からの応答: バイト数 =32 時間 =2ms TTL=63
192.168.10.1 からの応答: バイト数 =32 時間 =2ms TTL=63
192.168.10.1 からの応答: バイト数 =32 時間 =2ms TTL=63
192.168.10.1 からの応答: バイト数 =32 時間 =2ms TTL=63

exited

実行中にコンソール上で「Ctrl-c」入力

start
handler

192.168.10.1 に ping を送信しています 32 バイトのデータ:
192.168.10.1 からの応答: バイト数 =32 時間 =1ms TTL=63
192.168.10.1 からの応答: バイト数 =32 時間 =2ms TTL=63
192.168.10.1 からの応答: バイト数 =32 時間 =3ms TTL=63
192.168.10.1 からの応答: バイト数 =32 時間 =2ms TTL=63
192.168.10.1 からの応答: バイト数 =32 時間 =2ms TTL=63
192.168.10.1 からの応答: バイト数 =32 時間 =1ms TTL=63
192.168.10.1 からの応答: バイト数 =32 時間 =2ms TTL=63
192.168.10.1 からの応答: バイト数 =32 時間 =1ms TTL=63

192.168.10.1 の ping 統計:
    パケット数: 送信 = 8、受信 = 8、損失 = 0 (0% の損失)、
ラウンド トリップの概算時間 (ミリ秒):
    最小 = 1ms、最大 = 3ms、平均 = 1ms
Ctrl+C

exited

実行前の中断(おまけ)

stop
exited
ctrlC
exited
handler
exited

参考にしたリンク

EOF

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?