Kivy动态生成医生按钮不显示问题求助
Kivy动态生成医生按钮不显示问题修复
问题背景
我正在开发一款电子健康记录(EHR)程序,用户登录后可在同一账户下创建多名医生。需要在SignIn_MD界面中,为用户列表中的每位医生生成对应按钮。示例字典包含2个医生('a'和'b'),假设kivyfxns功能正常。目前遇到的问题:硬编码列表时按钮可正常显示,但通过函数动态更新时按钮不显示。
示例字典(修正语法错误后)
users= {'doctors': [{'name':'a'}, {'name':'b'}]}
原代码
GUI.py
class UserSignIn(Screen): username_input = StringProperty('username') password_input = StringProperty('password') user_error = StringProperty('') pass_error = StringProperty('') doctor_list = None def update_user(self, txt_input): self.username_input = txt_input.text print(self.username_input) def update_pw(self, txt_input): self.password_input = txt_input.text print(self.password_input) def submit(self): print('submitted') print(self.username_input) print(self.password_input) check = kivy_fxns.kivy_signin(self.username_input,self.password_input) if check == True: self.doctor_list = DoctorList() self.doctor_list.create_doctor_buttons() App.get_running_app().root.current ='SignIn_MD' else: self.user_error = 'invalid username and password' class DoctorList(GridLayout): def __init__(self, *args, **kwargs): super().__init__(**kwargs) self.cols = 1 def create_doctor_buttons(self): doctors = kivy_fxns.get_doctors() for doctor in doctors: btn = Button(text= doctor.get('lastname'), on_release= lambda instance, doctor : self.on_button_click(instance,doctor)) self.add_widget(btn)
GUI.kv
<SignIn_MD>: name: 'SignIn_MD' BoxLayout: orientation: 'vertical' Label: text: 'Sign In' Label: text: 'the following are the list of doctors of user' BoxLayout: orientation: 'vertical' Label: size_hint: 0.25,1 DoctorList: #does not show any button Button: # this button is a sample that works fine text: 'sample' Label: size_hint: 0.25,1 Label:
问题原因
你在submit方法中新建的DoctorList实例,和KV文件中SignIn_MD界面里的DoctorList是两个独立对象。KV文件里的DoctorList是界面加载时自动创建的,而你动态添加按钮的是另一个未被挂载到界面的实例,所以按钮无法显示。
修复方案
1. 给KV中的DoctorList添加id
修改GUI.kv中的DoctorList部分,添加id以便Python代码引用:
<SignIn_MD>: name: 'SignIn_MD' BoxLayout: orientation: 'vertical' Label: text: 'Sign In' Label: text: 'the following are the list of doctors of user' BoxLayout: orientation: 'vertical' Label: size_hint: 0.25,1 DoctorList: id: doctor_list # 添加id Button: text: 'sample' Label: size_hint: 0.25,1 Label:
2. 修改submit方法,操作界面已存在的DoctorList实例
不要新建DoctorList,而是获取界面中已有的实例,清空旧按钮后再添加新按钮:
def submit(self): print('submitted') print(self.username_input) print(self.password_input) check = kivy_fxns.kivy_signin(self.username_input,self.password_input) if check == True: # 获取SignIn_MD界面的DoctorList实例 signin_md = App.get_running_app().root.get_screen('SignIn_MD') doctor_list = signin_md.ids.doctor_list # 清空现有按钮,避免重复添加 doctor_list.clear_widgets() # 生成新按钮 doctor_list.create_doctor_buttons() App.get_running_app().root.current ='SignIn_MD' else: self.user_error = 'invalid username and password'
3. 修正DoctorList类的缩进错误
原代码中__init__方法内的代码没有缩进,会导致运行报错,修正后:
class DoctorList(GridLayout): def __init__(self, *args, **kwargs): super().__init__(**kwargs) self.cols = 1
4. 修正lambda变量绑定问题
原lambda表达式会导致所有按钮引用最后一个医生对象,需要显式绑定当前doctor变量:
def create_doctor_buttons(self): doctors = kivy_fxns.get_doctors() for doctor in doctors: # 显式绑定doctor参数 btn = Button(text= doctor.get('name'), on_release= lambda instance, doctor=doctor : self.on_button_click(instance,doctor)) self.add_widget(btn)
(注:如果get_doctors()返回的医生字典包含lastname字段,可保留doctor.get('lastname'),否则改成name匹配示例字典)
5. 修正示例字典的语法错误
原示例字典是无效Python语法,列表内不能直接放键值对,需改成包含字典的列表:
users= {'doctors': [{'name':'a'}, {'name':'b'}]}
内容的提问来源于stack exchange,提问作者user22600459
相关产品推荐
相关产品推荐

