【问题标题】:Add and remove Kivy Layout using CheckBox使用 CheckBox 添加和删除 Kivy 布局
【发布时间】:2021-08-25 18:14:44
【问题描述】:

我在 Kivy 中设置了一个 CheckBox,当勾选它时,会添加一个带有一些标签和 TextInputs 的布局小部件,但我希望它在未勾选该框时删除布局。勾选复选框会添加具有正确大小和位置的布局(在带有 CheckBox 的 GridLayout 下方,在 input_layout BoxLayout 内)但是当我取消勾选它时,布局不会消失。我检查了它是否会删除 input_layout 布局,它确实会删除,但不是通过 python 代码添加的。

取消选中该框时打印语句打印 False,因此我知道它工作正常,但 self.ids.input_layout.remove_widget(self.layout) 没有删除布局。

我尝试设置一个模板 GridLayout,然后通过 CheckBox 和 python 代码将标签和 TextInputs 添加到该模板中。此设置部分有效; Checkbox 会添加小部件,然后取消勾选它然后删除它们,但我无法再次添加它们,因为整个 GridLayout 都消失了。

其他复选框将添加/删除不同的布局,所以我的第一次设置尝试更理想,如果它真的可以工作的话。

更新:

使用问题的可运行示例更新代码。

Python

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.metrics import dp

Builder.load_file("process_data_example_design.kv")

class ProcessDataEx(BoxLayout):

    def add_layout(self, checkbox, value):
        self.layout = GridLayout(cols=2, rows=4, size_hint_y=None, height=self.height*0.275, spacing=dp(8), padding=dp(8))
        self.layout.add_widget(Label(text="Histogram particle label:", size_hint_x=None, width=self.width*0.33))
        self.layout.add_widget(TextInput())
        self.layout.add_widget(Label(text="Dumps to iterate:", size_hint_x=None, width=self.width*0.33))
        self.layout.add_widget(TextInput())
        self.layout.add_widget(Label(text="X-axis max:", size_hint_x=None, width=self.width*0.33))
        self.layout.add_widget(TextInput())
        self.layout.add_widget(Label(text="Y-axis max:", size_hint_x=None, width=self.width*0.33))
        self.layout.add_widget(TextInput())
        if value:
            self.ids.input_layout.add_widget(self.layout)
        else:
            self.ids.input_layout.remove_widget(self.layout)
            print(value)

class ProcessDataApp(App):
    def build(self):
        return ProcessDataEx()

if __name__ == '__main__':
    ProcessDataApp().run()

基维

#:kivy 2.0.0

<ProcessDataEx>:
    BoxLayout:
        orientation: 'vertical'
        BoxLayout:
            id: input_layout
            orientation: 'vertical'
            GridLayout:
                cols: 3
                rows: 2
                height: self.minimum_height
                spacing: dp(8)
                padding: dp(8)
                Label:
                    text: 'Move data'
                    size_hint_y: None
                    height: self.texture_size[1]
                    halign: 'right'
                Label:
                    text: 'Histograms'
                    size_hint_y: None
                    height: self.texture_size[1]
                    halign: 'right'
                Label:
                    text: 'Log Histograms'
                    size_hint_y: None
                    height: self.texture_size[1]
                    halign: 'right'
                CheckBox:
                    size_hint_y: None
                    height: root.height * 0.05
                CheckBox:
                    size_hint_y: None
                    height: root.height * 0.05
                CheckBox:
                    size_hint_y: None
                    height: root.height * 0.05
                    on_active: root.add_layout(*args)

【问题讨论】:

  • 能否添加一个简单的可运行示例
  • @HussamF.Alkdary 用可运行的示例更新了帖子中的代码

标签: python kivy kivy-language


【解决方案1】:

您犯的错误是每次调用add_layout 方法时都创建laoyut 的新实例,因此remove 小部件不起作用,因为input_layout 中不存在它的新小部件解决方案是创建布局时不存在所以 你的python代码应该是这样的

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.metrics import dp

Builder.load_file("process_data_example_design.kv")

class ProcessDataEx(BoxLayout):
    # initialize the layout variable
    layout=None
    def add_layout(self, checkbox, value):
        
        if value:
            self.layout = GridLayout(cols=2, rows=4, size_hint_y=None, height=self.height * 0.275, spacing=dp(8),
                                     padding=dp(8))
            self.layout.add_widget(Label(text="Histogram particle label:", size_hint_x=None, width=self.width * 0.33))
            self.layout.add_widget(TextInput())
            self.layout.add_widget(Label(text="Dumps to iterate:", size_hint_x=None, width=self.width * 0.33))
            self.layout.add_widget(TextInput())
            self.layout.add_widget(Label(text="X-axis max:", size_hint_x=None, width=self.width * 0.33))
            self.layout.add_widget(TextInput())
            self.layout.add_widget(Label(text="Y-axis max:", size_hint_x=None, width=self.width * 0.33))
            self.layout.add_widget(TextInput())
            self.ids.input_layout.add_widget(self.layout)
        else:
            self.ids.input_layout.remove_widget(self.layout)
            print(value)

class ProcessDataApp(App):
    def build(self):
        return ProcessDataEx()

if __name__ == '__main__':
    ProcessDataApp().run()


【讨论】:

    【解决方案2】:

    从你的逻辑来看,你可以给GridLayout一个id,然后使用clear_widgets()函数删除Layout里面的widget,这样只会删除widget而不是Layout

    提供身份证

    self.layout = GridLayout(id=layout_1,cols=2, rows=4, size_hint_y=None, height=self.height*0.275, spacing=dp(8), padding=dp(8))
    

    然后使用 clear_widgets() 函数删除小部件

            if value:
                self.ids.input_layout.add_widget(self.layout)
            else:
                self.input_layout.ids.layout_1.clear_widgets()
                print(value)
    

    另一个建议

    您可以在 kv 中完成,而不是通过 App 类创建布局及其子小部件

    您可以通过将 Layout 注册为 Factory 小部件来实现此目的, 因此,当您只需要添加该 Factory 对象时,不需要删除该 Factory 小部件

    一个简单的例子

    <layout_1@GridLayout>:
        cols:2
        rows:2
        Label:
            text:"hello"
    

    【讨论】:

    • 我试过这个,但当我试图删除它时,它无法识别GridLayoutid
    猜你喜欢
    • 2018-12-26
    • 2013-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-28
    相关资源
    最近更新 更多