通过GUI按钮“未定义”杀死子进程

时间:2019-11-17 00:12:28

标签: python tkinter subprocess

from tkinter import *
from tkinter import messagebox
from tkinter import ttk
from tkinter import filedialog

import os
import shutil
import subprocess
import _thread



gui = Tk()

gui.geometry("+350+350")
gui.resizable(0,0)

gui.title(" * ---  Comm Test  --- * ")

class CreateButton(Frame):
    def __init__(self,parent=None,buttonName="", buttonName2 = "" ,**kw):
        Frame.__init__(self,master=parent,**kw)
        self.folderPath = StringVar()
        self.btnFind2 = ttk.Button(self,text = buttonName,command=do_sth)
        self.btnFind2.grid(row=4,column=1,padx=20 , pady = 10)
        self.btnQuit = ttk.Button(self,text = buttonName2,command=kill_comm)
        self.btnQuit.grid(row=4,column=2,padx=20 , pady = 10)

def do_sth():
    _thread.start_new_thread(comm_func, ())

def comm_func():
    cmd_specs = ["C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe", '-ExecutionPolicy', 'Unrestricted', "C:\\PS\\TST.PS1"]
    proc_tst = subprocess.Popen(cmd_specs , stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines = True)

def kill_comm():
    proc_tst.kill()

btn1 = CreateButton(gui," START " , " KILL ")
btn1.grid(row=4)
gui.mainloop()
gui.destroy()

我正在使用_thread,因为我的GUI被冻结了。 但是问题是,在我调用子进程(并且该部分起作用)之后,当我尝试按下“杀”按钮时,它返回:

  

NameError:名称'proc_tst'未定义

我已经为此苦苦挣扎了一段时间,但是没有设法解决这个问题。

非常感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

这是变量作用域的问题。在Python中和大多数编程语言中,在特定函数中定义的变量不适用于其他函数或主函数。这是“本地”范围。

您在函数proc_tst中定义了comm_func,因此,当您在kill_comm()中引用此变量时,将没有变量“被找到”。

您显然可以使用全局变量,但这可能不是您想要的。 您可以改为在类CreateButton内定义函数,但是我将在开头说这种设计很奇怪,因为类通常表示“对象”或“结构”。尽管如此,以下代码仍然有效:

from tkinter import *
from tkinter import messagebox
from tkinter import ttk
from tkinter import filedialog

import os
import shutil
import subprocess
import _thread



gui = Tk()

gui.geometry("+350+350")
gui.resizable(0,0)

gui.title(" * ---  Comm Test  --- * ")

class CreateButton(Frame):
    def __init__(self,parent=None,buttonName="", buttonName2 = "" ,**kw):
        Frame.__init__(self,master=parent,**kw)
        self.folderPath = StringVar()
        self.btnFind2 = ttk.Button(self,text = buttonName,command=self.do_sth)
        self.btnFind2.grid(row=4,column=1,padx=20 , pady = 10)
        self.btnQuit = ttk.Button(self,text = buttonName2,command=self.kill_comm)
        self.btnQuit.grid(row=4,column=2,padx=20 , pady = 10)
    def comm_func(self):
        cmd_specs = ["C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe", '-ExecutionPolicy', 'Unrestricted', "C:\\PS\\TST.PS1"]
        self.proc_tst = subprocess.Popen(cmd_specs , stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines = True)
    def kill_comm(self):
        self.proc_tst.kill()
    def do_sth(self):
        _thread.start_new_thread(self.comm_func, ())


btn1 = CreateButton(gui," START " , " KILL ")
btn1.grid(row=4)
gui.mainloop()
gui.destroy()