Python 如何在不完全退出Tkinter窗口的情况下停止正在运行的功能?

Python 如何在不完全退出Tkinter窗口的情况下停止正在运行的功能?,python,python-2.7,tkinter,Python,Python 2.7,Tkinter,我正在使用Python2.7,我正在尝试编写GUI,但我的按钮有一些问题。目前,我所有的功能都正常运行,但假设我的输入有错误,我想在按下“GO”按钮后停止运行功能。我的代码太长,无法在这里发布,但下面是一个简单的示例。如何使“停止”按钮中断启动功能,但不完全退出窗口?也许和线程有关 我对编写GUI有点陌生,而且我不是真正的程序员,所以这不是我的专业领域 当主功能运行时,GUI完全没有响应。必须有一种方法可以同时运行我的函数,同时允许我在GUI中更改内容并点击按钮,但我不确定这是如何工作的。不过,

我正在使用Python2.7,我正在尝试编写GUI,但我的按钮有一些问题。目前,我所有的功能都正常运行,但假设我的输入有错误,我想在按下“GO”按钮后停止运行功能。我的代码太长,无法在这里发布,但下面是一个简单的示例。如何使“停止”按钮中断启动功能,但不完全退出窗口?也许和线程有关

我对编写GUI有点陌生,而且我不是真正的程序员,所以这不是我的专业领域

当主功能运行时,GUI完全没有响应。必须有一种方法可以同时运行我的函数,同时允许我在GUI中更改内容并点击按钮,但我不确定这是如何工作的。不过,在下次按下“开始”按钮之前,不必执行更新

import time
from Tkinter import *


class Example:
    def __init__(self,master):
        self.startButton = Button(master,text='Start',command=self.start)
        self.startButton.grid(row=0,column=0)

        self.stopButton = Button(master,text='Stop',command=self.stop)
        self.stopButton.grid(row=0,column=1)

        self.textBox = Text(master,bd=2)
        self.textBox.grid(row=1,columnspan=2)

    def start(self):
        self.textBox.delete(0.0,END)
        for i in xrange(1000):
            text = i+1
            self.textBox.insert(END,str(text)+'\n\n')
            time.sleep(1)
        return

    def stop(self):
        """ Do something here to stop the running "start" function """
        pass


root=Tk()
Example(root)
root.mainloop()

您可以尝试使用类型为
bool

init
方法上方,可以定义如下属性:
boolstopflag=False

然后在
for
循环中,添加
if(!self.stopfag):break
。这将在每次迭代中检查
停止标志
,并将其取反。因此,它将默认首先通过if检查

然后在
stop
方法中,只需设置
self.stopFlag=True


因此,当调用
stop
时,它将翻转标志,如果
start
方法在它的
for
循环中运行,它将捕获标志中的此更改并中断。

使用
Tkinter
,通常使用通用小部件方法来完成这些事情。通常不应在Tkinter程序中使用
time.sleep()
,因为它会阻止
mainloop()
运行(这正是导致GUI在代码中无响应的原因)

成功的
after()
调用将返回一个整数“cancel id”,可用于停止刚刚计划的回调。这是您的
示例
类的
Stop()
方法停止该方法进行计数所需要的

from Tkinter import *

class Example:
    def __init__(self, master):
        self.startButton = Button(master,text='Start', command=self.start)
        self.startButton.grid(row=0, column=0)

        self.stopButton = Button(master, text='Stop', command=self.stop)
        self.stopButton.grid(row=0, column=1)

        self.textBox = Text(master, bd=2)
        self.textBox.grid(row=1, columnspan=2)

    def start(self):
        self.count = 0
        self.cancel_id = None
        self.counter()

    def counter(self):
        self.textBox.delete("1.0", END)
        if self.count < 10:
            self.count += 1
            self.textBox.insert(END, str(self.count)+'\n\n')
            self.cancel_id = self.textBox.after(1000, self.counter)

    def stop(self):
        if self.cancel_id is not None:
            self.textBox.after_cancel(self.cancel_id)
            self.cancel_id = None

root=Tk()
Example(root)
root.mainloop()
从Tkinter导入*
课堂示例:
定义初始(自我,主):
self.startButton=按钮(主控,text='Start',command=self.Start)
self.startButton.grid(行=0,列=0)
self.stopButton=按钮(master,text='Stop',command=self.Stop)
self.stopButton.grid(行=0,列=1)
self.textBox=Text(主控,bd=2)
self.textBox.grid(行=1,列span=2)
def启动(自):
self.count=0
self.cancel\u id=None
self.counter()
def计数器(自身):
self.textBox.delete(“1.0”,结束)
如果self.count<10:
self.count+=1
self.textBox.insert(END,str(self.count)+'\n\n')
self.cancel\u id=self.textBox.after(1000,self.counter)
def停止(自):
如果self.cancel\u id不是None:
self.textBox.after\u cancel(self.cancel\u id)
self.cancel\u id=None
root=Tk()
示例(根)
root.mainloop()

我对上面的答案做了一些改进,多次单击“开始”按钮不会损坏程序:

from tkinter import *

class Example:
    def __init__(self, master):
        self.cancel_id = None

        self.startButton = Button(master,text='Start', command=self.start)
        self.startButton.grid(row=0, column=0)

        self.stopButton = Button(master, text='Stop', command=self.stop)
        self.stopButton.grid(row=0, column=1)

        self.textBox = Text(master, bd=2)
        self.textBox.grid(row=1, columnspan=2)

    def start(self):
        if(self.cancel_id==None):
            self.count = 0
            #self.cancel_id = None
            self.counter()

    def counter(self):
        self.textBox.delete("1.0", END)
        if (self.count < 10):
            self.count += 1
            self.textBox.insert(END, str(self.count)+'\n\n')
            self.cancel_id = self.textBox.after(1000, self.counter)

    def stop(self):
        if self.cancel_id is not None:
            self.textBox.after_cancel(self.cancel_id)
            self.cancel_id = None

root=Tk()
Example(root)
root.mainloop()
从tkinter导入*
课堂示例:
定义初始(自我,主):
self.cancel\u id=None
self.startButton=按钮(主控,text='Start',command=self.Start)
self.startButton.grid(行=0,列=0)
self.stopButton=按钮(master,text='Stop',command=self.Stop)
self.stopButton.grid(行=0,列=1)
self.textBox=Text(主控,bd=2)
self.textBox.grid(行=1,列span=2)
def启动(自):
如果(self.cancel_id==None):
self.count=0
#self.cancel\u id=None
self.counter()
def计数器(自身):
self.textBox.delete(“1.0”,结束)
如果(自计数<10):
self.count+=1
self.textBox.insert(END,str(self.count)+'\n\n')
self.cancel\u id=self.textBox.after(1000,self.counter)
def停止(自):
如果self.cancel\u id不是None:
self.textBox.after\u cancel(self.cancel\u id)
self.cancel\u id=None
root=Tk()
示例(根)
root.mainloop()

我应该在原始帖子中提到这一点,但我最初尝试过类似的方法,但不幸的是,当函数运行时,“停止”按钮甚至不起作用(可单击)。显然,必须有更好的方法来实现main函数,以便GUI始终处于活动状态,但我不知道如何进行。同意w/OP。这将不起作用,因为start()方法阻塞,因此不允许调用stop()方法。