我正在制作一个在 Raspberry Pi 支持的LCD屏幕上运行的菜单。我正在尝试使用线程模块使LCD上的文本更新,直到菜单位置发生变化。
菜单由菜单位置更改时调用的函数列表组成。使用事件处理程序从类外部调用switch_menu()
函数,并用于调用正确的菜单函数。其中一些功能(item2
);我希望他们循环,并与其他人(item1
);只显示静态文本。重要的是,当再次调用switch_menu()
时,它们会停止循环。我怎么能这样做?
(这是我的代码的简化版本)
class Menu:
def __init__(self):
self.LCD = Adafruit_CharLCD()
self.m_pos = 0
self.items = [self.item1,self.item2]
self.switch_menu(0)
def switch_menu(self,operation):
# 2. And here I want to stop it.
m_pos = self.m_pos
pos = m_pos
max_pos = len(self.items) - 1
m_pos = self.loop_selection(pos,max_pos,operation)
# 1. Here I want to start looping the function below.
self.items[m_pos]()
self.m_pos = m_pos
def loop_selection(self,pos,max_pos,operation):
if pos >= max_pos and operation == 1:
pos = 0
elif pos <= 0 and operation == -1:
pos = max_pos
else:
pos += operation
return pos
def item1(self):
self.LCD.clear()
text = "item1"
self.LCD.message(text)
def item2(self):
while True:
self.LCD.clear()
text = "item2"
self.LCD.message(text)
time.sleep(10)
答案 0 :(得分:0)
有很多方法可以实现这一点,一种简单的方法是在变量中进行 while 循环,然后在循环外部将其设置为 False (例如,一旦你想要停止它,当调用switch_menu时。请注意可能引起的任何竞争条件,由于我不了解您的其余代码,因此我无法进行更多的讨论。
答案 1 :(得分:0)
典型的,我一直试图让这个工作几天,并且我发布一个问题;我找到了答案。
这是我找到答案的地方: Stopping a thread after a certain amount of time
这就是我做的工作:
class Menu:
def __init__(self):
self.LCD = Adafruit_CharLCD()
self.m_pos = 0
self.items = [self.item1,self.item2]
self.switch_menu(0)
def switch_menu(self,operation):
try:
self.t_stop.set()
except:
pass
m_pos = self.m_pos
pos = m_pos
max_pos = len(self.items) - 1
m_pos = self.loop_selection(pos,max_pos,operation)
item = self.items[m_pos][0]
self.t_stop = threading.Event()
self.t = threading.Thread(target=item,args=(1,self.t_stop))
self.t.start()
self.m_pos = m_pos
def loop_selection(self,pos,max_pos,operation):
if pos >= max_pos and operation == 1:
pos = 0
elif pos <= 0 and operation == -1:
pos = max_pos
else:
pos += operation
return pos
def item1(self,arg):
while not stop_event.is_set():
text = "item1"
self.LCD.clear()
if not stop_event.is_set(): self.LCD.message(text)
stop_event.wait(10)
def item2(self,arg):
while not stop_event.is_set():
text = "item2"
self.LCD.clear()
if not stop_event.is_set(): self.LCD.message(text)
stop_event.wait(10)
我使用了try / except来绕过switch_menu()的初始执行:
try:
self.t_stop.set()
except:
pass
我第二次检查条件作为解决方法,以防止竞争条件:
if not stop_event.is_set(): self.LCD.message(text)
我不知道为什么在创建线程时我必须传递一个参数,但是当我没有时它会给我错误:
self.t = threading.Thread(target=item,args=(1,self.t_stop))
我知道它需要一些整理,但它确实有效。如果有人有一个更优雅的解决方案随时发布它。