2016-04-23 68 views
1

在Python 2.7中,如果我點擊一個按鈕,當一個循環運行IDLE停止工作,直到python走出循環。我附上我的整個代碼,因爲我不知道爲什麼會發生這種情況。按鈕不工作,直到當前循環結束於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的值精被更新時,我就停止,也沒有按鈕點擊作品直到蟒蛇出來的循環。有人可以告訴爲什麼會發生這種情況。

回答

1

是的,程序在執行任何其他操作之前執行for()。爲了避免這種情況,你將不得不使用一些線程和主程序可以實時共享的容器,以便在中途停止for()(在Multiprocessing中它是一個管理器字典或列表,不知道它是什麼是在Threading中),或者使用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() 
+0

:/是否有可能不使用類? – YSR

+0

班是禮貌。你必須學習禮貌@ YSR –

+0

:D我知道,我當然會@BillalBEGUERADJ但我沒有在我的項目中使用它們,這裏需要這些代碼^ _ ^'這就是爲什麼我問是否可以在沒有類的情況下完成 – YSR

1

僅需要使用variable.get()和()設置與在所述循環結束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() 

,但是我要說類是一個更好的方式來做到這一點:)