kivy部署移动端预测模型网页计算器记录

kivy部署移动端预测模型记录

之所以选择kivy作为移动端的语言,本人是先了解的python,然后才来学习kivy,是看中了python的数据处理能力和施行机器学习算法的能力,kivy与python无缝结合,或许是优于其他类似的语言。

架构(kv部分,python部分,APP部分如何组织

目前采用的一个架构是:

from kv.lang.builder import Builder
#第一部分: kv部分,其中构建了一个尖括号包裹的Widget, 尖括号包裹的widget在kv中被认为是'"root"widget.
Builder.load_string(""" 
<MenuScreen>:#主页
	name:'menu'
	BoxLayout:
        orientation:'vertical' 
        ActionBar:
            id:bar
            ActionView:
                ActionPrevious:
                    title:'慢性疾病'
                    font_name:"Droid"
                    markup:True
                    with_previous:False
                    app_icon:'logo.png'
                ActionButton:
                    text:"遇病一测,防微杜渐"
                    font_name:"Droid"
        Accordion:
            orientation:'vertical'
            AccordionItem:
                title:"常见问题问答"
                collapse:False
                GridLayout:
                    cols:1
                    canvas:
                        Color:
                            rgb:1,1,0.8
                        Rectangle:
                            pos:self.pos
                            size:self.size
                    ScrollView:
                        do_scroll_x:False
                        do_scroll_y:True
                        Label:
                            size_hint_y:None
                            text:root.txt
                            font_name:"Droid"
                            color: 0,0.2,0.4,1
                            markup:True
                            height:self.texture_size[1]
                            text_size:self.width, None
                            line_height:1.2
                            # padding_x:2
                            valign: 'center'               
            AccordionItem:
                title:"糖尿病、冠心病、卒中"
                GridLayout:
                    cols:3
                    pos_hint: {"center_x": .5, "center_y": .5}
                    row_force_default:True
                    row_default_height:200
                    padding_y:10
                    canvas:
                        Color:
                            rgb:0.6,0.8,0.2
                        Rectangle:
                            pos:self.pos
                            size:self.size
                    Button:
                        text:'2型糖尿病肾病'
                        on_press:root.manager.current='screen1'  
                        # background_normal:''
                        # background_color:(0,0.6,1,1)
                    Button:
                        text:"2型糖尿病脑卒中"
                        on_press:root.manager.current='screen2'  
                    Button:
                        text:"2型糖尿病"
                        on_press:root.manager.current='screen4'  
                    Button:
                        text:"冠心病"
                        on_press:root.manager.current='screen5' 
                    Button:
                        text:"卒中"
                        on_press:root.manager.current='screen7' 
                    Button:
                        text:'认知功能障碍'
                        on_press:root.manager.current='screen8'  
           
<screen1>: #与主页并列
	name:'screen1'
	BoxLayout:
        orientation:'vertical'
        ActionBar:
            id:bar
            ActionView:
                ActionPrevious:
                    title:'2型糖尿病肾病'
                    font_name:"Droid"
                    markup:True
                    app_icon:'logo.png'
                    with_previous:True
                    on_press:root.manager.current="menu"
        TabbedPanel:
            id:tp
            do_default_tab:False
            canvas.before:
                Color:
                    rgb:0.4,0.4,0.6
                Rectangle:
                    pos:self.pos
                    size:self.size
            TabbedPanelItem:
                text:"ID31865340"
                font_name:"Droid"
                # border:'off'
                GridLayout:
                    cols:1
                    padding: '10dp'
                    spacing:'10dp' 
                    canvas.before:
                        Color:
                            rgb:0.8,0.8,1
                        Rectangle:
                            pos:self.pos
                            size:self.size 
                    GridLayout:
                        cols:3
                        panding:10
                        DarkLabel:
                            text:"性别"
                        ToggleButton:
                            id:female
                            text:'女' 
                            group:'gender'
                            state:'down'
                        ToggleButton:
                            id:male
                            text:"男"
                            group:'gender'
                    GridLayout:
                        cols:4
                        spacing:10
                        DarkLabel:
                            text:"糖尿病病程"
                        ToggleButton:
                            id:<5year
                            text:'<5年' 
                            group:'duration'
                            state:'down'
                        ToggleButton:
                            id:5-10year
                            text:"5-10年"
                            group:'duration'
                        ToggleButton:
                            id:>10year
                            text:">10年"
                            group:'duration'
                    GridLayout:
                        cols:3
                        DarkLabel:
                            text:"视网膜病变"
                        ToggleButton:
                            text:"无"
                            group:'dr'
                            state:"down"
                        ToggleButton:
                            id:dr_yes
                            text:'有'
                            group:'dr'
                    GridLayout:
                        cols:4
                        DarkLabel:
                            text:"血尿"
                        ToggleButton:
                            id:<5num
                            text:'<5个' 
                            group:'hematuria'
                            state:'down'
                        ToggleButton:
                            id:5-10num
                            text:"5-10个"
                            group:'hematuria'
                        ToggleButton:
                            id:>10num
                            text:">10个"
                            group:'hematuria'
                    GridLayout:
                        cols:3
                        DarkLabel:
                            text:'贫血'
                        ToggleButton:
                            id:anemia_no
                            text:'否'
                            group:'anemia'
                            state:'down'
                        ToggleButton:
                            id:anemia_yes
                            text:'是'
                            group:'anemia'
                    GridLayout:
                        cols:3
                        DarkLabel:
                            text:'HbA1c'
                        ToggleButton:
                            id:HbA1c_no
                            text:'<7%'
                            group:'HbA1c'
                            state:'down'
                        ToggleButton:
                            id:HbA1c_yes
                            text:'≥7%'
                            group:'HbA1c'   
                    GridLayout:
                        cols:3
                        DarkLabel:
                            text:'eGFR'
                        ToggleButton:
                            id:eGFR_high
                            text:'≥90ml/min/1.73m2'
                            group:'gfr'
                            state:'down'
                        ToggleButton:
                            id:eGFR_low
                            text:'<90ml/min/1.73m2'
                            group:'gfr'
                    GridLayout:
                        cols:4
                        DarkLabel:
                            text:"UPE"
                        ToggleButton:
                            id:<1g
                            text:'<1g/24h' 
                            group:'upe'
                            state:'down'
                        ToggleButton:
                            id:1-3g
                            text:"1-3.5g/24h"
                            group:'upe'
                        ToggleButton:
                            id:>3g
                            text:">3.5g/24h"
                            group:'upe'
                    GridLayout:
                        cols:3
                        DarkLabel:
                            text:"高血压"
                        ToggleButton:
                            id:bp_normal
                            text:'SBP<140且DBP<90'
                            font_size:15
                            group:'bp'
                            state:'down'
                        ToggleButton:
                            id:bp_unnormal
                            text:'SBP≥140或DBP≥90'
                            font_size:15
                            group:'bp'
                    AButton:
                        text:'计算'
                        on_state: root.on_press_prob()
                        pos_hint:{'center_x':.5,'center_y':.5}
                        size_hint:(0.9,0.9)              
                    Label:
                        id:prob_label
                        text:" "
                        color:(0.4,0.4,0.6,1)
                    GridLayout:
                        cols:4
                        spacing: '10dp'         
                        AButton:
                            text:'模型信息表'
                            on_release:root.info_sheet()
                            pos_hint:{'center_x':.5,'center_y':.5} 
                        AButton:
                            text:'评价星级:3星'
                            on_release:root.conclusion()
                            pos_hint:{'center_x':.5,'center_y':.5}
""") 
#第二部分:python 部分, 与一般的python语言类似
class MenuScreen(Screen):
	pass
class screen1(Screen):
	def on_press_prob(self, *args):
        duration1 = self.ids['5-10year'].state
        if duration1=="down":
            duration_5=1
        else:
            duration_5=0
        duration2=self.ids['>10year'].state
        if duration2=='down':
            duration_10=1
        else:
            duration_10=0
        sex = self.ids['female'].state
        if sex == 'down':
            sex_female = 1
        else:
            sex_female = 0
        dr=self.ids['dr_yes'].state
        if dr=='down':
            dr_yes =1
        else:
            dr_yes=0
        hematuria1=self.ids['>10num'].state
        if hematuria1=='down':
            hematuria_10 = 1
        else:
            hematuria_10 = 0
        hematuria2=self.ids['5-10num'].state
        if hematuria2=='down':
            hematuria_5=1
        else:
            hematuria_5=0
        anemia=self.ids['anemia_yes'].state
        if anemia=='down':
            anemia_yes=1
        else:
            anemia_yes=0
        HbA1c=self.ids['HbA1c_yes'].state
        if HbA1c=='down':
            hba1c=1
        else:
            hba1c=0
        gfr=self.ids['eGFR_low'].state
        if gfr=='down':
            egfr_90=1
        else:
            egfr_90=0
        upe1=self.ids['>3g'].state
        if upe1=='down':
            upe_3=1
        else:
            upe_3=0
        upe2=self.ids['1-3g'].state
        if upe2=='down':
            upe_1=1
        else:
            upe_1=0
        bp=self.ids['bp_unnormal'].state
        if bp=='down':
            bp_unnormal=1
        else:
            bp_unnormal=0

        list_or = [0.35, 7.46, 2.99, 8.27, 0.15,0.70,3.48,1.43,3.78,2.24,1.76,2.17]
        list_para = [sex_female, duration_10, duration_5,dr_yes,hematuria_10,hematuria_5,anemia_yes,hba1c,bp_unnormal,upe_3,upe_1,egfr_90]
        intercept = 0.017   
        model=ev.logistic(ls_or=list_or,ls_xvar=list_para,intercept=intercept)
        prob = model.prob()
        label = self.ids['prob_label']
        label.text = "患者患糖尿病肾病的概率为: " + str(round(prob, 2) * 100) + '%'
#第三部分:APP部分,也是python语言的一部分,但是功能是与其它python部分有不同,可以独立出来作为一个特殊的功能块.
class MPDApp(App):
  def build(self):
        sm=ScreenManager() #通过这一部分将所有的widget整合整合在一起.
        sm.add_widget(MenuScreen(name='menu'))
        sm.add_widget(screen1(name='screen1'))
        
        return sm
MPDApp().run()

个人认为这个架构比较清晰,当然我的经验还是有限。

遇到的问题及解决

首先是中文支持的问题,如果构建的是手机端的app,那就不要 用雅黑字体(开始用雅黑字体导致在手机上一直不能识别),因为手机不支持,我现在用的是‘Droid-Sans-Fallback.ttf’。

kivy.resources.resource_add_path("./") #字体文件放在了和main.py同样的目录下
# #通过labelBase
LabelBase.register("Droid","Droid-Sans-Fallback.ttf")
kivy.core.text.Label.register("Droid","Droid-Sans-Fallback.ttf")

widget模板

这一部分主要用kv语言来进行书写。
可以通过改写widget来个性化widget,我一般用来支持中文和调整各种背景颜色和大小。
暂时没有对应python 类,或许是因为没有用到复杂的函数功能,有相应心得随时更新。

<DarkLabel@Label>:
    font_name:"Droid"#指定字体
    color:(0.4,0.4,0.6,1)
    size_hint_x: None
    width:220
    text_size:self.width, None

共同的函数可放在app类中

比如在主页和页面1,有同样一个按钮使用相似的函数,这个函数就可以放在app类中,不用在页面对应的class里面重复写。

buildozer构建APP

操作系统用的是ubuntu系统(windows7+虚拟机)
一定要安装adb。一是方便检查app不成功时哪里出错,个人有好几次app闪退的情况, 就是靠adb检查出的原因;二是builder构建app时,如果连有手机,可以将app直接推送到手机上安装。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

预测模型的开发与应用研究

文中代码请大家随意

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值