2017-05-17 22 views
2

私は、インポートされたスクリプトを終了することなく、Pythonで2つのスクリプトの間で変数を渡す際に問題があります。私は、tkinter GUIのステータスバーを更新して、script2のカウンターの数を反映させたいと思います。私はデータを送信、これは発電に関係していますが、私の理解が収量がループを一時停止するというものであったことを理解2つのスクリプト間で変数を渡しますか?

#script2 
import time 

def information(): 
    variable = 0 
    while variable < 500: 
     yield variable 
     variable += 1 
     print(variable) 
     time.sleep(1) 

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() 

スクリプト2は、次のようになります。私は以下のコードを含めました元のプログラムに処理させ、ループをポーズ解除します。このプロセスを理解する良い方法はありますか?

ありがとうございました!

答えて

0

一つには、script2.information()は手動でする必要があります意味ジェネレータ関数であります最初の呼び出しで返されたジェネレータオブジェクトを反復して、連続する値を取得します。

tkinterは、マルチスレッドをサポートしていません。 1つのことです。ユニバーサルウィジェットのメソッドafter()を使用して一定時間後に関数を呼び出すスケジュールです。この場合、生成された後にジェネレータオブジェクトを反復する(追加された)関数の呼び出しをスケジュールするのに、script2.information()を呼び出して、それが呼び出されるたびにStringVar()ウィジェットを更新します。

またscript2.pyを変更してtime.sleep()を呼び出さないようにする必要があります。そうすることで、tkinter GUIプログラムが呼び出されるたびにハングする(tkinter mainloop()の実行を一時的に中断するため)。

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 

メインスクリプト:応答のための

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() 
0

informationジェネレータがイテレータを返した場合は、イテレータインスタンスを保存し、次の値を取得するために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は同じままです。しかし、私はにはお勧めしませんを使用time.sleep、それは期待どおりに動作しません!それはあなたのプログラムが与えられた秒間応答しないようにします。

あなたが呼び出すとStopIterationまで継続してインクリメントしたい場合は、単にこれにrunScriptを変更root.afterを使用する必要があります::

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) 
+0

ありがとう!私があなたの提案した変更を加えると、私のステータスバーは "<ジェネレータオブジェクト...>"になり、script2のループは継続しません。 – cloudfr0g

+0

また、他のスクリプトに時間を入れて、困難で時間のかかることをシミュレートします。私はそれについての情報のナゲットに感謝します! – cloudfr0g

+0

それは私のためにうまくいきました。私のコードを 'var.set(information())'に変更しましたか?あなたは私が行ったことを正確に行う必要があります。 – abccd

関連する問題