Python 在两个脚本之间传递变量?
我在python中的两个脚本之间传递变量时遇到问题,而不结束导入的脚本。我希望tkinter GUI中的状态栏能够更新,以反映Python 在两个脚本之间传递变量?,python,tkinter,scripting,statusbar,yield,Python,Tkinter,Scripting,Statusbar,Yield,我在python中的两个脚本之间传递变量时遇到问题,而不结束导入的脚本。我希望tkinter GUI中的状态栏能够更新,以反映script2中的计数器处于启用状态。我已将代码包括在下面: from tkinter import * import script2 root = Tk() canvas = Canvas(root, width=300, height=300) canvas.pack() def runScript(): var = script2.information
script2
中的计数器处于启用状态。我已将代码包括在下面:
from tkinter import *
import script2
root = Tk()
canvas = Canvas(root, width=300, height=300)
canvas.pack()
def runScript():
var = script2.information()
button1 = Button(root, text="Click Me!", command=runScript)
button1.pack()
var = StringVar()
var.set('Waiting for Input...')
status = Label(root, textvariable=var, bd=1, relief=SUNKEN, anchor=W)
status.pack(side=BOTTOM, fill=X)
root.mainloop()
script2.py
将是:
#script2
import time
def information():
variable = 0
while variable < 500:
yield variable
variable += 1
print(variable)
time.sleep(1)
#脚本2
导入时间
def信息():
变量=0
变量<500时:
产量变量
变量+=1
打印(变量)
时间。睡眠(1)
我知道这与生成器有关,但我的理解是,
yield
将暂停循环,将数据发送到原始程序,让它处理,然后取消暂停循环。有更好的方法来理解这个过程吗?您的信息
生成器返回一个迭代器,您需要保存迭代器实例并调用它的next()
,以获取下一个值。要更改var
,您需要使用.set()
来更改它
from tkinter import *
import script2
root = Tk()
canvas = Canvas(root, width=300, height=300)
canvas.pack()
def runScript():
var.set(next(info)) # set the variable as the "next" result of the info generator
info = script2.information() # the info is an iterator
button1 = Button(root, text="Click Me!", command=runScript)
button1.pack()
var = StringVar()
var.set('Waiting for Input...')
status = Label(root, textvariable=var, bd=1, relief=SUNKEN, anchor=W)
status.pack(side=BOTTOM, fill=X)
root.mainloop()
script2
可以保持不变。但是我建议你不要使用时间。睡眠,它不会像你期望的那样工作!它只会使你的程序在给定的几秒钟内没有响应
您将需要使用根目录。在之后,如果您想继续递增直到停止迭代,只需将runScript
更改为:
def runScript():
global info
try:
var.set(next(info)) # set the variable as the "next" result of the info generator
except StopIteration:
var.set('Finished')
info = script2.information()
else:
root.after(1, runScript)
首先,script2.information()
是一个生成器函数,这意味着您必须手动迭代第一次调用时返回的生成器对象,以获得连续的值
另一方面,tkinter
不支持多线程。您可以做的一件事是使用universal widget方法安排在一定时间后调用函数。在这种情况下,可以使用它来计划对(添加的)函数的调用,该函数在通过调用script2.information()
创建生成器对象后迭代生成器对象,并在每次调用时相应地更新StringVar()
小部件
您还需要更改script2.py
,这样它就不会调用time.sleep()
。这样做会使tkinter GUI程序在每次调用时挂起(因为它会临时中断tkintermainloop()
)的执行)
修改的script2.py
:
import time
def information():
variable = 0
while variable < 60: # changed from 500 for testing
yield variable
variable += 1
print(variable)
# time.sleep(1) # don't call in tkinter programs
谢谢你的回复!但是,当我做出您建议的更改时,我的状态栏变为“”,script2中的循环不会继续。此外,我只在另一个脚本中花费时间来模拟一些困难和耗时的事情。不过,我很感激这方面的宝贵信息!这对我很管用。。您是否将我的代码更改为:var.set(information())
?你需要做的和我做的完全一样。每次你按下按钮它都会增加吗?或者它是一次一个地通过数字直到循环结束,有点像一个进度表?我正在努力实现后者。我想我解释得不好。好吧,那你还想用发电机吗?生成器在“每次按下按钮时递增”的情况下工作得非常好,因为生成器在遇到收益时会暂停,在再次调用next()时会继续。。。。但对于后者,我认为没有必要
from tkinter import *
import script2
DELAY = 100 # in millisecs
root = Tk()
canvas = Canvas(root, width=300, height=300)
canvas.pack()
def do_update(gen, var):
try:
next_value = next(gen)
except StopIteration:
var.set('Done!')
else:
var.set(next_value)
root.after(DELAY, do_update, gen, var) # call again after delay
def run_script(var):
gen = script2.information() # create generator object
do_update(gen, var) # start iterating generator and updating var
var = StringVar()
var.set('Waiting for Input...')
button1 = Button(root, text="Run script!", command=lambda: run_script(var))
button1.pack()
status = Label(root, textvariable=var, bd=1, relief=SUNKEN, anchor=W)
status.pack(side=BOTTOM, fill=X)
root.mainloop()