如何从网格布局中删除特定行?从弹出窗口添加行

How to remove specific row from gridlayout? Rows are added from popup

我想使用删除按钮从网格布局中删除特定行。行在弹出窗口中创建。我能够向每一行添加删除按钮,但无法弄清楚如何在其中添加逻辑。

这是我试过的代码。我玩了一会儿。我尝试了很多方法,这就是我停止的地方。

Py.

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.popup import Popup
from kivy.uix.button import Button
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.properties import StringProperty, BooleanProperty, ObjectProperty
from kivy.uix.textinput import TextInput


class Row(BoxLayout):
    x1 = StringProperty('')
    x2 = StringProperty('')
    x3 = BooleanProperty(False)
    x4 = ObjectProperty()

    def __init__(self, x1, x2, x3, x4, **kwargs):
        super(Row, self).__init__(**kwargs)
        self.x1 = x1
        self.x2 = x2
        self.x3 = x3
        self.x4 = x4

    def remove_row(self):
        self.remove_widget(Row)

class MyPopup(Popup):
    pass


class MainScreen(Screen):
    pass

class SecondScreen(Screen):
    def fire_popup(self):
        pops = MyPopup()
        pops.open()


class ScreenManagement(ScreenManager):
    def changescreen(self, value):

        try:
            if value !='main':
                self.current = value
        except:
            print('No Screen named'+ value)




class testiApp(App):
    def build(self):
        self.title = 'Hello'

    def add_more(self, x1, x2, x3, x4):
        addbutton = self.root.get_screen('Page2').ids.empty
        addbutton.add_widget(Row(x1, x2, x3, x4))

    def remove(self):
        container = self.root.get_screen('Page2').ids.empty
        if len(container.children) > 0:
            container.remove_widget(container.children[0])

testiApp().run()

KV.


<MyPopup>:
    id:pop
    size_hint: .4, .4
    auto_dismiss: False
    title: 'XXX!!'
    BoxLayout:
        orientation:'vertical'
        BoxLayout:
            orientation:'horizontal'
            Label:
                text:'X1'
            TextInput:
                id: X1

            Label:
                text:'X2'
            TextInput:
                id:X2

            CheckBox:
                id:X3
            Button:
                id:X4
                text:'Delete'

        BoxLayout:
            orientation:'horizontal'
            Button:
                text:'Lisää'
                on_release: app.add_more(X1.text, X2.text, X3.active, X4)
            Button:
                text: 'Close'
                on_press: pop.dismiss()

<Row>:
    x1:''
    x2:''
    x3:False
    x4:

    Label:
        text: root.x1
    Label:
        text: root.x2
    CheckBox:
        active: root.x3
    Button:
        text:'poista'
        on_release: root.remove_row()


ScreenManagement:
    MainScreen:
        name:'Main'
    SecondScreen:
        name:'Page2'



<MainScreen>:
    name:'Main'
    BoxLayout:
        orientation:'vertical'
        GridLayout:
            id:container
            cols:2
            Label:
                text:'testfield1'
            TextInput:
                id: textfield1
            Label:
                text:'testfield2'
            TextInput:
                id: textfield2

        Button:
            text:'Next Page'
            on_release: app.root.current ='Page2'




<SecondScreen>:
    name:'Page2'


    BoxLayout:
        orientation:'vertical'
        BoxLayout:
            orientation:'vertical'
            Label:
                text:'Popup Test'
            ScrollView:
                bar_width: 5
                bar_color: 1,0,0,1 #red
                bar_inactive_color: 0,0,1,1 #blue
                effect_cls: 'ScrollEffect'
                scroll_type:['bars','content']
                GridLayout:
                    orientation: "vertical"
                    size_hint_y: None
                    height: self.minimum_height
                    row_default_height: 60
                    cols:1
                    id:empty
            BoxLayout:
                Button:
                    text:'Open Popup'
                    on_press: root.fire_popup()

                Button:
                    text:'remove'
                    on_release: app.remove()



问题 2 - 确认删除的弹出消息

... want that Poista(Delete) button to open popup asking " are you sure? Yes or No" How should i bind the remove_row?

解决方案

kv 文件

  • 创建 class 规则,<ConfirmDeleteRow>: 继承 Popup 小部件
  • Popup 小部件的内容是一个 Label 小部件,文本为 'Are you sure?',两个 Button 小部件,文本为 'Yes',和 'No'分别。
  • 使用on_release事件绑定'Yes'按钮调用remove_row()方法
  • 使用on_release事件绑定两个按钮以通过调用dismiss()方法关闭弹出窗口window
  • 绑定delete按钮调用新方法,confirm_delete()

片段 - kv 文件

<ConfirmDeleteRow>:    # class rule
    size_hint: .4, .4
    auto_dismiss: False
    title: 'Delete'

    BoxLayout:    # content
        orientation:'vertical'
        Label:
            text: 'Are you sure?'
        BoxLayout:
            size_hint: 1, 0.2
            Button:
                text: 'Yes'
                on_release:
                    root.dismiss()
                    root.row.remove_row()
            Button:
                text: 'No'
                on_release:
                    root.dismiss()
...


<Row>:
    x1:''
    ...
    Button:
        text:'poista'
        on_release: root.confirm_delete()

Py文件

  • 使用新的 class 属性 row = ObjectProperty(None) 和接受附加参数的构造函数 row
  • 实现 class ConfirmDeleteRow()
  • 实现一个新方法,confirm_delete()实例化ConfirmDeleteRow()并传递self(即行)作为参数

片段 - py 文件

class ConfirmDeleteRow(Popup):
    row = ObjectProperty(None)

    def __init__(self, row, **kwargs):
        super(ConfirmDeleteRow, self).__init__(**kwargs)
        self.row = row    # save row object


class Row(BoxLayout):
    ...

    def confirm_delete(self):
        confirm_delete_row = ConfirmDeleteRow(self)   # pass self / row object
        confirm_delete_row.open()

问题 1 - 删除特定行

... would like to remove specific row from the gridlayout with delete button

解决方案

当按下按钮 'poista'(删除)时,remove_row() 方法中的 self 指的是 Row 中该特定行的实例化对象 ScrollView。因此,要删除该特定行,您必须引用其父级才能从父级中删除 it/child。

self.remove_widget(Row)替换为self.parent.remove_widget(self)

片段

def remove_row(self):
    self.parent.remove_widget(self)

输出