如何将.py文件中的按钮动态添加到.kv文件中的屏幕管理器的单个屏幕中

时间:2019-09-22 02:12:29

标签: python json dynamic kivy

如何动态地向.kv文件的屏幕管理器的特定屏幕添加按钮?问题是,创建的按钮会显示在所有屏幕上。

我正在开发一个程序,该程序将允许用户在其中输入特定条件并计算ACFM。我目前正在尝试设置一个文件屏幕,允许用户创建多个文件。我试图允许一个名为“创建新文件”的主按钮在第一个屏幕上创建更多按钮。问题是,创建的按钮会显示在所有屏幕上。

main.py

from kivy.app import App
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.uix.floatlayout import FloatLayout
import Functions as f1
from kivy.uix.button import Button
Window.size = (300,625)
window_x = Window.width
window_y = Window.height

Builder.load_file("main.kv")

class counter:
    def __init__(self):
        self.count = 2
    def increase(self):
        self.count += 1
b = counter()

class Calc(FloatLayout):
    def testbutton(self,instance):
        btn = Button(text = "testing123", color = (1,1,1,1),
                     size_hint =(.5,.05),
                     pos = (0,(window_y-(window_y*(.07+(b.count*.05)))))
                     )
        b.increase()
        self.add_widget(btn)

    # define the multiplication of a function
    def calculate(self, instance):
        f = float(self.flow.text)
        p = float(self.pressure.text)
        t = float(self.temperature.text)
        sg = float(self.specific_gravity.text)
        self.acfm.text = str(f) #str(f1.ACFM(f,p,t,sg)) I commented this out for the purpose of posting this in my questions.

class test(App):
    def build(self):
        return Calc()

if __name__=="__main__":
    test().run()

main.kv

<calc>:
    flow: _flow
    pressure: _pressure
    temperature: _temperature
    specific_gravity: _specific_gravity
    acfm: _acfm
    FloatLayout:
        ScreenManager:
            id: screen_manager
            size: self.size
            Screen:
                name: "filescreen"
                FloatLayout:
                    canvas:
                        Color:
                            rgb: 1,1,1
                        Rectangle:
                            size: self.width, self.height
                            pos: self.pos
                    AnchorLayout:
                        anchor_x: 'center'
                        anchor_y: 'top'
                        Label:
                            canvas.before:
                                Color:
                                    rgb: 1,1,1
                                Rectangle:
                                    size: self.size
                                    pos: self.pos
                                Color:
                                    rgb: 0,0,0
                                Line:
                                    width: 1
                                    rectangle: self.x,self.y,self.width,self.height
                            size_hint: 1,.07
                    FilescreenButton:
                        text: "Create New File"
                        pos: 0,root.height-(root.height*(.07+.05))
                        on_press: root.testbutton(*args)
            Screen:
                name: "solverscreen"
                GridLayout:
                    cols:1
                    size_hint: 1,1
                    ScrollView:
                        FloatLayout:
                            canvas:
                                Color:
                                    rgb: 1,1,1
                                Rectangle:
                                    size: self.width, self.height
                                    pos: self.pos
                            size_hint: 1,1.5
                            GridLayout:
                                cols:1
                                spacing: 1
                                pos_hint: {"top": (1),"left": 1}
                                size_hint: .4, None
                                row_default_height: root.height*.05
                                Label:
                                    text: "Inputs"
                                    color: 0,0,0,1
                                    canvas.before:
                                        Color:
                                            rgb: 1,1,1
                                        Rectangle:
                                            size: self.width,self.height
                                            pos: self.pos
                                CustomLabel:
                                    text: "Flow"
                                CustomLabel:
                                    text: "Pressure"
                                CustomLabel:
                                    text: "Temperature"
                                CustomLabel:
                                    text: "Specific Gravity"
                                Label:
                                    text: "Results"
                                    color: 0,0,0,1
                                    canvas.before:
                                        Color:
                                            rgb: 1,1,1
                                        Rectangle:
                                            size: self.width,self.height
                                            pos: self.pos
                                Button:
                                    text: "Calculate"
                                    on_press: root.calculate(*args)
                            GridLayout:
                                cols:1
                                spacing: 1
                                pos_hint: {"top": (1),"right": .7}
                                size_hint: .3, None
                                row_default_height: root.height*.05
                                Label:
                                    canvas.before:
                                        Color:
                                            rgb: 1,1,1
                                        Rectangle:
                                            size: self.width,self.height
                                            pos: self.pos
                                TextInput:
                                    text: "0"
                                    id: _flow
                                TextInput:
                                    text: "0"
                                    id: _pressure
                                TextInput:
                                    text: "0"
                                    id: _temperature
                                TextInput:
                                    text: ".6"
                                    id: _specific_gravity
                                Label:
                                    canvas.before:
                                        Color:
                                            rgb: 1,1,1
                                        Rectangle:
                                            size: self.width,self.height
                                            pos: self.pos
                                Label:
                                    id: _acfm
                                    color: 0,0,0,1
                                    canvas.before:
                                        Color:
                                            rgba: .7,.7,.7,1
                                        Rectangle:
                                            pos: self.pos
                                            size: self.size
                                        Color:
                                            rgb: 1,1,1
                                        Line:
                                            width: 1
                                            rectangle: self.x,self.y,self.width,self.height
                            GridLayout:
                                cols:1
                                spacing: 1
                                pos_hint: {"top": (1),"right": 1}
                                size_hint: .3, None
                                row_default_height: root.height*.05
                                Label:
                                    canvas.before:
                                        Color:
                                            rgb: 1,1,1
                                        Rectangle:
                                            size: self.width,self.height/2
                                            pos: self.pos
                                CustomButton:
                                    text: "MMSCFD"
                                CustomButton:
                                    text: "PSIG"
                                CustomButton:
                                    text: "F"
                                CustomButton:
                                    text: "SG"
                                Label:
                                    canvas.before:
                                        Color:
                                            rgb: 1,1,1
                                        Rectangle:
                                            size: self.width,self.height
                                            pos: self.pos
                                CustomButton:
                                    text: "ACFM"
        AnchorLayout:
            anchor_x: 'left'
            anchor_y: 'bottom'
            GridLayout:
                cols: 4
                size_hint: 1,.05
                canvas:
                    Color:
                        rgb: 1,1,1
                    Rectangle:
                        size: self.size
                        pos: self.pos
                Button:
                    text: "Files"
                    on_press: screen_manager.current = 'filescreen'
                Button:
                    text: "Solver"
                    on_press: screen_manager.current = 'solverscreen'
<CustomLabel@Label>:
    #font_size: (((self.width*5)+(self.height))/6)*.12
    canvas.before:
        Color:
            rgb: 0,0,0
        Rectangle:
            size: self.size
            pos: self.pos
<CustomButton@Button>:
    background_color: .25,.25,.25,1
    canvas.before:
        Color:
            rgba: .25,.25,.25,1
        Rectangle:
            size: self.size
            pos: self.pos
        Line:
            width: .09
            rectangle: self.x,self.y,self.width,self.height
<FilescreenButton@Button>:
    size_hint: .5,.05
    color: 0,0,0,1
    background_color: 1,1,1,0
    canvas:
        Color:
            rgb: 0,0,0
        Line:
            width: 1
            rectangle: self.x,self.y,self.width,self.height

我没有收到任何错误消息。我只希望从.py文件动态创建的按钮只能转到.kv文件的一个屏幕。

1 个答案:

答案 0 :(得分:0)

您当前正在将其添加到作为根的Calc FloatLayout中,每个屏幕都是该根的子级。如果要将其仅添加到一个屏幕,则需要调用该特定屏幕的add_widgets函数。

一个选项是通过ID

更改kv文件,如下所示

        Screen:
            id: id_solverscreen
            name: "solverscreen"

更改py文件,如下所示

self.ids.id_solverscreen.add_widget(btn)

python文件

from kivy.app import App
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.button import Button
Window.size = (300,625)
window_x = Window.width
window_y = Window.height

Builder.load_file("main.kv")

class counter:
    def __init__(self):
        self.count = 2
    def increase(self):
        self.count += 1
b = counter()

class Calc(FloatLayout):
    def testbutton(self,instance):
        btn = Button(text = "testing123", color = (1,1,1,1),
                    size_hint =(.5,.05),
                    pos = (0,(window_y-(window_y*(.07+(b.count*.05)))))
                    )
        b.increase()
        self.ids.id_solverscreen.add_widget(btn)

    # define the multiplication of a function
    def calculate(self, instance):
        f = float(self.flow.text)
        p = float(self.pressure.text)
        t = float(self.temperature.text)
        sg = float(self.specific_gravity.text)
        self.acfm.text = str(f) #str(f1.ACFM(f,p,t,sg)) I commented this out for the purpose of posting this in my questions.

class test(App):
    def build(self):
        return Calc()

if __name__=="__main__":
    test().run()

kv文件

<calc>:
    flow: _flow
    pressure: _pressure
    temperature: _temperature
    specific_gravity: _specific_gravity
    acfm: _acfm
    FloatLayout:
        ScreenManager:
            id: screen_manager
            size: self.size
            Screen:
                name: "filescreen"
                FloatLayout:
                    canvas:
                        Color:
                            rgb: 1,1,1
                        Rectangle:
                            size: self.width, self.height
                            pos: self.pos
                    AnchorLayout:
                        anchor_x: 'center'
                        anchor_y: 'top'
                        Label:
                            canvas.before:
                                Color:
                                    rgb: 1,1,1
                                Rectangle:
                                    size: self.size
                                    pos: self.pos
                                Color:
                                    rgb: 0,0,0
                                Line:
                                    width: 1
                                    rectangle: self.x,self.y,self.width,self.height
                            size_hint: 1,.07
                    FilescreenButton:
                        text: "Create New File"
                        pos: 0,root.height-(root.height*(.07+.05))
                        on_press: root.testbutton(*args)
            Screen:
                id: id_solverscreen
                name: "solverscreen"
                GridLayout:
                    cols:1
                    size_hint: 1,1
                    ScrollView:
                        FloatLayout:
                            canvas:
                                Color:
                                    rgb: 1,1,1
                                Rectangle:
                                    size: self.width, self.height
                                    pos: self.pos
                            size_hint: 1,1.5
                            GridLayout:
                                cols:1
                                spacing: 1
                                pos_hint: {"top": (1),"left": 1}
                                size_hint: .4, None
                                row_default_height: root.height*.05
                                Label:
                                    text: "Inputs"
                                    color: 0,0,0,1
                                    canvas.before:
                                        Color:
                                            rgb: 1,1,1
                                        Rectangle:
                                            size: self.width,self.height
                                            pos: self.pos
                                CustomLabel:
                                    text: "Flow"
                                CustomLabel:
                                    text: "Pressure"
                                CustomLabel:
                                    text: "Temperature"
                                CustomLabel:
                                    text: "Specific Gravity"
                                Label:
                                    text: "Results"
                                    color: 0,0,0,1
                                    canvas.before:
                                        Color:
                                            rgb: 1,1,1
                                        Rectangle:
                                            size: self.width,self.height
                                            pos: self.pos
                                Button:
                                    text: "Calculate"
                                    on_press: root.calculate(*args)
                            GridLayout:
                                cols:1
                                spacing: 1
                                pos_hint: {"top": (1),"right": .7}
                                size_hint: .3, None
                                row_default_height: root.height*.05
                                Label:
                                    canvas.before:
                                        Color:
                                            rgb: 1,1,1
                                        Rectangle:
                                            size: self.width,self.height
                                            pos: self.pos
                                TextInput:
                                    text: "0"
                                    id: _flow
                                TextInput:
                                    text: "0"
                                    id: _pressure
                                TextInput:
                                    text: "0"
                                    id: _temperature
                                TextInput:
                                    text: ".6"
                                    id: _specific_gravity
                                Label:
                                    canvas.before:
                                        Color:
                                            rgb: 1,1,1
                                        Rectangle:
                                            size: self.width,self.height
                                            pos: self.pos
                                Label:
                                    id: _acfm
                                    color: 0,0,0,1
                                    canvas.before:
                                        Color:
                                            rgba: .7,.7,.7,1
                                        Rectangle:
                                            pos: self.pos
                                            size: self.size
                                        Color:
                                            rgb: 1,1,1
                                        Line:
                                            width: 1
                                            rectangle: self.x,self.y,self.width,self.height
                            GridLayout:
                                cols:1
                                spacing: 1
                                pos_hint: {"top": (1),"right": 1}
                                size_hint: .3, None
                                row_default_height: root.height*.05
                                Label:
                                    canvas.before:
                                        Color:
                                            rgb: 1,1,1
                                        Rectangle:
                                            size: self.width,self.height/2
                                            pos: self.pos
                                CustomButton:
                                    text: "MMSCFD"
                                CustomButton:
                                    text: "PSIG"
                                CustomButton:
                                    text: "F"
                                CustomButton:
                                    text: "SG"
                                Label:
                                    canvas.before:
                                        Color:
                                            rgb: 1,1,1
                                        Rectangle:
                                            size: self.width,self.height
                                            pos: self.pos
                                CustomButton:
                                    text: "ACFM"
        AnchorLayout:
            anchor_x: 'left'
            anchor_y: 'bottom'
            GridLayout:
                cols: 4
                size_hint: 1,.05
                canvas:
                    Color:
                        rgb: 1,1,1
                    Rectangle:
                        size: self.size
                        pos: self.pos
                Button:
                    text: "Files"
                    on_press: screen_manager.current = 'filescreen'
                Button:
                    text: "Solver"
                    on_press: screen_manager.current = 'solverscreen'
<CustomLabel@Label>:
    #font_size: (((self.width*5)+(self.height))/6)*.12
    canvas.before:
        Color:
            rgb: 0,0,0
        Rectangle:
            size: self.size
            pos: self.pos
<CustomButton@Button>:
    background_color: .25,.25,.25,1
    canvas.before:
        Color:
            rgba: .25,.25,.25,1
        Rectangle:
            size: self.size
            pos: self.pos
        Line:
            width: .09
            rectangle: self.x,self.y,self.width,self.height
<FilescreenButton@Button>:
    size_hint: .5,.05
    color: 0,0,0,1
    background_color: 1,1,1,0
    canvas:
        Color:
            rgb: 0,0,0
        Line:
            width: 1
            rectangle: self.x,self.y,self.width,self.height