python界面执行shell_Python tkinter GUI 中调用 shell 脚本

#!/usr/bin/env python3

# -*- coding:utf-8 -*-

import tkinter

from tkinter import messagebox, scrolledtext

import subprocess

import select

import os

import signal

WINDOW_SIZE = "600x400"

# Run Button

btn_upd = None

# Output textbox

txt_out = None

# current script job/process

cur_process = None

# mark if Tk is closing

close_flag = False

# Tk root

root = tkinter.Tk()

def disable_allbtn():

global close_flag

global btn_upd

if close_flag:

return

btn_upd.configure(state=tkinter.DISABLED)

def enable_allbtn():

global close_flag

global btn_upd

if close_flag:

return

btn_upd.configure(state=tkinter.NORMAL)

def cb_runbash_withoutput(script):

global cur_process

global txt_out

global root

global close_flag

# clear output

txt_out.delete(1.0, tkinter.END)

# create subprocess

process = subprocess.Popen(script, shell=True, preexec_fn=os.setsid,

stderr=subprocess.PIPE, stdout=subprocess.PIPE)

# read subprocess stderr/stdout in non-blocking

outpoll = select.poll()

errpoll = select.poll()

outpoll.register(process.stdout, select.POLLIN)

errpoll.register(process.stderr, select.POLLIN)

# store current subprocess

cur_process = process

while True:

output = ""

errput = ""

# poll stdout, timeout 2ms

if outpoll.poll(2):

output = process.stdout.readline().decode()

# insert stdout to txt_out

if output and not close_flag:

txt_out.insert(tkinter.INSERT, output)

# poll stderr, timeout 2ms

if errpoll.poll(2):

errput = process.stderr.readline().decode()

# insert stderr to txt_out

if errput and not close_flag:

txt_out.insert(tkinter.INSERT, errput)

# scroll text if have output

if (output or errput) and not close_flag:

txt_out.see(tkinter.END)

# do eventloop when not closing

if not close_flag:

root.update()

# process end

if output == "" and process.poll() is not None:

break

# get process return code

code = process.poll()

# reset current subprocess

cur_process = None

return code

# callback 函数

def cb_update():

global close_flag

disable_allbtn()

code = cb_runbash_withoutput("./bash_script_sample.sh")

# exit when closing

if close_flag:

return

if code != 0:

messagebox.showerror(title="Error", message="run bash script failed")

else:

messagebox.showinfo(title="Info", message="run bash script success")

enable_allbtn()

def on_closing():

global cur_process

global root

global close_flag

# if cur_process still running

if cur_process:

if messagebox.askokcancel("Quit", "There is task running, do you want to quit?"):

# kill subprocess

os.killpg(os.getpgid(cur_process.pid), signal.SIGTERM)

cur_process = None

else:

return

# mark closing

close_flag = True

# close window

root.destroy()

root.title("Hello world")

root.geometry(WINDOW_SIZE)

# register cloing event callback

root.protocol("WM_DELETE_WINDOW", on_closing)

btn_upd = tkinter.Button(root, text="Update", command = cb_update)

btn_upd.pack(fill=tkinter.X, pady=10)

txt_out = scrolledtext.ScrolledText(root)

txt_out.pack(fill=tkinter.BOTH, expand=True, padx=20, pady=20)

tkinter.mainloop()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值