【问题标题】:Making a Tkinter button do something while the program is within a loop在程序处于循环中时让 Tkinter 按钮执行某些操作
【发布时间】:2015-09-29 12:56:40
【问题描述】:

这是一个较长计划的一部分。所有这些方法都在同一个类中。 这个程序的基本作用是,只要按下开始按钮,程序就会在 30 秒的循环内运行。在这 30 秒内,每次触摸触摸传感器时,鼠标都会进水 2 秒。还有一个“GiveWater”按钮,每次我按下它时鼠标都会喝水。

我使用 tkinter 创建按钮

但是,该按钮仅在程序不在 30 秒循环内时有效。即使程序在循环中,“GiveWater”按钮如何才能工作?

我知道有一些关于多线程的东西,但我是 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

【问题讨论】:

  • 不要在tkinter 应用程序中使用time.sleep()。请改用after 方法。
  • 有什么区别?
  • 睡眠阻塞...
  • sleep 在一定时间内停止程序的执行。 after 将任务放在应用程序的“待办事项列表”中。

标签: python multithreading user-interface tkinter


【解决方案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)

【讨论】:

  • 你假设 selfafter()after_idle() 方法。
  • @martineau:这可能是一个正确的假设。 self 似乎是 Frame 或其他容器,因为它在创建按钮时用作第一个参数......不过,在答案中说明该假设可能会很好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-15
  • 1970-01-01
  • 1970-01-01
  • 2022-01-16
  • 1970-01-01
相关资源
最近更新 更多