Issue
Good day guys,
Please am new to python and I have a little project am working on. The project generates input field base on barcode scanned, and each input field has a unique id. Now my challenge is how can I bind or pass the instance of a particular input field to a function or get the ID of the input field currently been modified secondly when you click on the remove product I want the product attach to the button to be removed
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()
Solution
Here is a modified version of your code that allows you to delete the product and gets the id
string of the input field and uses that to access the text:
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()
I have added a ProductLayout
class that contains all the widgets for a product. That allows easy removal. And when each instance of ProductLayout
is created, the ids
are added to the ids
dictionary of the Windows
Screen
. The on_text()
or on_focus()
methods can be used to access the text fields and their contained text.
Still don't understand the purpose of the dynamic_ids
, but I left that code in.
Answered By - John Anderson
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.