当程序在循环中时,制作Tkinter按钮可以执行某些操作

时间:2015-07-10 17:04:02

标签: python multithreading user-interface tkinter

这是较长节目的一部分。所有这些方法都属于同一类。 该程序基本上做的是每当按下启动按钮时,程序在30秒循环内运行。在这30秒期间,每次触摸触摸传感器时,鼠标都会吸水2秒钟。还有#GiveWater'每次按下鼠标时都可以按下鼠标的按钮。

我使用tkinter来创建butttons

但是,该按钮仅在程序不在30秒循环内时才有效。我怎样才能“给水”'即使程序在循环中,按钮也能正常工作?

我知道有关于多线程的东西,但我是python的新手,我不知道它是什么或它是如何工作的。

如果有人能用简单的英语解释我如何使用多线程来实现这个程序或者让这个程序工作的另一种方法,我将不胜感激。

def createStartButton(self):
    """creates a button to start the program"""
    #Whenever button is pressed the 'touchSensor' method is invoked.
    self.StartButton = Button(self, text = 'Run touch sensor', command = self.touchSensor)        
    self.StartButton.grid()

def createGiveWaterButton(self):
    """creates a button that gives water to mouse whenever pressed"""
    #Whenever button is pressed the 'giveWater' method is invoked.
    self.WaterButton = Button(self, text = 'Give water', command = self.giveWater).        
    self.WaterButton.grid()

def giveWater(self):
    #Every time setOutputState(n, True) the output sends a signal..
    #..allowing the mouse to get water until it's set to False.
    self.myObject.setOutputState(0, True)
    time.sleep(0.1)
    self.myObject.setOutputState(0, False)

def touchSensor(self):
    """controls how the touch sensor runs"""

    time_at_program_start = time.time()

    #Every time setOutputState(n, True) it the output sends..
    #..a signal until it's set to False

    while True:
        self.myObject.setOutputState(0, False)

        #If the sensorValue > 900 (i.e. it's touched) the output is True       
        #(i.e. sends a signal allowing the mouse to drink.)
        if self.myObject.getSensorValue(2) >900:
            self.myObject.setOutputState(0, True)
            #waits 2 seconds
            time.sleep(2)
            #sets OutputState to False so the signal stops.
            self.myObject.setOutputState(0, False)

        #checks if the program already runs for 30 seconds.
        #If it does the loop/program stops.
        if time.time() - time_at_program_start >= 30:
            break

1 个答案:

答案 0 :(得分:1)

使用以下两种方法替换touchSensor方法并改为使用它们:

def touchSensor(self):
    self.after_idle(self.touchSensorLoop, time.time())

def touchSensorLoop(self, time_at_program_start):
    self.myObject.setOutputState(0, False)
    if time.time() - time_at_program_start < 30:
        if self.myObject.getSensorValue(2) > 900:
            self.myObject.setOutputState(0, True)
            self.after(2000, self.touchSensorLoop, time_at_program_start)
        else:
            self.after_idle(self.touchSensorLoop, time_at_program_start)