【问题标题】:Button not working till current loop ends in python直到当前循环在python中结束,按钮才起作用
【发布时间】:2016-04-23 13:02:36
【问题描述】:

在 python 2.7 中,如果我在循环运行时单击按钮 IDLE 将停止工作,直到 python 退出循环。我附上了我的整个代码,因为我不知道为什么会发生这种情况。

import time
import  Tkinter as tk
from Tkinter import StringVar
import threading

x="False"

def xval(*args):
    for i in range(0,9):
        global x
        if(x=="False"):
            print "x=false %d time"%i
            time.sleep(1)

def stop(event):
                resume_btn.configure(state="normal")
                global x
                x ="True"
                print "execution stopped:%s"%x

def start(event):
                global x
                x ="False"
                print "execution started:%s"%x
                xval()

root = tk.Tk()

th = threading.Event()
t = threading.Thread(target=xval,args=(th,))
t.deamon=True
t.start()

x_btn = tk.Button(root, text="Stop", background="Snow", width=20)
x_btn.grid(row=0, column=4, sticky="W", padx=20, pady=5)
x_btn.bind('<Button-1>',stop)

resume_btn = tk.Button(root, text="Start", background="Snow", width=20)
resume_btn.configure(state="disabled")
resume_btn.grid(row=0, column=6, sticky="W", padx=20, pady=5)
resume_btn.bind('<Button-1>',start)

root.mainloop()

这两个按钮在第一次运行时都可以正常工作,但第二次在我单击停止时 x 的值都不会更新,也不会在 python 退出循环之前按钮正常工作。谁能说出为什么会这样。

【问题讨论】:

    标签: python-2.7 loops button tkinter


    【解决方案1】:

    是的,程序在执行任何其他操作之前执行 for()。要绕过它,您将不得不使用一些可以由线程和主程序实时共享的容器来停止中途的 for() (在多处理中它是一个管理器字典或列表,不知道它是什么在线程中),或者使用 Tkinter 的 after 方法执行类似于下面的代码的操作,该代码使用可以在整个类中看到和使用的类实例对象/属性(此代码中的变量)。 http://www.tutorialspoint.com/python/python_classes_objects.htm

    import  Tkinter as tk
    
    class StartStop():
        def __init__(self, root):
            self.x="False"
            self.ctr=0
    
            x_btn = tk.Button(root, text="Stop", background="Snow", width=20)
            x_btn.grid(row=0, column=4, sticky="W", padx=20, pady=5)
            x_btn.bind('<Button-1>', self.stop)
    
            self.resume_btn = tk.Button(root, text="Start", background="Snow", width=20)
            self.resume_btn.configure(state="disabled")
            self.resume_btn.grid(row=0, column=6, sticky="W", padx=20, pady=5)
            self.resume_btn.bind('<Button-1>', self.start)
    
    
        def xval(self):
            if self.x=="False":
                print "x=false %d=counter value"%self.ctr
                self.ctr += 1
                if self.ctr < 9:
                    ## after gives the program time to update
                    ## time.sleep() stops everyting
                    root.after(1000, self.xval)
    
        def stop(self, event):
                self.resume_btn.configure(state="normal")
                self.x ="True"
                print "execution stopped:%s"%self.x
    
        def start(self, event):
                self.x ="False"
                print "execution started:%s"%self.x
                self.ctr=0
                self.xval()
    
    root = tk.Tk()
    S=StartStop(root)
    root.mainloop()
    

    【讨论】:

    • :/不使用类可以吗?
    • :我知道而且我肯定会@BillalBEGUERADJ,但我没有在需要此代码的项目中使用它们^_^'这就是为什么我问它是否可以在没有课程的情况下完成
    • 我得到了答案 :) 没有课程......但@joe 所做的是正确的做法......无论如何我都会附上答案......
    【解决方案2】:

    只需要在循环结束时使用 variable.get() 和 set() 以及 root.update()。

    import time
    import  Tkinter as tk
    from Tkinter import StringVar
    import threading
    global root
    root = tk.Tk()
    x = tk.StringVar()
    x.set('false')
    
    def xval(*args):
        try:
            for i in range(0,9):
                global x
                print x.get()
                if x.get()== 'false' :
                    print "x=false %d time"%i
                    time.sleep(1)
                else:
                    print "waiting"
                root.update()
        except:
            pass
    
    def stop(event):
                    resume_btn.configure(state="normal")
                    global x
                    x.set('true')
                    print "execution stopped:%s"%x
    
    
    def start(event):
                    global x
                    x.set('false')
                    print "execution started:%s"%x
                    xval()
    
    
    root.title("GUI-Data Retrieval")
    th = threading.Event()
    t = threading.Thread(target=xval,args=(th,))
    t.deamon=True
    t.start()
    x_btn = tk.Button(root, text="Stop", background="Snow", width=20)
    x_btn.grid(row=0, column=4, sticky="W", padx=20, pady=5)
    x_btn.bind('<Button-1>',stop)
    resume_btn = tk.Button(root, text="Start", background="Snow", width=20)
    resume_btn.configure(state="disabled")
    resume_btn.grid(row=0, column=6, sticky="W", padx=20, pady=5)
    resume_btn.bind('<Button-1>',start)
    root.mainloop()
    

    但我会说类是一个更好的方式来做到这一点:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-12-03
      • 2015-04-09
      • 1970-01-01
      • 1970-01-01
      • 2021-01-12
      • 1970-01-01
      • 2017-09-30
      • 1970-01-01
      相关资源
      最近更新 更多