在Tkin中用after()循环

2024-10-01 17:30:20 发布

您现在位置:Python中文网/ 问答频道 /正文

我是Tkinter的新手,对我想做的事情还是很不确定,希望这不是愚蠢的。任何帮助都是受欢迎的。在

我想用我的Rasberry Pi控制一些马达。这些马达把原料放在一起。它在Python中工作得很好,但是我想要一个带有几个按钮的GUI。每个按钮都应该在函数makerecipe中放入一个配方。配方包括不同电机应启动的时间列表。Makerecipe将激活GPIO引脚。在

然后一个新功能的电机应该启动。在这里,它检查何时应停用电机。这是一个在Python中有效的simpel技巧,但我不知道如何在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:motor

第二个问题是我知道如何与时间。睡觉,但我在这个论坛上到处都看到你不应该这样做。所以我试着以后再使用,但不知道如何正确使用这个。在

我希望有人能帮助这个新手。我很了解Python的逻辑,但Tkinter对我来说是一种新的思维方式。在


Tags: thetoinoutputindexgpioreciperoot
1条回答
网友
1楼 · 发布于 2024-10-01 17:30:20

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)

变量root是一个没有运动功能的TK对象。这就是AttributeError的原因。将此行改为:

^{2}$

将删除此错误。在

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.

您应该使用after,因为Tk有一个eventloop正在运行(the根.mainloop()call)根据事件做出反应(例如在单击按钮或经过某个时间后调用函数)。但是如果你用时间。睡觉在代码中,可能会干扰此事件循环。在

解决方法是在之后向传递一个函数引用,这样Tk eventloop会在合适的时间调用该函数。但在这里,您将立即调用函数:

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

这行调用motor(并将alfa作为参数传递),然后将motor的返回值(可以是任何值)传递给根。后。在

这条线应该是这样的:

root.after(1000, motor, alfa)

现在我们告诉在1秒后用alfa参数调用motor。在

相关问题 更多 >

    热门问题