【问题标题】:How to Dynamically add a button from the .py file to a single screen of a screen manager in .kv file如何将 .py 文件中的按钮动态添加到 .kv 文件中屏幕管理器的单个屏幕
【发布时间】:2020-01-22 12:34:43
【问题描述】:

如何将按钮动态添加到 .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 文件的一个屏幕。

【问题讨论】:

    标签: python json dynamic kivy


    【解决方案1】:

    您当前正在将其添加到作为根的 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
    

    【讨论】:

    • 这完美地解决了我的问题。谢谢!
    猜你喜欢
    • 2021-09-20
    • 2019-04-22
    • 1970-01-01
    • 2021-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多