2014-01-14 63 views
0

我是Tkinter的新手,我仍然很不確定我想要做的事情,希望它不會愚蠢。歡迎每一個幫助。與Tkinter中的after()循環

我想用我的Rasberry Pi來控制一些電機。這些電機將原料放在一起。它在Python中工作正常,但我想要一個帶有幾個按鈕的GUI。每個按鈕都應該在makerecipe函數中放置一個配方。配方由一系列時間表組成,包括不同電機的啓動時間。 Makerecipe將激活GPIO引腳。

然後啓動一個新的功能電機。在此檢查電機何時應該停用。這是一個在Python中工作的小技巧,但我不知道如何使它在Tkinter中工作。每秒一個循環檢查時間是否等於配方中的含量。如果發生這種情況,電機將停用。

from Tkinter import * 
import ttk 
import time 

root = Tk() 
var = StringVar() 
uitput = StringVar() #I want to print what is happening to label L2 
uitput.set('Nothing') #when program starts it says 
conversie = [7, 11, 15] #I will use pins 7, 11 and 15 on the RPi, 
moj = [0, 0, 2] #recipe 1, through Button 1, number of seconds the pins are True 
sob = [4, 0, 0] #recipe 2, through Button 2, number of seconds the pins are True 

#The following function activates the pins which are used in making the recipe 
#later this will just activate the pins, for now it shows it in a label on screen. 
#this seems to work 

def makerecipe(argu): 
    aa=[] 
    for i in range(len(argu)): 
     if argu[i]==0: 
      a=('GPIO.output(', str(conversie[i]), 'False)') 
      aa.append(a) 
     else: 
      b=('GPIO.output(', str(conversie[i]), 'True)') 
      aa.append(b) 
    uitput.set(aa) 
    root.update_idletasks() 
    root.motor(argu) 

#Next I want to have a function that looks at recipe and reads how long the 
#GPIO pins should be active. Then turns them off one at a time. I just don't 
#understand the after function. 
#I think, but probably wrong, that my recipe was loaded in makerecipe and argu 
#has the value of the recipe because of the button, and I hoped I could pass argu 
#along to the function motor. 


def motor(motorinput): 
    resultaat=('bla') 
    uitput.set(resultaat) 
`enter code here` cc=[] 
    for MotorNum in range(max(motorinput)+1): 
     if MotorNum in motorinput: 
      if motorinput.index(MotorNum)==0: 
       c=("GPIO.output(",conversie[motorinput.index(MotorNum)],", False)") 
       cc.append(c) 
      elif motorinput.index(MotorNum)==1: 
       d=("GPIO.output(",conversie[motorinput.index(MotorNum)],", False)") 
       cc.append(d) 
      elif motorinput.index(MotorNum)==2: 
       e=("GPIO.output(",conversie[motorinput.index(MotorNum)],", False)") 
       cc.append(e) 
     uitput.set(cc) 
     root.update_idletasks() 
     #root.after(1000, motor(alfa)) #This goes wrong. 

B= Button(root, text="optie 1", command=lambda: makerecipe(moj)) 
B.pack() 
L2=Label(root, textvariable=uitput, width=100) 
L2.pack() 
root.mainloop() 

我在這裏打印我整個代碼的原因是,它可能有助於知道什麼是地獄,我想,它可能看起來可怕,但我試圖得到它更好。

第一個問題是我顯然不知道如何調用我的第一個函數內的下一個函數電機。它停在那裏,給我:AttributeError:馬達

第二個問題是我知道如何使用time.sleep,但我在這個論壇上到處讀到你不應該這樣做。所以我試圖用後,但不知道如何正確使用它。

我希望有人能幫助這個總新手。我很瞭解Python的邏輯,但Tkinter對我來說是一種新的思維方式。

回答

0

First question is I apparently don't understand how to call the next function motor inside my first function. It stops there and gives me: AttributeError: motor

的問題是在makerecipe功能最後一行:

root.motor(argu) 

可變是不具有電動機功能的TK對象。這就是AttributeError的原因。將此行更改爲:

motor(argu) 

將刪除此錯誤。

Second question is I know how to work with time.sleep, but I read everywhere on this forum that you should not do this. So I am trying to use after, but don't know how to use this properly.

因爲Tk的有一個事件循環運行(在root.mainloop()調用)基於事件的反應(如調用你的功能一個按鈕被按下時,或在一定時間之後,您應該使用)。但是,如果在代碼中使用time.sleep,則可能會干擾此事件回調。

修復方法是,您應該在之後將函數引用傳遞給,這樣Tk eventloop會在正確的時間調用該函數。但在這裏,您呼叫的功能馬上:

root.after(1000, motor(alfa)) #This goes wrong. 

此行是調用電機(並通過阿爾法作爲參數),然後電機的返回值(可以是任何東西)傳遞給根據

此行應該是這樣的:

root.after(1000, motor, alfa) 

現在我們告訴調用電機阿爾法的說法,1秒後。