使用Tkinter模块中的GUI“按钮”管理脚本执行

时间:2014-08-21 18:48:54

标签: python tkinter

有以下脚本:

import sys, Tkinter

def myScript():
    ...

    ...


def runScript():
    while 1:
        myScript()

我想使用GUI"按钮"来管理它。来自Tkinter模块

if __name__ == '__main__':
    win = Frame ()
    win.pack ()
    Label(win, text='Choose following action', font=("Helvetica", 16), width=70, height=20).pack(side=TOP)
    Button(win, text='Start script', width=20, height=3, command=runScript).pack(side=LEFT)
    Button(win, text='Stop script', width=20, height=3, command=sys.exit).pack(side=LEFT)
    Button(win, text='Quit', width=15, height=2, command=win.quit).pack(side=RIGHT)
    mainloop()

当我输入"启动脚本"按钮我的脚本成功启动和工作(无限循环),但后来我想停止执行使用"停止脚本"按钮我不能这样做,因为带按钮的主窗口不可用("没有响应")

为了正确使用这两个按钮,我必须更改什么?

2 个答案:

答案 0 :(得分:2)

问题是脚本的执行被认为是被阻止的,所以当它连续运行时,控件永远不会返回到GUI,以便能够继续使用任何外部命令来停止它。要调整此项,您需要使用线程。执行此操作的最佳方法是使用threading.Thread将脚本方法子类化,并使用脚本执行重载.run()方法。这样做会是这样的:

import threading

class MyScript(threading.Thread):
    def __init__(self):
        super(MyScript, self).__init__()
        self.__stop = threading.Event()

    def stop(self):
        self.__stop.set()

    def stopped(self):
        return self.__stop.isSet()

    def run(self):
        while not self.stopped():
            # Put your script execution here
            print "running"

从那里你可以设置一个全局变量或类变量来跟踪你当前是否正在运行一个线程(如果你想让用户运行脚本的多个实例,你可能希望以不同的方式执行此操作)和方法来启动并阻止它。我推荐一个类变量,您的应用程序本身就是一个类,但这取决于您。

script_thread = None

def startScript():
    global script_thread
    # If we don't already have a running thread, start a new one
    if not script_thread:
        script_thread = MyScript()
        script_thread.start()

def stopScript():
    global script_thread
    # If we have one running, stop it
    if script_thread:
        script_thread.stop()
        script_thread = None

从那里你可以将这些方法绑定到你的按钮。我不确定你的应用程序结构是如何设置的(在我看来你从Tkinter导入了所有内容或者对Tkinter.Tk()实例进行了细分。但是,为了做你提出的建议,你需要使用线程来防止阻塞情况。

答案 1 :(得分:-2)

使用此:

import sys
from Tkinter import *
import tkMessageBox as tkmsg

win = None

def myScript():
    pass

def runScript():
    global win
    while 1:
        win.update()
        pass

def btnStop_Click():
    tkmsg.showinfo("Stopped", "Stopped")
    sys.exit

if __name__ == '__main__':
    global win
    win = Frame ()
    win.pack ()
    Label(win, text='Choose following action', font=("Helvetica", 16), width=70, height=20).pack(side=TOP)
    Button(win, text='Start script', width=20, height=3, command=runScript).pack(side=LEFT)
    Button(win, text='Stop script', width=20, height=3, command=btnStop_Click).pack(side=LEFT)
    Button(win, text='Quit', width=15, height=2, command=win.quit).pack(side=RIGHT)
    mainloop()