My target is like
I am choosing an option from the recycle view list from button 1, after choosing the option, then I am choosing from button 2,now the display must not show the choosed value in button 1(previously choosed option must be removed from recycle view 2). More over the button text must be updated to the choosed value text.
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.screenmanager import ScreenManager,Screen,SlideTransition,FadeTransition
from kivy.uix.checkbox import CheckBox
from kivy.properties import ObjectProperty, NumericProperty, BooleanProperty,ListProperty,StringProperty
from kivy.uix.dropdown import DropDown
from kivy.uix.button import Button
from kivy.base import runTouchApp
from kivy.uix.behaviors import FocusBehavior
from kivy.uix.recycleboxlayout import RecycleBoxLayout
from kivy.uix.recycleview import RecycleView
from kivy.uix.recycleview.layout import LayoutSelectionBehavior
from kivy.uix.recycleview.views import RecycleDataViewBehavior
alph = ['a','b','c','d','e','f','g','h','i']
val1_chsd = None
val2_chsd = None
class Screen3(Screen):
#pass
labeltext = StringProperty('My selection')
def buttontype(self,types):
global buttonval
print("type called :",types)
if types is "button1":
buttonval = "selection1"
print ('value set 1',buttonval)
elif types is "button2":
buttonval = "selection2"
print ('value set 2',buttonval)
def setvalueselected(self,sel_value):
print("Selected value is",sel_value)
global val1_chsd
global val2_chsd
if buttonval is "selection1":
val1_chsd = sel_value
val1_name = sel_value
print("choosed no. 1",val1_name)
if buttonval is "selection2":
val2_chsd = sel_value
val2_name = sel_value
print("choosed no. 2",val2_name)
def printselected(self):
print("abcdef",val1_chsd,val2_chsd)
if val1_chsd != None and val2_chsd != None:
selected = val1_chsd + '\n' + val2_chsd
print ("choosed : ",selected)
self.labeltext = selected
else:
print ("Choose all values")
class Screen4(Screen):
list = ListProperty([])
class Screen5(Screen):
list = ListProperty([])
class ScreenManagement(ScreenManager):
pass
class SelectableRecycleBoxLayout(FocusBehavior, LayoutSelectionBehavior,
RecycleBoxLayout):
''' Adds selection and focus behaviour to the view. '''
class RVval1(RecycleView):
def __init__(self, **kwargs):
super(RVval1, self).__init__(**kwargs)
#print('removedval:', value2_chsd)
self.data = [{'text': str(x)} for x in alph]
class RVval2(RecycleView):
def __init__(self, **kwargs):
super(RVval2, self).__init__(**kwargs)
print('removedval:', val1_chsd)
self.data = [{'text': str(x)} for x in alph]
class SelectableLabel(RecycleDataViewBehavior, Label):
''' Add selection support to the Label '''
index = None
selected = BooleanProperty(False)
selectable = BooleanProperty(True)
sc3 = Screen3()
def refresh_view_attrs(self, rv, index, data):
''' Catch and handle the view changes '''
self.index = index
return super(SelectableLabel, self).refresh_view_attrs(
rv, index, data)
def on_touch_down(self, touch):
''' Add selection on touch down '''
if super(SelectableLabel, self).on_touch_down(touch):
return Truej
if self.collide_point(*touch.pos) and self.selectable:
return self.parent.select_with_touch(self.index, touch)
def apply_selection(self, rv, index, is_selected):
''' Respond to the selection of items in the view. '''
self.selected = is_selected
if is_selected:
print("selection changed to {0}".format(rv.data[index]))
valueselected = format(rv.data[index])
valueselected = valueselected.replace("{'text': '","")
valueselected = valueselected.replace("'}","")
print("valueselected : ",valueselected)
self.sc3.setvalueselected(valueselected)
else:
print("selection removed for {0}".format(rv.data[index]))
presentation = Builder.load_file('dfive2.kv')
class DfiveZApp(App):
def build(self):
return presentation
if __name__ == '__main__':
DfiveZApp().run()
Kivy file
#:import SlideTransition kivy.uix.screenmanager.SlideTransition
ScreenManagement:
id:screenmgr
Screen3:
id: screen_3
name : "screen3"
manager: screenmgr
Screen4:
id: rv_screen_val1
name : "screen4"
Screen5:
id: rv_screen_val2
name : "screen5"
<Screen3>:
BoxLayout:
orientation: "vertical"
BoxLayout:
orientation: "vertical"
#size_hint_y: 1
GridLayout:
cols: 2
size_hint_y: 2
Label:
text:"Value1"
Button:
id: val1_name
text: 'val1'
on_press:
root.buttontype('button1')
app.root.transition = SlideTransition(direction='left')
app.root.current = 'screen4'
Label:
text:"Value2"
Button:
id: val2_name
text: 'val2'
on_press:
root.buttontype('button2')
app.root.transition = SlideTransition(direction='left')
app.root.current = 'screen5'
BoxLayout:
Label:
text:root.labeltext
Button:
text: 'Submit'
on_press:
root.printselected()
#app.root.transition = SlideTransition(direction='left')
<SelectableLabel>:
# Draw a background to indicate selection
canvas.before:
Color:
rgba: (.0, 0.9, .1, .3) if self.selected else (0, 0, 0, 1)
Rectangle:
pos: self.pos
size: self.size
<RVval1>:
viewclass: 'SelectableLabel'
SelectableRecycleBoxLayout:
default_size: None, dp(56)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
multiselect: False
touch_multiselect: False
<RVval2>:
viewclass: 'SelectableLabel'
SelectableRecycleBoxLayout:
default_size: None, dp(56)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
multiselect: False
touch_multiselect: False
<Screen4>:
BoxLayout:
list: rv_list_val1
orientation: "vertical"
RVval1:
id: rv_list_val1
Button:
text: 'Previous screen'
size_hint: None, None
size: 150, 50
#on_press: root.SetText()
on_release:
#root.manager.current = root.manager.previous()
app.root.transition = SlideTransition(direction='right')
app.root.current = 'screen3'
<Screen5>:
BoxLayout:
list: rv_list_val2
orientation: "vertical"
RVval2:
id: rv_list_val2
Button:
text: 'Previous screen'
size_hint: None, None
size: 150, 50
#on_press: root.SetText()
on_release:
#root.manager.current = root.manager.previous()
app.root.transition = SlideTransition(direction='right')
app.root.current = 'screen3'
You can create a method to reload the data on the second step and set a string property on the view.
.py file
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.screenmanager import ScreenManager,Screen,SlideTransition,FadeTransition
from kivy.uix.checkbox import CheckBox
from kivy.properties import ObjectProperty, NumericProperty, BooleanProperty,ListProperty,StringProperty
from kivy.uix.dropdown import DropDown
from kivy.uix.button import Button
from kivy.base import runTouchApp
from kivy.uix.behaviors import FocusBehavior
from kivy.uix.recycleboxlayout import RecycleBoxLayout
from kivy.uix.recycleview import RecycleView
from kivy.uix.recycleview.layout import LayoutSelectionBehavior
from kivy.uix.recycleview.views import RecycleDataViewBehavior
alph = ['a','b','c','d','e','f','g','h','i']
sel_values1 = []
val1_chsd = None
val2_chsd = None
class Screen3(Screen):
#pass
labeltext = StringProperty('My selection')
val1 = StringProperty('val1')
val2 = StringProperty('val2')
def buttontype(self,types):
global buttonval
print("type called :",types)
if types is "button1":
buttonval = "selection1"
print ('value set 1',buttonval)
elif types is "button2":
buttonval = "selection2"
print ('value set 2',buttonval)
def setvalueselected(self,sel_value):
print("Selected value is",sel_value)
global val1_chsd
global val2_chsd
if buttonval is "selection1":
val1_chsd = sel_value
val1_name = sel_value
print("choosed no. 1",val1_name)
self.val1 = val1_name
if buttonval is "selection2":
val2_chsd = sel_value
val2_name = sel_value
print("choosed no. 2",val2_name)
self.val2 = val2_name
def printselected(self):
print("abcdef",val1_chsd,val2_chsd)
if val1_chsd != None and val2_chsd != None:
selected = val1_chsd + '\n' + val2_chsd
print ("choosed : ",selected)
self.labeltext = selected
else:
print ("Choose all values")
class Screen4(Screen):
list = ListProperty([])
class Screen5(Screen):
list = ListProperty([])
class ScreenManagement(ScreenManager):
pass
class SelectableRecycleBoxLayout(FocusBehavior, LayoutSelectionBehavior,
RecycleBoxLayout):
''' Adds selection and focus behaviour to the view. '''
class RVval1(RecycleView):
def __init__(self, **kwargs):
super(RVval1, self).__init__(**kwargs)
#print('removedval:', value2_chsd)
self.data = [{'text': str(x)} for x in alph]
class RVval2(RecycleView):
def __init__(self, **kwargs):
super(RVval2, self).__init__(**kwargs)
print('removedval:', val1_chsd)
self.data = [{'text': str(x)} for x in alph]
def reload_data(self):
self.data = [{'text': str(x)} for x in alph if x not in sel_values1]
class SelectableLabel(RecycleDataViewBehavior, Label):
''' Add selection support to the Label '''
index = None
selected = BooleanProperty(False)
selectable = BooleanProperty(True)
sc3 = Screen3()
def refresh_view_attrs(self, rv, index, data):
''' Catch and handle the view changes '''
self.index = index
return super(SelectableLabel, self).refresh_view_attrs(
rv, index, data)
def on_touch_down(self, touch):
''' Add selection on touch down '''
if super(SelectableLabel, self).on_touch_down(touch):
return Truej
if self.collide_point(*touch.pos) and self.selectable:
return self.parent.select_with_touch(self.index, touch)
def apply_selection(self, rv, index, is_selected):
''' Respond to the selection of items in the view. '''
self.selected = is_selected
if is_selected:
print("selection changed to {0}".format(rv.data[index]))
valueselected = format(rv.data[index])
valueselected = valueselected.replace("{'text': '","")
valueselected = valueselected.replace("'}","")
print("valueselected : ",valueselected)
print(hasattr(rv, "RVval1"))
if (rv.name == "RVval1"):
sel_values1.append(valueselected)
app = App.get_running_app()
app.root.ids['screen_3'].setvalueselected(valueselected)
app.root.ids['rv_screen_val2'].ids['rv_list_val2'].reload_data()
else:
print("selection removed for {0}".format(rv.data[index-1]))
presentation = Builder.load_file('dfive2.kv')
class DfiveZApp(App):
def build(self):
return presentation
if __name__ == '__main__':
DfiveZApp().run()
.kv file
#:import SlideTransition kivy.uix.screenmanager.SlideTransition
ScreenManagement:
id:screenmgr
Screen3:
id: screen_3
name : "screen3"
manager: screenmgr
Screen4:
id: rv_screen_val1
name : "screen4"
Screen5:
id: rv_screen_val2
name : "screen5"
<Screen3>:
BoxLayout:
orientation: "vertical"
BoxLayout:
orientation: "vertical"
#size_hint_y: 1
GridLayout:
cols: 2
size_hint_y: 2
Label:
text:"Value1"
Button:
id: val1_name
text: root.val1
on_press:
root.buttontype('button1')
app.root.transition = SlideTransition(direction='left')
app.root.current = 'screen4'
Label:
text:"Value2"
Button:
id: val2_name
text: root.val2
on_press:
root.buttontype('button2')
app.root.transition = SlideTransition(direction='left')
app.root.current = 'screen5'
BoxLayout:
Label:
text:root.labeltext
Button:
text: 'Submit'
on_press:
root.printselected()
#app.root.transition = SlideTransition(direction='left')
<SelectableLabel>:
# Draw a background to indicate selection
canvas.before:
Color:
rgba: (.0, 0.9, .1, .3) if self.selected else (0, 0, 0, 1)
Rectangle:
pos: self.pos
size: self.size
<RVval1>:
viewclass: 'SelectableLabel'
SelectableRecycleBoxLayout:
default_size: None, dp(56)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
multiselect: False
touch_multiselect: False
<RVval2>:
viewclass: 'SelectableLabel'
SelectableRecycleBoxLayout:
default_size: None, dp(56)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
multiselect: False
touch_multiselect: False
<Screen4>:
BoxLayout:
list: rv_list_val1
orientation: "vertical"
RVval1:
id: rv_list_val1
name: 'RVval1'
Button:
text: 'Previous screen'
size_hint: None, None
size: 150, 50
#on_press: root.SetText()
on_release:
#root.manager.current = root.manager.previous()
app.root.transition = SlideTransition(direction='right')
app.root.current = 'screen3'
<Screen5>:
BoxLayout:
list: rv_list_val2
orientation: "vertical"
RVval2:
id: rv_list_val2
name: 'RVval2'
Button:
text: 'Previous screen'
size_hint: None, None
size: 150, 50
#on_press: root.SetText()
on_release:
#root.manager.current = root.manager.previous()
app.root.transition = SlideTransition(direction='right')
app.root.current = 'screen3'
Related
So i am having trouble trying to set my button text from another class.
if you look at the function set_people, i use PosScreen.people = name to change the name, but the button text wont change. So i figured i have to acccess it via ids but im stuck on how to do it from another class. Here is my code:
test.py
from kivy.properties import StringProperty
from kivy.uix.boxlayout import BoxLayout
from kivymd.app import MDApp
from kivy.uix.screenmanager import ScreenManager, Screen
from kivymd.uix.button import MDFlatButton
from kivymd.uix.dialog import MDDialog
pos_dialog = None
class PosScreen(Screen):
people = StringProperty("")
def __init__(self, **kwargs):
super(PosScreen, self).__init__(**kwargs)
def on_pre_enter(self, *args):
self.people = "No one"
def close_dialog(self, *obj):
global pos_dialog
pos_dialog.dismiss()
pos_dialog = None
def open_people_dialog(self):
global pos_dialog
if not pos_dialog:
pos_dialog = MDDialog(
title="Choose customer",
type="custom",
content_cls=DialogContentPosAddPeople(),
buttons=[
MDFlatButton(
text="Close",
theme_text_color="Custom",
on_release=self.close_dialog
)
]
)
pos_dialog.open()
class DialogContentPosAddPeople(BoxLayout):
def __init__(self, **kwargs):
super(DialogContentPosAddPeople, self).__init__(**kwargs)
self.set_list_people()
def set_list_people(self, text="", search=False):
peeps = ["Brian", "AJ", "Nick", "Kevin", "Howie"]
def add_name_item(name):
self.ids.rv.data.append(
{
"viewclass": "OneLineListItem",
"text": name,
"on_release": lambda x=name: self.set_people(x),
}
)
self.ids.rv.data = []
for name in peeps:
if search:
if text.lower() in name.lower():
add_name_item(name)
else:
add_name_item(name)
def set_people(self, name):
global pos_dialog
PosScreen.people = name # it changes the variable but button text doesn't change
PosScreen.ids.people_button.text = name # Not accessible NoneType
pos_dialog.dismiss()
pos_dialog = None
return
class testApp(MDApp):
def build(self):
self.theme_cls.primary_palette = "Teal"
sm = ScreenManager()
sm.add_widget(PosScreen(name="pos"))
return sm
if __name__ == "__main__":
testApp().run()
test.kv
PosScreen:
<PosScreen>:
name: "pos"
people_button: people_button
canvas.before:
Color:
rgba: 72/255, 72/255, 72/255, 1
Rectangle:
pos: self.pos
size: self.size
MDBoxLayout:
orientation: "vertical"
RelativeLayout:
orientation: "vertical"
MDRectangleFlatIconButton:
id: people_button
icon: "account-circle-outline"
text: root.people
pos_hint:{'x': 0.05, 'center_y': 0.9}
md_bg_color: 0, 0, 0, 1
on_release: root.open_people_dialog()
<DialogContentPosAddPeople>:
rv: rv
orientation: "vertical"
spacing: dp(10)
padding: dp(20)
size_hint_y: None
height: "240dp"
MDBoxLayout:
adaptive_height: True
MDIconButton:
icon: 'magnify'
MDTextField:
id: search_field
hint_text: 'Search name'
on_text: root.set_list_people(self.text, True)
RecycleView:
id: rv
key_viewclass: 'viewclass'
key_size: 'height'
RecycleBoxLayout:
padding: dp(10)
default_size: None, dp(48)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
Expected result: When I click one of the names, it will close the dialog and change the button's text to the name that i picked
Can someone help me shed some light on how can I achieve this?
So i solved it by passing the screen object when calling the second class.
class PosScreen(Screen):
...
def open_people_dialog(self):
global pos_dialog
if not pos_dialog:
pos_dialog = MDDialog(
...
content_cls=DialogContentPosAddPeople(self), # Added self here
...
)
]
)
pos_dialog.open()
and in the called class:
class DialogContentPosAddPeople(BoxLayout):
def __init__(self, master, **kwargs): # Added master
super(DialogContentPosAddPeople, self).__init__(**kwargs)
self.master = master
def set_people(self, name):
self.master.people = name #Referencing the master
self.master.ids.people_button.text = name
I want to display a table in one of the screen and the displayed data in the table should come from the loan database, loan table.
I have created the database and also there is no error which is being shown. The table is created but there is no data displayed on it.Its empty table.
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
import json
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.properties import BooleanProperty, ListProperty, StringProperty, ObjectProperty
from kivy.uix.recyclegridlayout import RecycleGridLayout
from kivy.uix.behaviors import FocusBehavior
from kivy.uix.recycleview.layout import LayoutSelectionBehavior
from kivy.uix.popup import Popup
from loandatabase import Database
database = Database()
Builder.load_file('design.kv')
class MainScreen(Screen):
def goto_admin_page(self):
self.manager.current = "adminfirst_screen"
def goto_agent_page(self):
pass
def goto_customer_page(self):
pass
class AdminScreenFirst(Screen):
def go_to_adminsecond(self,uname,pword):
with open("users.json") as file:
users =json.load(file)
if uname in users and users[uname]['password'] == pword:
self.manager.current = "adminsecond_screen"
else:
self.ids.login_wrong.text = "Invalid Credentials.Please Contact the administrator"
class AdminScreenSecond(Screen):
def go_to_adminpending(self):
self.manager.current = "adminPending_screen"
def go_to_adminapproved(self):
self.manager.current = "adminsecond_screen"
def go_to_adminrejected(self):
self.manager.current = "adminsecond_screen"
class AdminPendingScreen(Screen):
def display(self):
self.manager.current = "rv_screen"
class RV(Screen):
data_items = ListProperty([])
def __init__(self, **kwargs):
super(RV, self).__init__(**kwargs)
for row in database.view():
for col in row:
self.data_items.append(col)
class TextInputPopup(Popup):
obj = ObjectProperty(None)
obj_text = StringProperty("")
def __init__(self, obj, **kwargs):
super(TextInputPopup, self).__init__(**kwargs)
self.obj = obj
self.obj_text = obj.text
class SelectableRecycleGridLayout(FocusBehavior, LayoutSelectionBehavior,
RecycleGridLayout):
''' Adds selection and focus behaviour to the view. '''
class SelectableButton(RecycleDataViewBehavior, Button):
''' Add selection support to the Label '''
index = None
selected = BooleanProperty(False)
selectable = BooleanProperty(True)
def refresh_view_attrs(self, rv, index, data):
''' Catch and handle the view changes '''
self.index = index
return super(SelectableButton, self).refresh_view_attrs(
rv, index, data)
def on_touch_down(self, touch):
''' Add selection on touch down '''
if super(SelectableButton, self).on_touch_down(touch):
return True
if self.collide_point(*touch.pos) and self.selectable:
return self.parent.select_with_touch(self.index, touch)
def apply_selection(self, rv, index, is_selected):
''' Respond to the selection of items in the view. '''
self.selected = is_selected
def on_press(self):
popup = TextInputPopup(self)
popup.open()
def update_changes(self, txt):
self.text = txt
class RootWidget(ScreenManager):
pass
class MainApp(App):
def build(self):
return RootWidget()
if __name__ == "__main__":
MainApp().run()
my kivy code :
<MainScreen>:
GridLayout:
cols:1
GridLayout:
cols:1
padding:15,15
spacing:20,20
Label:
text:"Login"
font_size:"20sp"
Button:
text:"Admin"
on_press : root.goto_admin_page()
Button:
text:"Agent"
on_press : root.goto_agent_page()
Button:
text: "Customer"
on_press:root.goto_customer_page()
<AdminScreenFirst>:
GridLayout:
cols:1
padding:15,15
spacing:20,20
Label:
text:"Admin Login"
font_size:"20sp"
TextInput:
id:username
hint_text:"Username"
TextInput:
id:password
password:True
hint_text:"Password"
RelativeLayout:
Button:
text:"Login"
on_press : root.go_to_adminsecond(root.ids.username.text,root.ids.password.text)
size_hint :0.3,0.5
pos_hint: {'center_x' : 0.5 , 'center_y' : 0.6}
Label:
id:login_wrong
text:""
<AdminScreenSecond>:
GridLayout:
cols:1
padding:15,15
spacing:20,20
Label:
text:"Loan"
font_size:"20sp"
Button:
text:"Pending Request"
on_press:root.go_to_adminpending()
Button:
text:"Approved"
on_press: root.go_to_adminapproved()
Button:
text:"Rejected"
on_press: root.go_to_adminrejected()
<AdminPendingScreen>:
GridLayout:
cols:1
padding:15,15
spacing:20,20
Label:
text:"Loans"
Button:
text:"Display"
on_press: root.display()
Label:
id:display
text:""
<TextInputPopup>:
title: "Popup"
size_hint: None, None
size: 400, 400
auto_dismiss: False
BoxLayout:
orientation: "vertical"
TextInput:
id: txtinput
text: root.obj_text
Button:
size_hint: 1, 0.2
text: "Save Changes"
on_release:
root.obj.update_changes(txtinput.text)
root.dismiss()
Button:
size_hint: 1, 0.2
text: "Cancel Changes"
on_release: root.dismiss()
<RV>:
BoxLayout:
orientation: "vertical"
GridLayout:
size_hint: 1, None
size_hint_y: None
height: 25
cols: 11
Label:
text: "LoanID"
Label:
text: "Name"
Label:
text:"Tenure"
Label:
text:"Balance"
Label:
text:"LoanType"
Label:
text:"InterestType"
Label:
text:"Interest % p.a."
Label:
text:"Security"
Label:
text:"Total"
Label:
text:"EMI"
Label:
text:"Request"
BoxLayout:
RecycleView:
viewclass: 'SelectableButton'
data: [{'text': str(x)} for x in root.data_items]
SelectableRecycleGridLayout:
cols: 11
default_size: None, dp(26)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
#orientation: 'vertical'
multiselect: True
touch_multiselect: True
<RootWidget>:
MainScreen:
name:"mainfirst_screen"
AdminScreenFirst:
name:"adminfirst_screen"
AdminScreenSecond:
name:"adminsecond_screen"
AdminPendingScreen:
name:"adminPending_screen"
RV:
name:"rv_screen"
my database code:
import sqlite3
class Database:
def __init__(self):
self.conn = sqlite3.connect("loandatabase.db")
self.cur = self.conn.cursor()
self.cur.execute("CREATE TABLE IF NOT EXISTS loan (id INTEGER PRIMARY KEY, customer_name TEXT, tenure integer, balance integer, loantype TEXT, interesttype TEXT,interest integer,security TEXT,totalpayment integer,emi integer,instruction TEXT)")
self.conn.commit()
def insert(self,cname,tenure,blance,ltype,itype,interest,security,tpay,emi,instr):
self.cur.execute("INSERT INTO loan VALUES (NULL,?,?,?,?,?,?,?,?,?,?)",(cname,tenure,blance,ltype,itype,interest,security,tpay,emi,instr))
self.conn.commit()
def view(self):
self.cur.execute("SELECT * FROM loan")
rows = self.cur.fetchall()
return rows
def __del__(self):
self.conn.close()
[![enter image description here][1]][1]
I would request you to help me with it. Thank You in Advance
I am using Kivy,Python,sqlite3
This is displayed:
[1]: https://i.stack.imgur.com/fkUvS.png
Try this:
class MainApp(App):
title = 'Title of the app'
def build(self):
sm = ScreenManager('''You can add transition here''')
sm.add_widget(MainScreen(name='main'))
sm.add_widget(AdminScreenFirst(name='admin1'))
sm.add_widget(AdminScreenSecond(name='admin2'))
sm.add_widget(AdminPendingScreen(name='pending'))
sm.add_widget(RV(name='rv'))
return sm
Each kivy carousel slide consists of an image at the top (with a checkbox) and text below. The direction of the carousel is 'right' (one after the other horizontally). Image and text data are fed to the carousel with a recycleview.
The minimum code results with a) Each slide stacked vertically; b) the checkbox not displaying.
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.recycleview import RecycleView
from kivy.properties import StringProperty, ListProperty, NumericProperty
Builder.load_string("""
<CarouselSlide>:
BoxLayout:
orientation: 'vertical'
size_hint_y: 1
AsyncImage:
source: root.tile
size_hint_y: 0.5
CheckBox:
id: cb
root_ref: root.index
on_press: app.on_checkbox_press(self, self.active, self.state, self.root_ref)
TextInput:
text: root.text
size_hint_y: 0.5
multiline: True
<CarouselScreen>:
name: 'carousel_screen'
Carousel:
direction: 'right'
ignore_perpendicular_swipes: True
size: root.width, root.height
RV:
id: rv
viewclass: 'CarouselSlide'
RecycleBoxLayout:
orientation: 'vertical'
size_hint_y: None
default_size_hint: 1, None
height: self.minimum_height
default_size: 1, root.height
""")
class CarouselScreen(Screen):
pass
class CarouselSlide(Screen):
tile = StringProperty('')
text = StringProperty('')
index = NumericProperty(-1)
cb_state = StringProperty('normal')
def __init__(self, **kwargs):
super(CarouselSlide, self).__init__(**kwargs)
self.bind(cb_state=self.set_cb_state)
def set_cb_state(self, carouselslide, cb_state_value):
self.ids.cb.state = cb_state_value
class RV(RecycleView):
data = ListProperty('[]')
def __init__(self, **kwargs):
super(RV, self).__init__(**kwargs)
self.get_slide_data()
def get_slide_data(self):
text="Ooh, a storm is threatening. My very life today. If I don't get some shelter. Ooh yeah I'm gonna fade away. War, children. It's just a shot away. It's just a shot away. War, children. It's just a shot away. It's just a shot away."
self.data = [{'tile': 'The Rolling Stones', 'text': text, "index": i, "cb_state": 'normal'} for i in range(41)]
class ThisApp(App):
def __init__(self, **kwargs):
super().__init__(**kwargs)
def build(self):
self.sm = ScreenManager()
self.sm.add_widget(CarouselScreen(name="carousel_screen"))
return self.sm
def on_checkbox_press(self, checkbox, active, state, root_ref):
if active:
print(active, state, root_ref)
else:
print(active, state, root_ref)
new_state = checkbox.state
checkbox.state = 'normal'
rv = self.root.get_screen('carousel_screen').ids.rv
rv.data[root_ref]['cb_state'] = new_state
rv.refresh_from_data()
if __name__ == "__main__":
ThisApp().run()
I believe the problem is that you are defining the CheckBox as a child of AsyncImage. The AsyncImage is not intended to be a container. Try un-indenting the CheckBox in your kv, and adding size/position attributes:
<CarouselSlide>:
BoxLayout:
orientation: 'vertical'
size_hint_y: 1
AsyncImage:
source: root.tile
size_hint_y: 0.5
CheckBox:
id: cb
size_hint: None, None
size: 48, 48
pos_hint: {'center_x':0.5}
root_ref: root.index
on_press: app.on_checkbox_press(self, self.active, self.state, self.root_ref)
TextInput:
text: root.text
size_hint_y: 0.5
multiline: True
I'm trying to better understand how the RecycleView functions. Seems like only practical examples will teach me. Docs aren't helping. Kindly have a look at my current screen in the pic below.
Now following are what I'm trying to achieve.
Add/Remove new rows to/from the list.
The first column sl/no should maintain the order even after deleting from in between.
How to achieve 'sort' function? Is it by taking the data into python and do the sort and then update that to the RV again ?
Please find the both .py and .kv codes below.
rv_main.py
import os
os.environ['KIVY_GL_BACKEND'] = 'gl'
import kivy
kivy.require('1.11.0')
from kivy.uix.boxlayout import BoxLayout
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.recycleview import RecycleView
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.recyclegridlayout import RecycleGridLayout
from kivy.uix.behaviors import FocusBehavior
from kivy.uix.recycleview.layout import LayoutSelectionBehavior
from kivy.uix.recycleboxlayout import RecycleBoxLayout
from kivy.uix.recyclegridlayout import RecycleGridLayout
from kivy.uix.label import Label
from kivy.clock import Clock
from kivy.lang import Builder
from kivy.properties import StringProperty
from kivy.properties import ObjectProperty
from kivy.properties import ListProperty, BooleanProperty
from kivy.properties import NumericProperty
class SelectableRecycleBoxLayout(FocusBehavior, LayoutSelectionBehavior, RecycleBoxLayout):
''' Adds selection and focus behaviour to the view. '''
#-----------------------------------------------------------------------
class RecycleViewRow(RecycleDataViewBehavior, BoxLayout):
''' Add selection support to the Label '''
index = None
selected = BooleanProperty(False)
selectable = BooleanProperty(True)
slno = StringProperty('')
typ = StringProperty('')
def refresh_view_attrs(self, rv, index, data):
''' Catch and handle the view changes '''
self.index = index
return super(RecycleViewRow, self).refresh_view_attrs(
rv, index, data)
def on_touch_down(self, touch):
''' Add selection on touch down '''
if super(RecycleViewRow, self).on_touch_down(touch):
return True
if self.collide_point(*touch.pos) and self.selectable:
return self.parent.select_with_touch(self.index, touch)
def apply_selection(self, rv, index, is_selected):
''' Respond to the selection of items in the view. '''
self.selected = is_selected
if is_selected:
pass
else:
pass
def delete_row(self,rv, index, is_selected):
if is_selected:
rv.data.pop(index)
rv.layout_manager.clear_selection()
#-----------------------------------------------------------------------
class RV(RecycleView):
def __init__(self, **kwargs):
super(RV, self).__init__(**kwargs)
#fetch data from the database
self.data = [{'slno': str(x+1),'typ': 'default'} for x in range(4)]
#-----------------------------------------------------------------------
class DataTable(BoxLayout):
def addRow(self):
pass
def removeRow(self):
pass
#-----------------------------------------------------------------------
class RvMainApp(App):
def build(self):
return DataTable()
if __name__ == '__main__':
RvMainApp().run()
rvmain.kv
#: kivy 1.11.0
<RecycleViewRow>:
id: rv
slno: ""
typ: ""
canvas.before:
Color:
rgba: (.0, 0.9, .1, .3) if self.selected else (0.4, 0.4, 0.4, 1)
Rectangle:
pos: self.pos
size: self.size
orientation: 'horizontal'
size_hint: 1.0, 1.0
Label:
text: root.slno
size_hint_x : 1.0
Label:
text: root.typ
size_hint_x : 1.0
#----------------------------------------------------------------
<RV>:
id : rv
viewclass: 'RecycleViewRow'
SelectableRecycleBoxLayout:
default_size: None, dp(40)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
#----------------------------------------------------------------
<DataTable>:
orientation : 'vertical'
Button:
BoxLayout:
Button:
RV:
Button:
BoxLayout:
Button:
text: "Add"
on_release: rv.data.append({"slno": "?", "typ": 'default'})
Button:
text: "Remove"
on_release:
You edit the data list of the recycleview. The data will be sorted as it is sorted in that list.
So here is an example of the add remove feature:
from kivy.app import App
from kivy.lang import Builder
KV = '''
<Row#BoxLayout>:
ind: 1
Button:
text: str(root.ind)
Button:
text: "default"
BoxLayout:
ind: 1
orientation: "vertical"
Button:
BoxLayout:
Button:
RecycleView:
id: rv
data: [{"text":"first","ind":1}]
viewclass: 'Row'
RecycleBoxLayout:
default_size_hint: 1, None
default_size: None, dp(56)
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
Button
BoxLayout:
Button:
text: "Add"
on_release:
root.ind += 1
rv.data.append({"ind": root.ind})
Button:
text: "Remove"
on_release:
root.ind = root.ind - 1 if root.ind > 0 else 0
if len(rv.data): rv.data.pop(-1)
'''
class Test(App):
def build(self):
self.root = Builder.load_string(KV)
return self.root
Test().run()
And here is an example on how to sort the data list by some key. In this case ind.
from kivy.app import App
from kivy.lang import Builder
KV = '''
RecycleView:
viewclass: 'Label'
data: sorted([{"text":"!", "ind":3},{"text":"world", "ind":2},{"text":"hello", "ind":1}], key=lambda k: k["ind"])
RecycleBoxLayout:
id: layout
default_size: None, dp(56)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
'''
class TestApp(App):
def build(self):
return Builder.load_string(KV)
if __name__ == '__main__':
TestApp().run()
menu.py
import kivy
kivy.require('1.9.0') # replace with your current kivy version !
import sqlite3 as lite
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import BooleanProperty, ListProperty, StringProperty, ObjectProperty,NumericProperty
from kivy.lang import Builder
from kivy.uix.dropdown import DropDown
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.button import Button
from kivy.uix.recyclegridlayout import RecycleGridLayout
from kivy.uix.behaviors import FocusBehavior
from kivy.uix.recycleview.layout import LayoutSelectionBehavior
from kivy.uix.popup import Popup
from kivy.core.window import Window
import sys
#Window.borderless = True
#Window.clearcolor = (0, 0.517, 0.705, 1)
Window.size = (900, 500)
#from easygui import msgbox
#db =lite.connect(':memory:')
con = lite.connect('test.db')
con.text_factory = str
cur = con.cursor()
class EditStatePopup(Popup):
obj = ObjectProperty(None)
start_point = NumericProperty(0)
max_table_cols = NumericProperty(0)
new_data = ListProperty([])
stateId = StringProperty("")
stateName = StringProperty("")
stateCode = StringProperty("")
def __init__(self, obj, **kwargs):
super(EditStatePopup, self).__init__(**kwargs)
self.obj = obj
self.start_point = obj.start_point
self.max_table_cols = obj.max_table_cols
self.stateId = obj.rv_data[obj.start_point]["text"]
self.stateName = obj.rv_data[obj.start_point + 1]["text"]
self.stateCode = obj.rv_data[obj.start_point + 2]["text"]
def package_changes(self, stateId, stateName, stateCode):
print(stateName)
self.new_data.append(stateId)
self.new_data.append(stateName)
self.new_data.append(stateCode)
class SelectableRecycleGridLayout(FocusBehavior, LayoutSelectionBehavior,
RecycleGridLayout):
''' Adds selection and focus behaviour to the view. '''
class SelectableButton(RecycleDataViewBehavior, Button):
''' Add selection support to the Button '''
index = None
selected = BooleanProperty(False)
selectable = BooleanProperty(True)
rv_data = ObjectProperty(None)
start_point = NumericProperty(0)
max_table_cols = NumericProperty(3)
data_items = ListProperty([])
def refresh_view_attrs(self, rv, index, data):
''' Catch and handle the view changes '''
self.index = index
return super(SelectableButton, self).refresh_view_attrs(rv, index, data)
def on_touch_down(self, touch):
''' Add selection on touch down '''
if super(SelectableButton, self).on_touch_down(touch):
return True
if self.collide_point(*touch.pos) and self.selectable:
return self.parent.select_with_touch(self.index, touch)
def apply_selection(self, rv, index, is_selected):
''' Respond to the selection of items in the view. '''
self.selected = is_selected
self.rv_data = rv.data
#print("selection changed to {0}".format(rv.data[1]))
def on_press(self):
end_point = self.max_table_cols
rows = len(self.rv_data) # self.max_table_cols
#print(end_point) // 3
#print(rows) // 3
for row in range(rows):
cols = list(range(end_point))
#print(cols) // [0, 1, 2]
#print(self.index) //1
#print(self.max_table_cols)//3
if self.index in cols:
break
self.start_point += self.max_table_cols
end_point += self.max_table_cols
popup = EditStatePopup(self)
popup.open()
def update_states(self, stateId, stateName, stateCode):
cur.execute("UPDATE m_state SET state_name=?, state_code=? WHERE state_id=?",(stateName, stateCode, stateId))
con.commit()
class RV(BoxLayout):
data_items = ListProperty([])
def __init__(self, **kwargs):
super(RV, self).__init__(**kwargs)
self.get_states()
def get_states(self):
cur.execute("SELECT * FROM `m_state` order by state_id asc")
rows = cur.fetchall()
#print(rows)
# create data_items
rows = [(1, 'Test', '01'), (2, 'test2', '02'), (2, 'test2', '03')]
for row in rows:
for col in row:
self.data_items.append(col)
#print(col)
class CustDrop(DropDown):
def __init__(self, **kwargs):
super(CustDrop, self).__init__(**kwargs)
self.select('')
class MainMenu(BoxLayout):
states = ObjectProperty(None)
dropdown = ObjectProperty(None)
def display_states(self):
# rv = RV()
self.dropdown.dismiss()
self.states.add_widget(RV())
#return CustDrop()
class FactApp(App):
title = "Test"
def build(self):
self.root = Builder.load_file('m_ListState.kv')
return MainMenu()
if __name__ == '__main__':
FactApp().run()
m_ListState.kv
#:kivy 1.10.0
#:import CoreImage kivy.core.image.Image
#:import os os
<EditStatePopup>:
title: "Update State"
size_hint: None, None
size: 300, 300
auto_dismiss: False
BoxLayout:
orientation: "vertical"
GridLayout:
cols: 2
Label:
text: "Id"
Label:
id: stateId
text: root.stateId
Label:
text: "Name"
TextInput:
id: stateName
text: root.stateName
Label:
text: "Code"
TextInput:
id: stateCode
text: root.stateCode
Button:
size_hint: 1, 0.4
text: "Cancel"
on_release: root.dismiss()
Button:
size_hint: 1, 0.4
text: "Ok"
on_release:
root.package_changes(stateId.text, stateName.text, stateCode.text)
#root.obj.update_states(root.start_point, root.max_table_cols, root.new_data)
root.obj.update_states(stateId.text, stateName.text, stateCode.text)
root.dismiss()
<SelectableButton>:
# Draw a background to indicate selection
canvas.before:
Color:
rgba: (.0, 0.9, .1, .3) if self.selected else (0, 0, 0, 1)
Rectangle:
pos: self.pos
size: self.size
<RV>:
BoxLayout:
orientation: "vertical"
GridLayout:
size_hint: 1, None
size_hint_y: None
height: 25
cols: 3
Label:
text: "Id"
Label:
text: "Name"
Label:
text: "Code"
BoxLayout:
RecycleView:
viewclass: 'SelectableButton'
data: [{'text': str(x)} for x in root.data_items]
SelectableRecycleGridLayout:
cols: 3
default_size: None, dp(26)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
multiselect: True
touch_multiselect: True
<DropdownButton#Button>:
border: (0, 16, 0, 16)
text_size: self.size
valign: "middle"
padding_x: 5
size_hint_y: None
height: '30dp'
background_color: 90 , 90, 90, 90
color: 0, 0.517, 0.705, 1
<MenuButton#Button>:
text_size: self.size
valign: "middle"
padding_x: 5
size : (80,30)
size_hint : (None, None)
background_color: 90 , 90, 90, 90
background_normal: ''
color: 0, 0.517, 0.705, 1
border: (0, 10, 0, 0)
<MainMenu>:
states: states
dropdown: dropdown
BoxLayout:
orientation: 'vertical'
#spacing : 10
BoxLayout:
canvas.before:
Rectangle:
pos: self.pos
size: self.size
size_hint_y: 1
MenuButton:
id: btn
text: 'View'
size : (60,30)
on_release: dropdown.open(self)
CustDrop:
id: dropdown
auto_width: False
width: 150
DropdownButton:
text: 'State'
size_hint_y: None
height: '32dp'
#on_release: dropdown3.open(self)
on_release: root.display_states()
DropdownButton:
text: 'City'
size_hint_y: None
height: '32dp'
#on_release: dropdown3.open(self)
on_release: root.display_city()
BoxLayout:
canvas.before:
Rectangle:
pos: self.pos
size: self.size
Color:
rgb: (1,1,1)
AsyncImage:
source: "add.jpg"
#on_release: os.system("python m_State.py")
Label:
size_hint_x: 22
BoxLayout:
id: states
size_hint_y: 9
Label:
size_hint_y: 9
Can anyone help for resolve some issue??
1. when i click on state (submenu of view) again and again then data repeats.How to avoid it.When i click on state then state list should be show and when i click on city then city list should be show.display_city() i have not written yet this for only example.
2. When i click on cancel two times then it shows error IndexError: list index out of range.
3.When i update state then it updated in database but does not change real time on screen.If i again run then shows updated data.
Please refer to the problems, solutions and example to solve your problems.
Columns Repeated
Problem
Each time you clicked View, widgets are dynamically added. If you clicked View twice, the columns are repeated twice.
Solution
You have to remove the widgets each time before adding them dynamically.
def display_states(self):
self.dropdown.dismiss()
self.remove_widgets()
self.rv = RV()
self.states.add_widget(self.rv)
def remove_widgets(self):
for child in [child for child in self.states.children]:
self.states.remove_widget(child)
IndexError
Problem
Whenever you clicked on each row of data, it invokes the on_press method. The self.start_point is initialized at the beginning when the class SelectableButton is instantiated.
Solution
Initialize self.start_point in the on_press method.
def on_press(self):
self.start_point = 0
end_point = MAX_TABLE_COLS
rows = len(self.rv_data) // MAX_TABLE_COLS
for row in range(rows):
if self.index in list(range(end_point)):
break
self.start_point += MAX_TABLE_COLS
end_point += MAX_TABLE_COLS
popup = EditStatePopup(self)
popup.open()
RecycleView Not Updated
Problem
In the method update_states, RecycleView's data update is missing.
Solution
Add the following to update RecycleView's data.
def update_states(self, obj):
# update data_items
# obj.start_point + 1 --- skip State_ID
for index in range(obj.start_point + 1, obj.start_point + MAX_TABLE_COLS):
self.rv.data_items[index] = obj.col_data[index - obj.start_point]
# update Database Table
cur.execute("UPDATE m_state SET State_Name=?, State_Code=? WHERE State_ID=?",
(obj.col_data[1], obj.col_data[2], obj.col_data[0]))
con.commit()
Example
m_ListState.py
import kivy
kivy.require('1.10.0') # replace with your current kivy version !
import sqlite3 as lite
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import BooleanProperty, ListProperty, ObjectProperty,NumericProperty
from kivy.lang import Builder
from kivy.uix.dropdown import DropDown
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.button import Button
from kivy.uix.recyclegridlayout import RecycleGridLayout
from kivy.uix.behaviors import FocusBehavior
from kivy.uix.recycleview.layout import LayoutSelectionBehavior
from kivy.uix.popup import Popup
from kivy.core.window import Window
import sys
#Window.borderless = True
#Window.clearcolor = (0, 0.517, 0.705, 1)
Window.size = (900, 500)
#from easygui import msgbox
MAX_TABLE_COLS = 3
path = "/home/iam/dev/SQLite/sampleDB/StateCodesNamesDB/"
#db =lite.connect(':memory:')
# con = lite.connect('fact.db')
con = lite.connect(path + 'country.db')
con.text_factory = str
cur = con.cursor()
class EditStatePopup(Popup):
start_point = NumericProperty(0)
col_data = ListProperty(["?", "?", "?"])
def __init__(self, obj, **kwargs):
super(EditStatePopup, self).__init__(**kwargs)
self.start_point = obj.start_point
self.col_data[0] = obj.rv_data[obj.start_point]["text"]
self.col_data[1] = obj.rv_data[obj.start_point + 1]["text"]
self.col_data[2] = obj.rv_data[obj.start_point + 2]["text"]
def package_changes(self, stateName, stateCode):
self.col_data[1] = stateName
self.col_data[2] = stateCode
class SelectableRecycleGridLayout(FocusBehavior, LayoutSelectionBehavior,
RecycleGridLayout):
''' Adds selection and focus behaviour to the view. '''
class SelectableButton(RecycleDataViewBehavior, Button):
''' Add selection support to the Button '''
index = None
selected = BooleanProperty(False)
selectable = BooleanProperty(True)
rv_data = ObjectProperty(None)
start_point = NumericProperty(0)
def refresh_view_attrs(self, rv, index, data):
''' Catch and handle the view changes '''
self.index = index
return super(SelectableButton, self).refresh_view_attrs(rv, index, data)
def on_touch_down(self, touch):
''' Add selection on touch down '''
if super(SelectableButton, self).on_touch_down(touch):
return True
if self.collide_point(*touch.pos) and self.selectable:
return self.parent.select_with_touch(self.index, touch)
def apply_selection(self, rv, index, is_selected):
''' Respond to the selection of items in the view. '''
self.selected = is_selected
self.rv_data = rv.data
def on_press(self):
self.start_point = 0
end_point = MAX_TABLE_COLS
rows = len(self.rv_data) // MAX_TABLE_COLS
for row in range(rows):
if self.index in list(range(end_point)):
break
self.start_point += MAX_TABLE_COLS
end_point += MAX_TABLE_COLS
popup = EditStatePopup(self)
popup.open()
class RV(BoxLayout):
data_items = ListProperty([])
def __init__(self, **kwargs):
super(RV, self).__init__(**kwargs)
self.get_states()
def get_states(self):
cur.execute("SELECT * FROM m_state order by State_ID asc")
rows = cur.fetchall()
# create data_items
for row in rows:
for col in row:
self.data_items.append(col)
class CustDrop(DropDown):
def __init__(self, **kwargs):
super(CustDrop, self).__init__(**kwargs)
self.select('')
class MainMenu(BoxLayout):
rv = ObjectProperty(None)
states = ObjectProperty(None)
dropdown = ObjectProperty(None)
def display_states(self):
self.dropdown.dismiss()
self.remove_widgets()
self.rv = RV()
self.states.add_widget(self.rv)
def remove_widgets(self):
for child in [child for child in self.states.children]:
self.states.remove_widget(child)
def update_states(self, obj):
# update data_items
# obj.start_point + 1 --- skip State_ID
for index in range(obj.start_point + 1, obj.start_point + MAX_TABLE_COLS):
self.rv.data_items[index] = obj.col_data[index - obj.start_point]
# update Database Table
cur.execute("UPDATE m_state SET State_Name=?, State_Code=? WHERE State_ID=?",
(obj.col_data[1], obj.col_data[2], obj.col_data[0]))
con.commit()
class FactApp(App):
title = "Test"
def build(self):
self.root = Builder.load_file('m_ListState.kv')
return MainMenu()
if __name__ == '__main__':
FactApp().run()
m_ListState.kv
#:kivy 1.10.0
#:import CoreImage kivy.core.image.Image
#:import os os
<EditStatePopup>:
title: "Update State"
size_hint: None, None
size: 300, 300
auto_dismiss: False
BoxLayout:
orientation: "vertical"
GridLayout:
cols: 2
Label:
text: "Id"
Label:
id: stateId
text: root.col_data[0]
Label:
text: "Name"
TextInput:
id: stateName
text: root.col_data[1]
Label:
text: "Code"
TextInput:
id: stateCode
text: root.col_data[2]
Button:
size_hint: 1, 0.4
text: "Cancel"
on_release: root.dismiss()
Button:
size_hint: 1, 0.4
text: "Ok"
on_release:
root.package_changes(stateName.text, stateCode.text)
app.root.update_states(root)
root.dismiss()
<SelectableButton>:
# Draw a background to indicate selection
canvas.before:
Color:
rgba: (.0, 0.9, .1, .3) if self.selected else (0, 0, 0, 1)
Rectangle:
pos: self.pos
size: self.size
<RV>:
BoxLayout:
orientation: "vertical"
GridLayout:
size_hint: 1, None
size_hint_y: None
height: 25
cols: 3
Label:
text: "Id"
Label:
text: "Name"
Label:
text: "Code"
BoxLayout:
RecycleView:
viewclass: 'SelectableButton'
data: [{'text': str(x)} for x in root.data_items]
SelectableRecycleGridLayout:
cols: 3
default_size: None, dp(26)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
multiselect: True
touch_multiselect: True
<DropdownButton#Button>:
border: (0, 16, 0, 16)
text_size: self.size
valign: "middle"
padding_x: 5
size_hint_y: None
height: '30dp'
background_color: 90 , 90, 90, 90
color: 0, 0.517, 0.705, 1
<MenuButton#Button>:
text_size: self.size
valign: "middle"
padding_x: 5
size : (80,30)
size_hint : (None, None)
background_color: 90 , 90, 90, 90
background_normal: ''
color: 0, 0.517, 0.705, 1
border: (0, 10, 0, 0)
<MainMenu>:
states: states
dropdown: dropdown
BoxLayout:
orientation: 'vertical'
#spacing : 10
BoxLayout:
canvas.before:
Rectangle:
pos: self.pos
size: self.size
size_hint_y: 1
MenuButton:
id: btn
text: 'View'
size : (60,30)
on_release: dropdown.open(self)
CustDrop:
id: dropdown
auto_width: False
width: 150
DropdownButton:
text: 'State'
size_hint_y: None
height: '32dp'
#on_release: dropdown3.open(self)
on_release: root.display_states()
DropdownButton:
text: 'City'
size_hint_y: None
height: '32dp'
#on_release: dropdown3.open(self)
on_release: root.display_city()
BoxLayout:
canvas.before:
Rectangle:
pos: self.pos
size: self.size
Color:
rgb: (1,1,1)
AsyncImage:
source: "clipboard.jpeg" # "gst_image/add.jpg"
#on_release: os.system("python m_State.py")
Label:
size_hint_x: 22
BoxLayout:
id: states
size_hint_y: 9
Label:
size_hint_y: 9
Output