【问题标题】:How to Get ID and How to Bind Kivymd Input Field without Kivy file如何获取 ID 以及如何在没有 Kivy 文件的情况下绑定 Kivymd 输入字段
【发布时间】:2022-01-24 10:34:20
【问题描述】:

大家好,

请是 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()

【问题讨论】:

  • 谢谢,我已将代码修改为可运行的sn-p。 @约翰安德森
  • 那仍然不是minimal。请修改您的示例以消除使用pyzbar 和条形码扫描。无论这些事情在哪里完成,都只是制造虚假结果。
  • 又修改了@JohnAnderson
  • 代码self.dynamic_ids[id] = product_code_id中的id是什么?

标签: python python-3.x kivy kivymd


【解决方案1】:

这是您的代码的修改版本,允许您删除产品并获取输入字段的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 类,其中包含产品的所有小部件。这样可以轻松移除。并且当ProductLayout 的每个实例被创建时,ids 被添加到WindowsScreenids 字典中。 on_text()on_focus() 方法可用于访问文本字段及其包含的文本。

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

【讨论】:

  • 非常感谢@johnanderson 我要实现的是,添加产品后,该产品的数量是否被修改,我想将被修改的文本字段的ID传递给函数作为回报,这将帮助我重新计算该产品的数量。这就是为什么我试图存储和访问他们的 ID。因为有了 ID,我可以获取单价并更新该特定产品。
猜你喜欢
  • 2020-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-12
  • 2022-01-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多