如何获取 ID 以及如何在没有 Kivy 文件的情况下绑定 Kivymd 输入字段

How to Get ID and How to Bind Kivymd Input Field without Kivy file

大家好,

请是 python 的新手,我有一个小项目正在进行中。 该项目根据扫描的条形码生成输入字段,每个输入字段都有一个唯一的 id。现在我的挑战是如何将特定输入字段的实例绑定或传递给函数或获取当前修改的输入字段的 ID 其次,当您单击删除产品时,我希望删除附加到按钮的产品

from kivy.lang import Builder
from kivy.factory import Factory

from kivymd.app import MDApp

from kivy.uix.screenmanager import Screen

from kivymd.uix.textfield import MDTextField
from kivymd.uix.button import MDRectangleFlatButton
import weakref

from kivy.properties import DictProperty
from kivy.properties import ObjectProperty

Builder.load_string(
    """
<Windows>:
    ScrollView:
        MDBoxLayout:
            orientation: 'vertical'
            padding: '48dp'
            spacing: '15dp'
            size_hint_y: None
            height: self.minimum_height
            id: data_layout
            
            MDRaisedButton:
                text: "open_window 2"
                on_release: root.opener()
"""
)
    
class Windows(Screen):
    got_txt = ObjectProperty()
    dynamic_ids = DictProperty({})
    
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

    
    def opener(self):
        #print(window_id)
        #self.layout = GridLayout(cols = 5, row_force_default=True, row_default_height=40)
        #window_id.open()
        #self.table()
        self.read_barcodes()
        
    def build(self):
        self.root = Factory.Windows()
    
    def read_barcodes(self):
        
        barcode = ['sfdfdf','fdfdfdfd','sdfdfd']
        
        for barcode_info in barcode:
            #d =str( str(len(self.tables_data) + 1) + '',''+barcode_info)
            #self.tables_data.append('('+barcode_info+')')
            product_code_id = barcode_info + "_product_code"
            product_name_id = barcode_info + "_product_name"
            product_qty_id = barcode_info + "_product_qty"
            product_price_id = barcode_info + "_product_price"
            product_amount_id = barcode_info + "_product_amount"
            
            
            product_code = MDTextField(mode= "rectangle", text=str(barcode_info), readonly=True, opacity=0)
            self.ids.data_layout.add_widget(product_code)
            # We'll use a weak ref to add our dynamic id 
            self.ids[product_code_id] = weakref.ref(product_code)
            self.dynamic_ids[id] = product_code_id
            
            product_name = MDTextField(hint_text="Product Name",mode= "rectangle", text=str(barcode_info), readonly=True)
            #product_name.bind(on_focus=self.focusedInpute())
            self.ids.data_layout.add_widget(product_name)
            # We'll use a weak ref to add our dynamic id 
            self.ids[product_name_id] = weakref.ref(product_name)
            self.dynamic_ids[id] = product_name_id
            
            
            product_qty = MDTextField(hint_text="qty",mode= "rectangle", text=str(1))
            self.ids.data_layout.add_widget(product_qty)
            # We'll use a weak ref to add our dynamic id 
            self.ids[product_qty_id] = weakref.ref(product_qty)
            self.dynamic_ids[id] = product_qty_id
            
            product_price = MDTextField(hint_text="U.Price",mode= "rectangle",text=str(200))
            self.ids.data_layout.add_widget(product_price)
            # We'll use a weak ref to add our dynamic id 
            self.ids[product_price_id] = weakref.ref(product_price)
            self.dynamic_ids[id] = product_price_id
            
            product_amount = MDTextField(hint_text="Amount",mode= "rectangle", text=str(200))
            self.ids.data_layout.add_widget(product_amount)
            # We'll use a weak ref to add our dynamic id 
            self.ids[product_amount_id] = weakref.ref(product_amount)
            
            self.ids.data_layout.add_widget(MDRectangleFlatButton(text ="Remove Product"))
            
            #self.ids.data_layout.add_widget(layout) , on_release=self.Remove_line(barcode_info)
            
            #self.Reload_Table()
            
            print("The id is " + str(self.ids[product_code_id]))
            
            #print("The text is " + str(self.ids[product_code_id].text))
            
            self.scaned = barcode_info
            
            print(self.dynamic_ids)
            
    def Remove_line(self, widgets):
        print('hi')
        #self.ids.data_layout.remove_widget(widgets)
        #self.ids.data_layout.remove_widget(self.ids[widgets + "_product_code"])
        #self.ids.data_layoutr.emove_widget(self.ids[widgets + "_product_name"])
        #self.ids.data_layout.remove_widget(self.ids[widgets + "_product_qty"])
        #self.ids.data_layoutr.remove_widget(self.ids[widgets + "_product_price"])
        #self.ids.data_layoutr.remove_widget(self.ids[widgets + "_product_amount"])
        #remove_widget()
        
        
        
    def focusedInpute(self,insatnce, value):
        #print(self)
       # print(value)
        if not value:   # defocused
            print(value)

class MainApp(MDApp):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)


    def build(self):
        self.root = Factory.Windows()
    


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

这是您的代码的修改版本,它允许您删除产品并获取输入字段的 id 字符串并使用它来访问文本:

from kivy.lang import Builder
from kivy.factory import Factory
from kivy.uix.boxlayout import BoxLayout
from kivymd.app import MDApp
from kivy.uix.screenmanager import Screen
from kivy.properties import DictProperty, StringProperty
from kivy.properties import ObjectProperty

Builder.load_string(
"""
<Windows>:
    ScrollView:
        MDBoxLayout:
            orientation: 'vertical'
            size_hint_y: None
            height: self.minimum_height
            id: data_layout

            MDRaisedButton:
                text: "open_window 2"
                pos_hint: {'center_x':0.5}
                on_release: root.opener()
                
<ProductLayout>:
    orientation: 'vertical'
    padding: '48dp'
    spacing: '15dp'
    size_hint_y: None
    height: self.minimum_height
    MDTextField:
        id: product_code
        mode: "rectangle"
        text: root.barcode_info
        readonly: True
        size_hint_y: None
        height: 0
        opacity: 0
    MDTextField:
        id: product_name
        hint_text: "Product Name"
        mode: "rectangle"
        text: root.barcode_info
        readonly: True
    MDTextField:
        sid: root.barcode_info + '_product_qty'
        id: product_qty
        hint_text: "qty"
        mode: "rectangle"
        text: str(1)
        on_text: root.text_changed(product_qty)
        on_focus: root.focus_changed(product_qty)
    MDTextField:
        sid: root.barcode_info + '_product_price'
        id: product_price
        hint_text: "U.Price"
        mode: "rectangle"
        text: str(200)
        on_text: root.text_changed(product_price)
        on_focus: root.focus_changed(product_price)
    MDTextField:
        sid: root.barcode_info + '_product_amount'
        id: product_amount
        hint_text: "Amount"
        mode: "rectangle"
        text: str(200)
        on_text: root.text_changed(product_amount)
        on_focus: root.focus_changed(product_amount)
    MDRectangleFlatButton:
        text: "Remove Product"
        on_release: root.parent.remove_widget(root)
"""
)


class ProductLayout(BoxLayout):
    barcode_info = StringProperty('')

    def text_changed(self, mdtf):
        # this gets called on every text change
        print('text changed for', self.barcode_info, ':')
        print('\t', mdtf.sid)
        print('\t', MDApp.get_running_app().root.ids[mdtf.sid].text)

    def focus_changed(self, mdtf):
        if not mdtf.focus:
            # this is run only when the text field loses focus
            print('focus changed to', mdtf.focus)
            print('\t', mdtf.sid)
            print('\t', MDApp.get_running_app().root.ids[mdtf.sid].text)


class Windows(Screen):
    got_txt = ObjectProperty()
    dynamic_ids = DictProperty({})

    def __init__(self, **kwargs):
        super().__init__(**kwargs)

    def opener(self):
        # print(window_id)
        # self.layout = GridLayout(cols = 5, row_force_default=True, row_default_height=40)
        # window_id.open()
        # self.table()
        self.read_barcodes()

    def build(self):
        self.root = Factory.Windows()

    def read_barcodes(self):

        barcode = ['sfdfdf', 'fdfdfdfd', 'sdfdfd']

        for barcode_info in barcode:
            # d =str( str(len(self.tables_data) + 1) + '',''+barcode_info)
            # self.tables_data.append('('+barcode_info+')')
            product_code_id = barcode_info + "_product_code"
            product_name_id = barcode_info + "_product_name"
            product_qty_id = barcode_info + "_product_qty"
            product_price_id = barcode_info + "_product_price"
            product_amount_id = barcode_info + "_product_amount"

            product_layout = ProductLayout(barcode_info=barcode_info)
            self.ids.data_layout.add_widget(product_layout)

            self.ids[product_code_id] = product_layout.ids.product_code
            self.dynamic_ids[id] = product_code_id

            self.ids[product_name_id] = product_layout.ids.product_name
            self.dynamic_ids[id] = product_name_id

            self.ids[product_qty_id] = product_layout.ids.product_qty
            self.dynamic_ids[id] = product_qty_id

            self.ids[product_price_id] = product_layout.ids.product_price
            self.dynamic_ids[id] = product_price_id

            self.ids[product_amount_id] = product_layout.ids.product_amount

            self.scaned = barcode_info

        print('dynamic ids:\n', self.dynamic_ids)
        print('ids:\n', self.ids)

    def Remove_line(self, widgets):
        print('hi')
        # self.ids.data_layout.remove_widget(widgets)
        # self.ids.data_layout.remove_widget(self.ids[widgets + "_product_code"])
        # self.ids.data_layoutr.emove_widget(self.ids[widgets + "_product_name"])
        # self.ids.data_layout.remove_widget(self.ids[widgets + "_product_qty"])
        # self.ids.data_layoutr.remove_widget(self.ids[widgets + "_product_price"])
        # self.ids.data_layoutr.remove_widget(self.ids[widgets + "_product_amount"])
        # remove_widget()

    def focusedInpute(self, insatnce, value):
        # print(self)
        # print(value)
        if not value:  # defocused
            print(value)


class MainApp(MDApp):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

    def build(self):
        return Windows()


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

我添加了一个 ProductLayout class,其中包含产品的所有小部件。这样可以轻松移除。当 ProductLayout 的每个实例被创建时,ids 被添加到 Windows Screenids 字典中。 on_text()on_focus() 方法可用于访问文本字段及其包含的文本。

仍然不明白 dynamic_ids 的用途,但我把那段代码留在了里面。