Python Kivy如何实现多个弹窗依次顺序弹出
Kivy无线程实现弹窗顺序弹出方案
问题背景
开发基于Python Kivy的应用时,程序运行了2个multiprocessing.Process进程:
- RFID读卡器进程:触发时弹出弹窗,供用户选择要跳转的界面
- 串口通信进程
主线程通过队列和两个进程通信,这部分功能运行正常。现在需要给Kivy程序新增学习流程,程序一共包含4个界面: mainscreenadminscreenmanagementscreeninitialscreen:该界面仅运行一次,完成配置后将无法再次访问
点击initialscreen内按钮会触发startLearningProcess函数,初始代码如下:
def startLearningProcess(self, lockeramount): self.lockeramount = int(lockeramount) with Database(self.databasepath) as db: db.truncate_table('LOCKERS') # 重置主键序列,让id从1开始计数 db.reset_primary_key_sequence('LOCKERS') for locker in range(int(lockeramount)): # 使用with语句保证操作完成后自动关闭数据库连接 with Database(self.databasepath) as db: # 插入对应数量的储物柜记录到数据库 db.insertLockerRow(locker+1,'Pieter')
如果直接在这个函数里加循环弹弹窗的逻辑,输入数值5时会一次性弹出5个弹窗,错误代码如下:
while self.lockeramount != 0: popup = Popup(title='Test popup', auto_dismiss=True, content=Label(text='Hello world'), size_hint=(None, None), size=(400, 400)) popup.open() self.lockeramount -= 1
需求:输入数值5时,5个弹窗逐个依次弹出,关闭当前弹窗后才弹出下一个,且不使用线程实现。
实现方法
不需要引入额外线程,借助Kivy自带的Clock定时调度+弹窗状态标记即可实现,步骤如下:
- 在
class InitialScreen(Screen):中新增两个类变量:- 布尔变量
booleanUp,初始值为False,用来标记当前是否有弹窗处于打开状态 - 整型变量
lockeramount,初始值为0,用来存储需要弹出的弹窗总数量
- 布尔变量
- 调用
startLearningProcess时,把界面输入的数值赋值给self.lockeramount,在函数中添加定时调度逻辑:Clock.schedule_interval(lambda dt: self.schedule_popups(), 1) - 新增弹窗关闭回调方法、定时任务执行方法,代码如下:
def close_popup(self, instance): self.booleanUp = False def schedule_popups(self): if self.lockeramount > 0 and not self.booleanUp: print(f'opening up popup {self.lockeramount}') popup = Popup(title='MyPopup', content=Label(text='Abba ' + str(self.lockeramount)), size_hint=(0.5, 0.5)) popup.bind(on_dismiss=self.close_popup) self.lockeramount -= 1 self.booleanUp = True popup.open() else: print('not opening another popup')
逻辑说明
- 弹出新弹窗时将
booleanUp设为True,阻止下一次定时调度触发新弹窗 - 给弹窗绑定
on_dismiss事件,弹窗关闭时会触发close_popup方法,把booleanUp重置为False,下一次定时任务检测到无弹窗打开、且还有待弹弹窗时,就会弹出下一个,最终实现弹窗依次弹出的效果。
内容的提问来源于stack exchange,提问作者hoek rand
相关产品推荐
相关产品推荐

