I am trying to create a ListView widget in Kivy, but cannot; am using Python 3.10 and Kivy 2.0. Later I changed it to RecycleView. Window is opening but items in the item_strings property of RecycleView are not getting displayed.
AddLocationForm:
<AddLocationForm#BoxLayout>:
orientation: 'vertical'
BoxLayout:
TextInput:
Button:
text: 'Search'
Button:
text: 'Current Location'
RecycleView:
item_strings: ["Kolkata", 'New Delhi']
My main.py is as follows:
from kivy.app import App
class WeatherApp(App):
pass
if __name__ == '__main__':
app = WeatherApp()
app.run()
Can you help me out.
Related
I'm building an Android App, using Kivy and Python 2.7, which is going to unlock the phone based on Face Recognition. After downloading the App and initializing it, I would like the App to be opened directly when Slide To Unlock the phone, open a specific screen "The Recognizer Screen, recognize my face and then Unlock the phone.
What should I add to the .KV code or even to the .py code to root the Slide To Unlock to my app?
For example, if this is my .KV code
<ScreenFour>:
name: "screen4"
id: screen_four
FloatLayout:
canvas:
Rectangle:
source: "image1.jpg"
pos:self.pos
size:self.size
Button:
text: 'Next'
font_size: 32 # font size
size_hint: .2,.1
pos_hint:{'right':1, 'y':0}
on_release: app.root.current="screen5"
Button:
text: "Unlock the phone"
font_size: 20
pos_hint:{'right':0.5, 'y':0.5}
size_hint: 0.4,0.2
on_release: app.fr()
where one_release: app.fr() is the root to start the FaceRecognizer code
What do I have to add to this code? Or do I have to add any thing to the Python code on the specific
class ScreenFour(Screen):
pass
Or do I have to add it here:
class FaceRecognitionApp(App):
def fg(self):
FaceGenerator()
def fr(self):
FaceRecognizer()
def build(self):
return sm
if __name__=="__main__":
FaceRecognitionApp().run()
I would really appreciate having an answer, I'm working on a project and I'm running out of time.
Framework: I am talking about an Android app written in Python 2.7 and packaged with Builtdozer
I have a Builder inside the app with a button
Builder.load_string('''
FloatLayout:
orientation: 'horizontal'
Button:
text: str(root.name)
font_size: '20sp'
pos_hint: {'x':.0, 'y':.3}
size_hint: .4, .8
''')
I want to create a function, change_name, that, if I press the above button, opens the android keyboard to accept an user raw_input
The raw_input provided by the user has to replace the text of the above button.
What I thought is:
1) Create a variable name = StringProperty('Me')
2) Create a function:
def change_name(self):
self.name = raw_input()
3) Call the function inside my button with a on_release
Builder.load_string('''
FloatLayout:
orientation: 'horizontal'
Button:
text: str(root.name)
font_size: '20sp'
pos_hint: {'x':.0, 'y':.3}
size_hint: .4, .8
on_release: root.change_name()
''')
It is correct? Because actually, running the app on Ubuntu, I am trying to click on the button but the app does not ask for an input (it seems blocked).
As a consequence I believe it will not work also on Android.
Could you please help me understanding where am I wrong?
raw_input allows to get input from stdin (terminal). On Android you will not have the terminal available. In addition, raw_input is blocking, this causes the main event loop of your app to be freeze and will cause your app to stop responding.
You shouldn't use raw_input but Kivy's own methods.
On the other hand, you want to make your button editable (as if it were a TextInput). You can create your own custom Button class or use WindowBase.request_keyboard() to request the keyboard manually. However, you can do a little trick by hiding a TextInput and use it to enter the text:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.textinput import TextInput
kv_text= ('''
<MyWidget>:
FloatLayout:
orientation: 'horizontal'
Button:
text: 'Hello'
font_size: '20sp'
pos_hint: {'x':.0, 'y':.3}
size_hint: .4, .8
on_release: root.change_name(self)
Button:
text: 'World'
font_size: '20sp'
pos_hint: {'x':0.6, 'y':.3}
size_hint: .4, 0.8
on_release: root.change_name(self)
''')
class MyWidget(FloatLayout):
def __init__(self, **kwargs):
super(MyWidget, self).__init__(**kwargs)
self.hide_input = TextInput(size_hint=(None, None),
size = (0, 0),
multiline = False)
self.hide_input_bind = None
def change_name(self, instance):
if self.hide_input_bind:
self.hide_input.unbind_uid('text', self.hide_input_bind)
self.hide_input.text = instance.text
self.hide_input.focus = True
self.hide_input_bind = self.hide_input.fbind('text', self._update_text, instance)
def _update_text(self, button, instance, value):
button.text = value
class MyKivyApp(App):
def build(self):
return MyWidget()
def main():
Builder.load_string(kv_text)
app = MyKivyApp()
app.run()
if __name__ == '__main__':
main()
App working on Android (Kivy Launcher):
im still a begginer with kivy, when i launch my kivy app on windows i get a black winodw and the window fits the whole laptop screen. how can i fix this and how can i resize the window?
my python code
# File name FaceRecognition.py
import kivy
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.button import Button
from kivy.uix.widget import Widget
from kivy.uix.label import Label
from kivy.lang import Builder
# Define each screen
class ScreenOne(Screen):
pass
class ScreenTwo(Screen):
pass
class ScreenManagement(ScreenManager):
pass
Builder.load_file("facerecognition.kv")
class FaceRecognitionApp(App):
def build(self):
return ScreenManagement()
if __name__=="__main__":
FaceRecognitionApp().run()
my kv file
# File name FaceRecognition.kv
#: kivy 1.9.1
ScreenManagement:
id: screen_management
ScreenOne:
ScreenTwo:
<MyButton#Button>:
color: .8,.9,0,1 # yellow color
font_size: 32 # font size
size_hint: .2,.1
<ScreenOne>:
name: "screen1"
id: screen_one
FloatLayout:
Label:
text:"Hello\n Welcome to my App\n"
font_size:40
color: 0,0,0,1
MyButton:
text: 'Next'
pos_hint:{'right':1, 'y':0}
on_press:root.manager.current="screen2"
<ScreenOne>:
name: "screen2"
id: screen_two
FloatLayout:
Label:
text:"Please insert your Name\n Please insert your Password\n"
font_size:40
color: 0,0,0,1
MyButton:
text: 'Next'
pos_hint:{'right':1, 'y':0}
on_press:root.manager.current="screen1"
first of all you are defining <ScreenOne> twice in your kv file, second one should be <ScreenTwo>
you are defining a root widget by returning it in your build method. you are also defining it in your kv file by not putting <> around it. You need to get rid of one definition. I just put it in <> in the kv file.
your labels color is black, hence black on black, you won't see anything. I changed it to white color: 1,1,1,1
the window does not fill up the whole screen on my Laptop. I think this is not a code issue.
Here is the kv file with all the changes I mentioned in the list. It works on my pc.
# File name FaceRecognition.kv
#: kivy 1.9.1
<ScreenManagement>:
id: screen_management
ScreenOne:
ScreenTwo:
<MyButton#Button>:
color: .8,.9,0,1 # yellow color
font_size: 32 # font size
size_hint: .2,.1
<ScreenOne>:
name: "screen1"
id: screen_one
FloatLayout:
Label:
text:"Hello\n Welcome to my App\n"
font_size:40
color: 1,1,1,1
MyButton:
text: 'Next'
pos_hint:{'right':1, 'y':0}
on_press:root.manager.current="screen2"
<ScreenTwo>:
name: "screen2"
id: screen_two
FloatLayout:
Label:
text:"Please insert your Name\n Please insert your Password\n"
font_size:40
color: 1,1,1,1
MyButton:
text: 'Next'
pos_hint:{'right':1, 'y':0}
on_press:root.manager.current="screen1"
I want my Kivy app to have multiple ListView instances. I'm stuck when it comes to assigning different properties, especially callbacks. The following code illustrates my problem:
from kivy.app import App
from kivy.uix.listview import ListItemButton
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang import Builder
Builder.load_string('''
#: import ListAdapter kivy.adapters.listadapter.ListAdapter
#: import ListItemButton kivy.uix.listview.ListItemButton
<smRoot>:
Screen1:
Screen2:
<ListItemButton>:
on_press: app.callback1(self)
height: dp(25)
size_hint: (1,.1)
<Screen1>:
name:'screen1'
BoxLayout:
orientation: 'vertical'
Label:
text: 'Screen1'
size_hint_y: .1
ListView:
id:lstScreen1
adapter:
ListAdapter(data=[{'text':'item1'},{'text':'item2'},{'text':'item3'}],
args_converter=lambda row_index, rec: {'text': rec['text']},
cls=ListItemButton,
selection_mode='single',
allow_empty_selection=False)
Button:
text: 'Switch Screen'
size_hint_y: .1
on_press: root.manager.current = 'screen2'
<ListItemButton>:
on_press: app.callback2(self)
height: dp(25)
size_hint: (1,.1)
<Screen2>:
name:'screen2'
BoxLayout:
orientation: 'vertical'
Label:
text: 'Screen2'
size_hint_y: .1
ListView:
id:lstScreen2
adapter:
ListAdapter(data=[{'text':'item1'},{'text':'item2'},{'text':'item3'}],
args_converter=lambda row_index, rec: {'text': rec['text']},
cls=ListItemButton,
selection_mode='single',
allow_empty_selection=False)
Button:
text: 'Switch Screen'
size_hint_y: .1
on_press: root.manager.current = 'screen1'
''')
class smRoot(ScreenManager):
pass
class Screen1(Screen):
MyButt = ListItemButton
pass
class Screen2(Screen):
pass
class myApp(App):
def build(self):
smroot = smRoot()
return smroot
def callback1(self, btn_instance):
index = btn_instance.index
print 'From Screen 1: ' + str(index)
def callback2(self, btn_instance):
index = btn_instance.index
print 'From Screen 2: ' + str(index)
myApp().run()
Here, I want each of the ListView instances on Screens 1 and 2 to have separate callbacks. But when I click on either screen, the output is the same, like so:
From Screen 2: 0
From Screen 1: 0
Ideally, I was hoping to implement something like a Dynamic Class. But when I tried something like this:
<MyButt#ListItemButton>:
#on_press: app.callback1(self)
height: dp(25)
size_hint: (1,.1)
<Screen1>:
name:'screen1'
MyButt:
on_press: app.callback1(self)
BoxLayout:
orientation: 'vertical'
Label:
text: 'Screen1'
size_hint_y: .1
ListView:
id:lstScreen1
adapter:
ListAdapter(data=[{'text':'item1'},{'text':'item2'},{'text':'item3'}],
args_converter=lambda row_index, rec: {'text': rec['text']},
cls=MyButt,
selection_mode='single',
allow_empty_selection=False)
I get a NameError: name 'MyButt' is not defined error. As far as I can tell, I've adhered to the same syntax in the documentation example linked above, so I'm confused.
I haven't tried creating a custom class in Python, but I would rather keep the UI elements separate in the .kv code (If I'm not mistaken, isn't that the basic idea behind kv?).
Any help/pointers/suggestions in this regard would be much appreciated.
You can't use a widget class from the python side (after ":") in kv without importing it, but since MyButt is not defined in any module, being a dynamic class (defined in pure kv) you can use Factory to use it.
first, import Factory at the top of your kv file.
#:import Factory kivy.factory.Factory
then change
ListView:
id:lstScreen1
adapter:
ListAdapter(data=[{'text':'item1'},{'text':'item2'},{'text':'item3'}],
args_converter=lambda row_index, rec: {'text': rec['text']},
cls=MyButt,
to
ListView:
id:lstScreen1
adapter:
ListAdapter(data=[{'text':'item1'},{'text':'item2'},{'text':'item3'}],
args_converter=lambda row_index, rec: {'text': rec['text']},
cls=Factory.MyButt,
I'm building a simple android App using Python Kivy, but I'm not able to make a simple GUI, what I'm trying to achieve is the following
a text saying "FB"
a user input
a Button
I'm using BoxLayout, below is my KV code and the result that I got ...
How can I make the TextInput above the button? Also, is there any simple Kivy GUI builder I can use?
Builder.load_string('''
<MyInterface>:
orientation: 'vertical'
Label:
text: "FB"
Label:
TextInput:
id: number
size_hint_y: None
size: (400,100)
IntentButton:
size_hint_y: None
size: (400,100)
text: "Dial call via phone"
on_release: self.send_sms()
Label:
''')
class MyInterface(BoxLayout):
pass
result:
Detele Label which is a parent of the TextInput.
If you add a widget to another widget, which isn't a layout, it will receive a default pos of [0, 0] and default size of [100, 100] (in your case, you have overwritten it to [400, 100]).
About a GUI designer - there is an experimental one, but it isn't recommended for beginners.